Me gustaría saber sobre el siguiente comportamiento del instanceof
operador en 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
}
}
¿Por que es esto entonces? No hay relación entre interface C
y class B
, pero da falso mientras que en caso de obj instanceof A
da error de compilador
java
class
inheritance
interface
instanceof
Ajay Sharma
fuente
fuente
Object obj = new B()
, se compila.class B
esfinal
entoncesobj instanceof C
tampoco se compilará, porque si noB
puede tener subtipos, se garantiza que no está relacionado conC
.Respuestas:
Debido a que Java no tiene herencia de clases múltiples, se sabe absolutamente durante la compilación que el
obj
objeto de tipoB
no puede ser un subtipoA
. Por otro lado, posiblemente puede ser un subtipo de interfazC
, por ejemplo en este caso: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 } }
Por lo tanto, mirar solo el
obj instanceof C
compilador de expresiones no puede decir de antemano si será verdadero o falso, pero al mirarloobj instanceof A
se sabe que esto siempre es falso, por lo que no tiene sentido y le ayuda a evitar un error. Si aún desea tener esta verificación sin sentido en su programa, puede agregar una conversión explícita aObject
:System.out.println(((Object)obj) instanceof A); //compiles fine
fuente
A.class.isAssignableFrom(obj.getClass())
Java has no multiple class inheritance
sí, estoy de acuerdo, pero cómo se aplica en este caso porque ni B ni A extienden nada, así que ¿por qué herencias múltiples aquí. Sería útil si pudiera explicarlo?B extends A
. En mi vida, de hecho, necesitaba hacer comprobaciones y lanzamientos tan raros como(A)(Object)b
si en tiempo de ejecución fuera posible ser verdad.Al usar el
final
modificador en la declaración de clase a continuación, se garantiza que no puede haber una subclase deTest
que pueda implementar la interfazFoobar
. En este caso, es obvio queTest
yFoobar
no son compatibles entre sí: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 { }
De lo contrario, si
Test
no se declarafinal
, es posible que una subclase deTest
implemente la interfaz. Y es por eso que el compilador permitiría la declaracióntest instanceof Foobar
en este caso.fuente