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.
NullPointerExceptionifobj == null.Respuestas:
clazz.isAssignableFrom(Foo.class)será verdadero siempre que la clase representada por elclazzobjeto sea una superclase o superinterfaz deFoo.clazz.isInstance(obj)será verdadero siempre que el objetoobjsea una instancia de la claseclazz.Es decir:
siempre es cierto siempre
clazzy cuando noobjsean nulos.fuente
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));-> es cierto también para las interfaces.objesnullasíclazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj), arrojará unNullPointerExceptiony 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 convertirMyClasssin generar aClassCastException. En otras palabras, obj es una instancia deMyClasso sus subclases.MyClass.class.isAssignableFrom(Other.class)devolverá true siMyClasses el mismo que, o una superclase o superinterfaz de,Other.Otherpuede ser una clase o una interfaz. Responde verdadero siOtherse puede convertir a aMyClass.Un pequeño código para demostrar:
fuente
A.class.isAssignableFrom(B.class)? Confundí por la salida :)isAssignableFrom()arroja un aNullPointerExceptionsi 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
isInstancepero solo elClassobjeto para usarisAssignableFrom.fuente
Comparable.class.isAssignableFrom(Byte.class) == trueperoByte.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 unClassobjeto 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 extiendeNumbery es una clase.(byte) 1No es equivalente aByte. El primero es un primitivo. Este último es una clase.byteenByteporque el tipo de parámetro deisInstanceesObject.Por brevedad, podemos entender estas dos API como a continuación:
X.class.isAssignableFrom(Y.class)Si
XyYson la misma clase, oXesYla superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.X.class.isInstance(y)Say
yes una instancia de claseY, siXyYson la misma clase, oXesYla superclase o la super interfaz, devuelve verdadero, de lo contrario, falso.fuente