Когда instanceof возвращает FALSE?

Я знаю, что instanceof возвращает TRUE, когда объект является экземпляром определенного класса. Например:

B extends A
C extends A

B b = new B();
C c = new C();

b instanceof A // returns TRUE

Пока все хорошо, поэтому давайте введем что-нибудь, что, казалось бы, должно возвращать false:

c instanceof B // won't compile (error: inconvertible types)

Это не компилируется, что имеет смысл, поскольку позволяет выявить недосмотр во время компиляции. Но когда действительно instanceof возвращает false? Кажется, есть только два варианта: ИСТИНА и ОШИБКА. Единственное исключение, о котором я могу думать, это следующее:

null instanceof A // returns FALSE

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

Что мне здесь не хватает? Являются ли true / error единственными практическими вариантами, или возможно ли действительно вернуть false более значимым образом, кроме случаев, когда в качестве ссылочной переменной задано значение null?


person abc32112    schedule 22.01.2014    source источник
comment
Это проверка орфографии сафари. Рассмотрим приведенный выше псевдокод. ;)   -  person abc32112    schedule 23.01.2014
comment
возможный дубликат Для чего используется оператор instanceof?   -  person Oliver Charlesworth    schedule 23.01.2014
comment
(Object)c instanceof B будет компилироваться. Причина, по которой c instanceof B не компилируется, заключается в том, что компилятор может статически определить, что ссылка на C никогда не может быть B.   -  person Radiodef    schedule 23.01.2014


Ответы (4)


Вот пример, который дает ложное значение:

class A {}
class B extends A {}

A a = new A();
a instanceof B   // false

Живая демонстрация: http://ideone.com/cQltqE.

person Oliver Charlesworth    schedule 22.01.2014

В дополнение к другим ответам: каждый раз, когда либо выражение слева, либо тип справа является интерфейсом, тогда instanceof может быть истинным, поэтому компилятор должен разрешить это. Так что легко найти примеры, когда это было бы неверно.

person ajb    schedule 22.01.2014

Вот еще один пример, который возвращает false

public static void main(String[] args) {
    checkType("");
}

static <T> void checkType(T sometype) {
    System.out.println(sometype instanceof A);
}

static class A {}

Это действительно полезно только при попытке сравнить (а затем привести) к более конкретному типу.

В вашем примере

c instanceof A

не имеет смысла, поскольку тип C не входит в иерархию наследования A.

person Sotirios Delimanolis    schedule 22.01.2014

B extends A
C extends A

B b = new B();
C c = new C();

b instanceof A // returns TRUE
myMethod(b); // has TRUE and then FALSE
myMethod(c); // has FALSE and then TRUE

void myMethod(A a){
  if(a instanceof B){System.out.println("This is a B");}//first statement
  if(a instanceof C){System.out.println("This is a C");}//second statement
}

При вызове myMethod(b), если оценка во втором операторе этого метода будет FALSE и будет напечатано Это B. Однако при вызове myMethod(c), если оценка в первом операторе этого метода будет FALSE и будет напечатана Это C

person user1642342    schedule 04.11.2017