web-dev-qa-db-fra.com

Comment vérifier si une sous-classe est une instance d'une classe au moment de l'exécution?

Dans une suite de tests d'applications Android, j'ai une classe comme celle-ci où B est une vue:

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

j'ai maintenant une liste d'objets de vue pouvant contenir des objets A, mais dans ce cas, je me soucie seulement de savoir s'ils sont des sous-classes ou des "instances de" B. J'aimerais 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 if rencontre un objet A, il ne correspond pas à une "instance de B". Y a-t-il un moyen de faire isSubclassOf ou quelque chose?

68
iamamused

Vous devez lire l'API attentivement pour ces méthodes. Parfois, vous pouvez vous confondre très facilement.

C'est soit:

if (B.class.isInstance(view))

L'API dit: Détermine si le objet spécifié (le paramètre) est compatible avec les affectations avec l'objet représenté par this Class (L'objet de classe auquel vous appelez la méthode)

ou:

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

L'API dit: Détermine si la classe ou l'interface représentée par ceci objet Classe est identique à, ou est une superclasse ou une superinterface de la classe ou interface représentée par le paramètre Classe spécifiée

ou (sans réflexion et le recommander):

if (view instanceof B)
154
Hardcoded
if(view instanceof B)

Cela retournera true si view est une instance de B ou de la sous-classe A (ou toute sous-classe de B d'ailleurs).

24
Kris

Peut-être que je manque quelque chose, mais cela ne suffirait-il pas:

if (view instanceof B) {
    // this view is an instance of B
}
10
Joachim Sauer

Class.isAssignableFrom() - fonctionne également pour les interfaces. Si vous ne le souhaitez pas, vous devrez appeler getSuperclass() et tester jusqu'à atteindre Object.

6

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

2
nanda

S'il existe un polymorphisme tel que la vérification de SQLRecoverableException vs SQLException, cela 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!");
    }
}

Dites simplement,

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