2010-03-09 3 views
56

Dans un androïde suite de tests d'application que j'ai une classe comme celui-ci où B est une vue:Comment vérifier si une sous-classe est une instance d'une classe lors de l'exécution?

public class A extends B { 
... etc... 
} 

maintenant j'ai une liste d'objets de vue qui peuvent contenir A objets, mais dans ce cas, je ne se soucient que si elles re sous-classes ou «instances de» B. Je voudrais faire quelque chose comme:

ArrayList<View> viewList = getViews(); 
Iterator<View> iterator = viewList.iterator(); 
while (iterator.hasNext() && viewList != null) { 
    View view = iterator.next(); 
    if (view.getClass().isInstance(B.class)) { 
     // this is an instance of B 
    } 
} 

Le problème est que lorsque le if rencontre un objet A il n'évalue pas à une « instance de B ». Y at-il un moyen de faire isSubclassOf ou quelque chose?

+1

si le tableau ViewList est null, plantage de votre programme, même l'enregistrement tout ne contribue pas. – Tim

+2

From Effective C++, par Scott Meyers: "Chaque fois que vous vous trouvez en train d'écrire du code" si l'objet est de type T1, alors faites quelque chose, mais si c'est du type T2, faites autre chose ". – ishmeister

+1

C'est pour un cas de test donc le code n'est pas réellement dans l'application de production, c'est pour tester pour s'assurer que les choses utilisent les bonnes classes :) – iamamused

Répondre

136

Vous devez lire attentivement l'API pour cette méthode. Parfois, vous pouvez être confus très facilement.

Il est soit:

if (B.class.isInstance(view)) 

API dit: Détermine si le spécifié objet(le paramètre) est compatible pour l'affectation avec l'objet représenté par cette classe(L'objet de classe que vous sont appelant la méthode à)

ou:

if (B.class.isAssignableFrom(view.getClass())) 

API dit: Détermine si la classe ou de l'interface représentée par cet objet de classe est soit le même que, ou est une superclasse ou superinterface de la classe ou de l'interface représentée par le spécifié paramètre classe

ou (sans réflexion et recommander un):

if (view instanceof B) 
+9

+1 pour if (voir instance de B). Simple et fonctionne. –

+10

Notez que 'instanceof' ne fonctionnera pas pour les génériques en raison de l'effacement. – Qix

+1

@Qix Merci pour l'info. Les effacements sont une douleur dans plus d'une partie du corps, mais travailler sans Generics est pire. – Hardcoded

21
if(view instanceof B) 

Ceci renvoie vrai si vue est une instance de B ou la sous-classe A (ou une sous-classe de B pour cette matière).

+2

Je voudrais mentionner que B doit être importé dans le fichier .java actuel pour que cela fonctionne.Eclipse marquera la ligne comme ayant une erreur mais n'offrira aucune solution utile sinon (gaspillé près d'une heure à essayer une syntaxe différente avant de réaliser que je n'avais tout simplement pas importé le fichier de classe.) Pour tout le monde, la syntaxe correcte est ((nom d'instance) instanceof (nom de classe)). La classe de mots n'apparaît nulle part en elle. – ArtOfWarfare

8

Peut-être que je manque quelque chose, mais ne serait-ce suffire:

if (view instanceof B) { 
    // this view is an instance of B 
} 
2

Il est l'inverse: B.class.isInstance(view)

-1

Je n'ai jamais utilisé, mais essayez view.getClass().getGenericSuperclass()

+1

La méthode est mal nommée et documentée. Cela n'aidera pas le problème, puisque ni A ni B n'ont de génériques. – Hardcoded

0

en cas de polymorphisme, comme la vérification SQLRecoverableException vs SQLException, il peut être fait comme ça.

try { 
    // sth may throw exception 
    .... 
} catch (Exception e) { 
    if(SQLException.class.isAssignableFrom(e.getCause().getClass())) 
    { 
     // do sth 
     System.out.println("SQLException occurs!"); 
    } 
} 

Il suffit de dire,

ChildClass child= new ChildClass(); 
if(ParentClass.class.isAssignableFrom(child.getClass())) 
{ 
    // do sth 
    ... 
} 
+1

Ne faites pas quelque chose comme attraper Exception et vérifier la classe de l'exception, si vous n'avez pas vraiment une bonne raison pour cela. faire à la place: '} catch (SQLException e) { } catch (Exception e) { }' – Hardcoded

Questions connexes