Deje que clazz
sea un Class
y obj
sea un Object
.java: Class.isInstance vs Class.isAssignableFrom
Es
clazz.isAssignableFrom(obj.getClass())
siempre el mismo que
clazz.isInstance(obj)
?
Si no, ¿cuáles son las diferencias?
Deje que clazz
sea un Class
y obj
sea un Object
.java: Class.isInstance vs Class.isAssignableFrom
Es
clazz.isAssignableFrom(obj.getClass())
siempre el mismo que
clazz.isInstance(obj)
?
Si no, ¿cuáles son las diferencias?
clazz.isAssignableFrom(Foo.class)
será verdadero siempre que la clase representada por el objeto clazz
sea una superclase o superinterfaz de Foo
.
clazz.isInstance(obj)
será verdadero siempre que el objeto obj
sea una instancia de la clase clazz
.
Eso es:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
siempre es cierto.
se echa de menos el caso donde el Foo es lo mismo que clazz - en cuyo caso devuelve verdadero: la respuesta de Pauls más votada a continuación corrige esto – Rhubarb
Acepto que cuando clazz es un Foo, entonces clazz.isAssignableFrom (Foo.class) es verdadero . ¿Dónde dije lo contrario? – uckelman
Esto no es 100% cierto. 'Comparable.class.isAssignableFrom (Byte.class) == true' pero' Byte.class.isInstance (Comparable.class) == false'. En otras palabras, 'isInstance()' no es simétrico para interfaces, solo para subclases. – Gili
Creo que el resultado para esos dos debería ser siempre el mismo. La diferencia es que necesita una instancia de la clase para usar isInstance
pero solo el objeto Class
para usar isAssignableFrom
.
Esto no es 100% cierto. 'Comparable.class.isAssignableFrom (Byte.class) == true' pero' Byte.class.isInstance (Comparable.class) == false'. En otras palabras, 'isInstance()' no es simétrico para interfaces, solo para subclases. – Gili
@Gili: Lo tienes un poco mal allí. 'Byte.class.isInstance (Comparable.class)' es falso porque un objeto 'Class' no es una instancia de' Byte'. La comparación correcta con 'Comparable.class.isAssignableFrom (Byte.class)' es 'Comparable.class.isInstance ((byte) 1)', que es verdadero. – ColinD
No estoy de acuerdo. Si busca el Javadoc de 'Byte', descubrirá que se extiende' Number' y es una clase. '(byte) 1' no es equivalente a' Byte'. El primero es un primitivo. Este último es una Clase. – Gili
Ambas respuestas están en el estadio pero ninguna es una respuesta completa.
MyClass.class.isInstance(obj)
es para verificar una instancia. Devuelve true cuando el parámetro obj no es nulo y se puede convertir a MyClass
sin generar un ClassCastException
. En otras palabras, obj es una instancia de MyClass
o sus subclases.
MyClass.class.isAssignableFrom(Other.class)
devolverá verdadero si MyClass
es lo mismo que, o una superclase o superinterfaz de, Other
. Other
puede ser una clase o una interfaz. Responde verdadero si Other
se puede convertir a MyClass
.
un poco de código para demostrar:
public class NewMain
{
public static void main(String[] args)
{
NewMain nm = new NewMain();
nm.doit();
}
public void doit()
{
A myA = new A();
B myB = new B();
A[] aArr = new A[0];
B[] bArr = new B[0];
System.out.println("b instanceof a: " + (myB instanceof A));
System.out.println("b isInstance a: " + A.class.isInstance(myB));
System.out.println("a isInstance b: " + B.class.isInstance(myA));
System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class));
System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class));
System.out.println("bArr isInstance A: " + A.class.isInstance(bArr));
System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr));
System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass()));
}
class A
{
}
class B extends A
{
}
}
Y la salida:
b instanceof a: true
b isInstance a: true
a isInstance b: false
b isAssignableFrom a: true
a isAssignableFrom b: false
bArr isInstance A: false
bArr isInstance aArr: true
bArr isAssignableFrom aArr: true
La penúltima y la penúltima líneas dicen 'bArr isInstance aArr' pero el código es diferente. –
¿Por qué en su ejemplo "b isAssignableFrom a:" pero el código es 'A.class.isAssignableFrom (B.class)'? Confundí por salida :) –
MyClass.class.isInstance (obj) también funcionará para las interfaces: _Si este objeto de clase representa una interfaz, este método devuelve verdadero si la clase o cualquier superclase del argumento de objeto especificado implementa esta interfaz._ – Patrick
Por razones de brevedad, podemos entender estas dos API, como a continuación:
Si X e Y son de la misma clase, o X es la superclase o súper interfaz de Y, devuelve verdadero, de lo contrario, falso.
Say y es una instancia de la clase Y, si X e Y son de la misma clase, o X es superclase o súper interfaz, devuelve verdadero; de lo contrario, es falso.
if obj == null, el segundo devuelve falso, el primero no. ;) –
@PeterLawrey, el primero arrojará una 'NullPointerException' si' obj == null'. – ryvantage
Encontré una respuesta con ejemplos de hrere: http://www.mytechnotes.biz/2012/07/java-instanceof-isassignablefrom-or.html –