Para los lectores: estás a punto de entrar en un agujero negro profundo y oscuro del que nunca escaparás. Las diferencias son infinitas. Ríndete ahora mientras puedas: stackoverflow.com/q/496928/1599699
esto pierde el caso donde Foo es lo mismo que clazz, en cuyo caso devuelve verdadero: la respuesta más votada de Pauls a continuación corrige esto
ruibarbo
3
Estoy de acuerdo en que cuando clazz es un Foo, entonces clazz.isAssignableFrom (Foo.class) es cierto. ¿Dónde dije lo contrario?
uckelman
55
@Gili Esto no es lo que dijo uckelman. Por favor, vuelva a leer su respuesta.
Puce
2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> es cierto también para las interfaces.
Puce
1
Técnico: si objes nullasí clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj), arrojará un NullPointerExceptiony no volverá true.
Andrew Macheret
196
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.
¿Por qué en su ejemplo "b isAssignableFrom a:" pero el código es A.class.isAssignableFrom(B.class)? Confundí por la salida :)
Roman Truba
44
ummm ... en todos sus ejemplos "instanceOf" devuelve verdadero iff "isAssignableFrom" devuelve verdadero ... No veo la diferencia de esta manera.
Desarrollador de Android
2
Tenga cuidado de que el texto impreso no coincida con el código y puede ser confuso ... Ejemplo: "System.out.println (" b isAssignableFrom a: "+ A.class.isAssignableFrom (B.class));"
Polster
21
@Paul La respuesta, como es, no es útil, porque el lector se pregunta "¿cuál es la diferencia entre un objeto que es una instancia de una subclase de una clase y el tipo de objeto que es convertible a la clase?" Seguramente, puede ver que le ha dejado al lector tantas preguntas después de leer su respuesta como cuando llegó a esta página. Una mejor respuesta en realidad explicaría la diferencia (o falta de ella). Si no hay diferencia, la respuesta debe indicar directamente: "no hay diferencia práctica".
Aleksandr Dubinsky
2
Más importante aún, el lector se pregunta qué diablos usar para sus propósitos. De acuerdo con los comentarios en la pregunta, isAssignableFrom()arroja un a NullPointerExceptionsi el objeto es nulo, mientras que isInstance()solo devuelve falso. Esa es la verdadera respuesta.
Andrew
6
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.
Esto no es 100% cierto. 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.
Gili
66
@Gili: Te has equivocado un poco allí. 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.
ColinD
1
Estoy en desacuerdo. Si busca el Javadoc 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.
Gili
2
@Gili: Autoboxing convierte primitivo byteen Byteporque el tipo de parámetro de isInstancees Object.
ColinD
2
Bueno. Mi punto original era que las llamadas no son exactamente simétricas entre sí, pero al volver a leer su respuesta, nunca hizo esta afirmación, por lo que tiene razón.
Gili
6
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.
NullPointerException
ifobj == null
.Respuestas:
clazz.isAssignableFrom(Foo.class)
será verdadero siempre que la clase representada por elclazz
objeto sea una superclase o superinterfaz deFoo
.clazz.isInstance(obj)
será verdadero siempre que el objetoobj
sea una instancia de la claseclazz
.Es decir:
siempre es cierto siempre
clazz
y cuando noobj
sean nulos.fuente
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));
-> es cierto también para las interfaces.obj
esnull
asíclazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
, arrojará unNullPointerException
y 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 convertirMyClass
sin generar aClassCastException
. En otras palabras, obj es una instancia deMyClass
o sus subclases.MyClass.class.isAssignableFrom(Other.class)
devolverá true siMyClass
es el mismo que, o una superclase o superinterfaz de,Other
.Other
puede ser una clase o una interfaz. Responde verdadero siOther
se puede convertir a aMyClass
.Un pequeño código para demostrar:
fuente
A.class.isAssignableFrom(B.class)
? Confundí por la salida :)isAssignableFrom()
arroja un aNullPointerException
si el objeto es nulo, mientras queisInstance()
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
isInstance
pero solo elClass
objeto para usarisAssignableFrom
.fuente
Comparable.class.isAssignableFrom(Byte.class) == true
peroByte.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 unClass
objeto no es una instancia deByte
. La comparación correcta conComparable.class.isAssignableFrom(Byte.class)
esComparable.class.isInstance((byte) 1)
, lo cual es cierto.Byte
, descubrirá que se extiendeNumber
y es una clase.(byte) 1
No es equivalente aByte
. El primero es un primitivo. Este último es una clase.byte
enByte
porque el tipo de parámetro deisInstance
esObject
.Por brevedad, podemos entender estas dos API como a continuación:
X.class.isAssignableFrom(Y.class)
Si
X
yY
son la misma clase, oX
esY
la superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.X.class.isInstance(y)
Say
y
es una instancia de claseY
, siX
yY
son la misma clase, oX
esY
la superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.fuente