Dejen clazzser algunos Classy objsean algunos Object.
Es
clazz.isAssignableFrom(obj.getClass())
siempre lo mismo que
clazz.isInstance(obj)
?
Si no es así, ¿cuáles son las diferencias?
NullPointerExceptionif obj == null.
Dejen clazzser algunos Classy objsean algunos Object.
Es
clazz.isAssignableFrom(obj.getClass())
siempre lo mismo que
clazz.isInstance(obj)
?
Si no es así, ¿cuáles son las diferencias?
NullPointerExceptionif obj == null.
Respuestas:
clazz.isAssignableFrom(Foo.class)será verdadero siempre que la clase representada por el clazzobjeto sea una superclase o superinterfaz de Foo.
clazz.isInstance(obj)será verdadero siempre que el objeto objsea una instancia de la clase clazz.
Es decir:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
siempre es cierto siempre clazzy cuando no objsean nulos.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> es cierto también para las interfaces.
objes nullasí clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj), arrojará un NullPointerExceptiony no volverá true.
Ambas respuestas están en el estadio pero ninguna es una respuesta completa.
MyClass.class.isInstance(obj)es para verificar una instancia. Devuelve verdadero cuando el parámetro obj no es nulo y se puede convertir MyClasssin generar a ClassCastException. En otras palabras, obj es una instancia de MyClasso sus subclases.
MyClass.class.isAssignableFrom(Other.class)devolverá true si MyClasses el mismo que, o una superclase o superinterfaz de, Other. Otherpuede ser una clase o una interfaz. Responde verdadero si Otherse puede convertir a a MyClass.
Un pequeño código para demostrar:
public class NewMain
{
public static void main(String[] args)
{
NewMain nm = new NewMain();
nm.doit();
}
class A { }
class B extends A { }
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)); // true
System.out.println("b isInstance a: " + A.class.isInstance(myB)); //true
System.out.println("a isInstance b: " + B.class.isInstance(myA)); //false
System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class)); //true
System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class)); //false
System.out.println("bArr isInstance A: " + A.class.isInstance(bArr)); //false
System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr)); //true
System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass())); //true
}
}
A.class.isAssignableFrom(B.class)? Confundí por la salida :)
isAssignableFrom()arroja un a NullPointerExceptionsi el objeto es nulo, mientras que isInstance()solo devuelve falso. Esa es la verdadera respuesta.
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 isInstancepero solo el Classobjeto para usar isAssignableFrom.
Comparable.class.isAssignableFrom(Byte.class) == truepero Byte.class.isInstance(Comparable.class) == false. En otras palabras, isInstance()no es simétrico para interfaces, solo para subclases.
Byte.class.isInstance(Comparable.class)es falso porque un Classobjeto no es una instancia de Byte. La comparación correcta con Comparable.class.isAssignableFrom(Byte.class)es Comparable.class.isInstance((byte) 1), lo cual es cierto.
Byte, descubrirá que se extiende Numbery es una clase. (byte) 1No es equivalente a Byte. El primero es un primitivo. Este último es una clase.
byteen Byteporque el tipo de parámetro de isInstancees Object.
Por brevedad, podemos entender estas dos API como a continuación:
X.class.isAssignableFrom(Y.class)Si Xy Yson la misma clase, o Xes Yla superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.
X.class.isInstance(y)Say yes una instancia de clase Y, si Xy Yson la misma clase, o Xes Yla superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.