2009-09-11 5 views
1

Dire que j'ai 3 classes comme ceci:Y at-il un moyen de déterminer de quel type une classe est une instance de Java?

class A {} 
class B extends A {} 
class C extends A {} 

Serait-il alors possible de déterminer si un objet particulier est une instance de A, B ou C?

Je pensais que quelque chose comme cela pourrait fonctionner:

if (myObject.getClass().isInstance(B.class)) { 
    // do something for B 
} else (myObject.getClass().isInstance(C.class)) { 
    // do something for C 
} else { 
    // do something for A 
} 

mais après avoir lu un peu, je pense qu'il évaluerait toujours en B car il teste simplement si un casting fonctionnerait et il n'y a pas de différence substantielle entre eux.

Répondre

7

Pour ce faire:

if (myObject instanceof B) { 
    // do something for B 
} else (myObject instanceof C) { 
    // do something for C 
} else { 
    // do something for A 
} 
+0

Merci pour la réponse rapide ... exactement ce que je cherchais. –

9

Le plus simple et le code plus rapide est:

if (myObject instanceof B) { 
} else if (myObject instanceof C) { 
} else if (myObject instanceof A) { 
} 

Notez que l'ordre est important: vous devez avoir le test A dernier, car cela réussira à instances de B et C ainsi.

Cependant, votre code d'origine fonctionnerait presque. Class.isInstance vérifie si la valeur est réellement une instance de la classe donnée ou une superclasse. Donc, si myObject est une instance de C, alors B.class.isInstance(myObject) retournera false. Tout ce que vous avez tort est que vous appelez getClass() sur myObject inutilement, au lieu d'utiliser B.class etc.

Telle est l'approche que vous prendriez si vous ne saviez pas que les classes que vous étiez intéressé au moment de la compilation - l'opérateur instanceof fonctionne uniquement lorsque vous pouvez spécifier le type statiquement dans le code.

Maintenant, si vous voulez savoir si myObject est une instance de exactementB (et non une sous-classe), puis il suffit d'utiliser:

if (myObject.getClass() == B.class) 

(Ce explosera si myObject est une référence null, bien sûr.)

+0

Répondu dans le stack-overfl ... Je veux dire, Skeet-overkill style. :RÉ – Epaga

0

Il ya l'opérateur instanceof qui fait ce que vous voulez, comme d'autres ont répondu. Mais sachez que si vous avez besoin de quelque chose comme ça, c'est un signe qu'il pourrait y avoir une faille dans la conception de votre programme. La meilleure façon de faire cela est d'utiliser le polymorphisme: mettre une méthode dans la superclasse A, remplacer cette méthode en B et C, et appeler la méthode sur myObject (qui devrait avoir le type A):

A myObject = ...; // wherever you get this from 

// Override someMethod in class B and C to do the things that are 
// specific to those classes 
myObject.someMethod(); 

instanceof est moche et devrait être évité autant que possible, tout comme la coulée est laide, potentiellement dangereuse et devrait être évitée.

1

Vous pouvez également regarder le double dispatch idiom qui est une manière OO de changer le comportement basé sur le type d'un argument dans les langues qui ne supportent pas les multi-méthodes.

0

vous pouvez le faire

if (myObject.getClass() == B.class) { 
    // do something for B (not subclasses of b!!!) 
} else if(myObject.getClass() == C.class) { 
    // do something for C (not subclasses of c!!!) 
} else if(myobject.getClass() == A.class) { 
    // do something for A (not subclasses of A!!) 
} else if(myobjects instanceof A){ 
    //all other subclasses of A 
} 
Questions connexes