Я хотел бы знать о следующем поведении instanceof
оператора в Java.
interface C {}
class B {}
public class A {
public static void main(String args[]) {
B obj = new B();
System.out.println(obj instanceof A); //Gives compiler error
System.out.println(obj instanceof C); //Gives false as output
}
}
Почему это так? Нет связи между interface C
и class B
, но он дает false, тогда как в случае obj instanceof A
он дает ошибку компилятора?
java
class
inheritance
interface
instanceof
Аджай Шарма
источник
источник
Object obj = new B()
, он компилируется.class B
это,final
тоobj instanceof C
тоже не будет компилироваться, потому что, еслиB
у него не может быть подтипов, то он гарантированно не связан сC
.Ответы:
Поскольку Java не имеет множественного наследования классов, во время компиляции абсолютно известно, что
obj
объект типаB
не может быть подтипомA
. С другой стороны, это может быть подтип интерфейсаC
, например в этом случае:interface C {} class B {} class D extends B implements C {} public class A { public static void main(String args[]) { B obj = new D(); System.out.println(obj instanceof C); //compiles and gives true as output } }
Таким образом, глядя только на
obj instanceof C
компилятор выражений, нельзя заранее сказать, будет ли оно истинным или ложным, но, глядя наobj instanceof A
него, он знает, что это всегда ложно, что бессмысленно и помогает предотвратить ошибку. Если вы по-прежнему хотите иметь эту бессмысленную проверку в своей программе, вы можете добавить явное приведение кObject
:System.out.println(((Object)obj) instanceof A); //compiles fine
источник
A.class.isAssignableFrom(obj.getClass())
Java has no multiple class inheritance
да, я согласен, но как оно применяется в этом случае, потому что ни B, ни A не расширяют ничего, так почему здесь множественное наследование. Было бы полезно, если бы вы могли объяснить?B extends A
. В моей жизни мне действительно(A)(Object)b
приходилось делать такие странные проверки и кастинги, как будто во время выполнения это действительно возможно.Использование
final
модификатора в объявлении класса ниже гарантирует, что не может быть подклассаTest
, который может реализовать интерфейсFoobar
. В этом случае очевидно, чтоTest
иFoobar
несовместимы друг с другом:public final class Test { public static void main(String[] args) { Test test = new Test(); System.out.println(test instanceof Foobar); // Compiler error: incompatible types } } interface Foobar { }
В противном случае, если
Test
не объявленоfinal
, возможно, что подклассTest
реализует интерфейс. И поэтомуtest instanceof Foobar
в этом случае компилятор разрешит оператор .источник