Почему этот экземпляр кода работает и не вызывает ошибку времени компиляции? - PullRequest
6 голосов
/ 09 октября 2010

В следующем коде типом x является I (хотя x также реализует J, но это не известно во время компиляции), так почему же код в (1) не приводит к ошибке времени компиляции.Потому что во время компиляции рассматривается только тип ссылки.

public class MyClass {
    public static void main(String[] args) {
        I x = new D();
        if (x instanceof J) //(1)
            System.out.println("J");
    }
}

interface I {}

interface J {}

class C implements I {}

class D extends C implements J {}

Ответы [ 2 ]

13 голосов
/ 09 октября 2010

instanceof используется для определения типа объекта во время выполнения.Вы пытаетесь определить, действительно ли x является объектом типа J во время работы программы, поэтому она компилируется.

Неужели вы думаете, что это должно привести к ошибке во время компиляции, потому что вы думаете, чтокомпилятор не знает тип x?

Редактировать

Как прокомментировал Кирк Волл (спасибо Кирку Воллу!), проверяли ли вы xэто instanceof конкретный класс, и компилятор может определить тип x, тогда вы получите ошибку во время компиляции.

Из спецификации языка Java:

Если приведение выражения RelationalExpression к ReferenceType будет отклонено как ошибка времени компиляции, то реляционное выражение instanceof также вызывает ошибку времени компиляции.В такой ситуации результат выражения instanceof никогда не может быть истинным.

Как пример этого:

import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

class SerializableClass implements Serializable
{
   private writeObject(ObjectOutputStream out) {}
   private readObject(ObjectInputStream in) {}
}

public class DerivedSerializableClass extends SerializableClass
{
   public static void main(String[] args)
   {
      DerivedSerializableClass dsc = new DerivedSerializableClass();

      if (dsc instanceof DerivedSerializableClass) {} // fine
      if (dsc instanceof Serializable) {} // fine because check is done at runtime
      if (dsc instanceof String) {} // error because compiler knows dsc has no derivation from String in the hierarchy

      Object o = (Object)dsc;
      if (o instanceof DerivedSerializableClass) {} // fine because you made it Object, so runtime determination is necessary
   }
}
2 голосов
/ 09 октября 2010

instanceof - это оператор времени выполнения, а не время компиляции, поэтому он оценивается с использованием фактического типа объекта, на который ссылаются.

...