2011-05-27 12 views
34

Quiero comparar el tipo de clase en Java.Comparación de tipos de clase en Java

pensé que podía hacer esto:

class MyObject_1 {} 
class MyObject_2 extends MyObject_1 {} 

public boolean function(MyObject_1 obj) { 
    if(obj.getClass() == MyObject_2.class) System.out.println("true"); 
} 

me querían comparar en caso si el obj introducida en la función se amplió de MyObject_1 o no. Pero esto no funciona. Parece que el método getClass() y .class proporcionan diferentes tipos de información.

¿Cómo puedo comparar dos tipos de clase, sin tener que crear otro objeto ficticio solo para comparar el tipo de clase?

+0

Esta pregunta me confunde y me dice mal sobre la forma en que "==" funciona en caso de comparar clases/interfaces. El ejemplo debe ser autónomo. ¡Lo que pases a tu función debería ser en el ejemplo! – croraf

Respuesta

40

Prueba esto:

MyObject obj = new MyObject(); 
if(obj instanceof MyObject){System.out.println("true");} //true 

Debido a la herencia esto es válido para las interfaces, también:

class Animal {} 
class Dog extends Animal {}  

Dog obj = new Dog(); 
Animal animal = new Dog(); 
if(obj instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Dog){System.out.println("true");} //true 

Para leer más sobre instanceof: http://mindprod.com/jgloss/instanceof.html

+0

¿Pero qué sucede si quiero verificar que un Animal es una instancia de Perro? ¿Todavía es posible? Di: public void cheque (obj Animal) { si (obj instanceof perro) {System.out.println ("verdadero");}} ¿Sigue siendo posible? – Carven

+0

@xEnON: Esto es posible, pero siempre será falso. No puede verificar si una interfaz es una instancia de una clase concreta. – Thor

+0

Entonces, si tengo una función que hace uso de esta característica de polimorfismo, no puedo verificar su tipo de clase exacta en tiempo de ejecución? – Carven

9

Imprime true en mi máquina. Y debería, de lo contrario, nada en Java funcionaría como se esperaba. (Esto se explica en el JLS: 4.3.4 When Reference Types Are the Same)

¿Tiene varios clasificadores en su lugar?


Ah, y en respuesta a este comentario:

me cuenta de que tengo un error tipográfico en mi pregunta . Debería ser así:

MyImplementedObject obj = new MyImplementedObject(); 
if(obj.getClass() == MyObjectInterface.class) System.out.println("true"); 

MyImplementedObject implementa MyObjectInterface Así, en otras palabras, estoy comparando con sus implementadas objetos.

bien, si usted quiere comprobar que se puede hacer ya sea:

if(MyObjectInterface.class.isAssignableFrom(obj.getClass())) 

o la mucho más concisa

if(obj instanceof MyobjectInterface) 
+0

Me doy cuenta de que tengo un error tipográfico en mi pregunta. Debería ser así: MyImplementedObject obj = new MyImplementedObject(); if (obj.getClass() == MyObjectInterface .class) System.out.println ("true"); MyImplementedObject implementa MyObjectInterface En otras palabras, lo estoy comparando con sus objetos implementados. – Carven

+0

He actualizado mi publicación con el código correcto que quise decir. Perdón por la confusion. – Carven

+0

@xEnOn y yo hemos actualizado el mío :-) –

24

Si no quiere o no puede utilizar instanceof, a continuación, comparar con equals:

if(obj.getClass().equals(MyObject.class)) System.out.println("true"); 

BTW - es extraño porque las dos instancias Class en su extracto deberían ser las mismas, al menos en su código de ejemplo. Ellos pueden ser diferente si:

  • las clases tienen el mismo nombre corto, pero definidos en diferentes paquetes
  • las clases tienen el mismo nombre completo, pero se cargan por diferentes cargadores de clases.
3

Como dije antes, su código funcionará a menos que tenga las mismas clases cargadas en dos cargadores de clases diferentes. Esto puede ocurrir en caso de que necesite varias versiones de la misma clase en la memoria al mismo tiempo, o si está haciendo algunas cosas sobre compilación sobre la marcha (como yo).

En este caso, si desea considerar esto como la misma clase (que podría ser razonable según el caso), puede hacer coincidir sus nombres para compararlos.

public static boolean areClassesQuiteTheSame(Class<?> c1, Class<?> c2) { 
    // TODO handle nulls maybe? 
    return c1.getCanonicalName().equals(c2.getCanonicalName()); 
} 

Tenga en cuenta que esta comparación hará exactamente lo que hace: comparar los nombres de las clases; No creo que puedas transmitir desde una versión de una clase a otra, y antes de reflexionar, es posible que quieras asegurarte de que haya una buena razón para el desastre de tu cargador de clases.

1

Comprobar código fuente para Class.java iguales()

public boolean equals(Object obj) { 
return (this == obj); 
} 
0

Hmmm ... Tenga en cuenta que la clase puede o no implementar equals() - que no es requerido por la especificación. Por ejemplo, HP Fortify marcará myClass.equals (myOtherClass).