Je veux comparer le type de classe en Java.
Je pensais pouvoir faire ceci:
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");
}
Je voulais comparer au cas où l'obj transmis à la fonction était étendu à partir de MyObject_1 ou non . Il semble que la méthode getClass () et la classe .class donnent un type d'information différent.
Comment comparer deux types de classe sans avoir à créer un autre objet factice pour comparer le type de classe?
Essaye ça:
MyObject obj = new MyObject();
if(obj instanceof MyObject){System.out.println("true");} //true
En raison de l'héritage, ceci est également valable pour les interfaces:
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
Pour en savoir plus sur instanceof: http://mindprod.com/jgloss/instanceof.html
Si vous ne voulez pas ou ne pouvez pas utiliser instanceof
, comparez avec equals
:
if(obj.getClass().equals(MyObject.class)) System.out.println("true");
BTW - c'est étrange, car les deux instances Class
de votre déclaration devraient être identiques, du moins dans votre exemple de code. Ils peuvent être différents si:
Il imprime true
sur ma machine. Et ce devrait être le cas, sinon rien en Java ne fonctionnerait comme prévu. (Ceci est expliqué dans le JLS: 4.3.4 Quand les types de référence sont identiques )
Avez-vous plusieurs chargeurs de classe en place?
Ah, et en réponse à ce commentaire:
Je me rends compte que j'ai une faute de frappe dans mon question. Je devrais être comme ça:
MyImplementedObject obj = new MyImplementedObject ();
if(obj.getClass() == MyObjectInterface.class) System.out.println("true");
MyImplementedObject implémente MyObjectInterface Donc, en d'autres termes, je Je le compare avec son implémenté objets.
OK, si vous voulez vérifier que vous pouvez faire soit:
if(MyObjectInterface.class.isAssignableFrom(obj.getClass()))
ou beaucoup plus concis
if(obj instanceof MyobjectInterface)
Comme indiqué précédemment, votre code fonctionnera à moins que les mêmes classes ne soient chargées sur deux chargeurs de classes différents . Cela peut arriver si vous avez besoin de plusieurs versions de la même classe en mémoire en même temps, ou si vous faites des choses étranges sur la compilation des trucs (comme je suis).
Dans ce cas, si vous souhaitez les considérer comme appartenant à la même classe (ce qui peut être raisonnable selon les cas), vous pouvez faire correspondre leurs noms pour les comparer.
public static boolean areClassesQuiteTheSame(Class<?> c1, Class<?> c2) {
// TODO handle nulls maybe?
return c1.getCanonicalName().equals(c2.getCanonicalName());
}
Gardez à l'esprit que cette comparaison fera exactement ce qu'elle fait: comparer les noms de classe; Je ne pense pas que vous serez en mesure de passer d’une version d’une classe à l’autre et, avant de vous pencher sur la réflexion, vous voudrez peut-être vous assurer qu’il ya une bonne raison pour le désordre de votre chargeur de classe.
Vérifiez le code source de Class.Java pour equals ()
public boolean equals(Object obj) {
return (this == obj);
}
Hmmm ... Gardez à l'esprit que Class peut ou non implémenter equals () - ce n'est pas requis par la spécification Par exemple, HP Fortify marquera myClass.equals (myOtherClass).