web-dev-qa-db-fra.com

Impossible d'effectuer une vérification de type paramétré ArrayList <Foo>

Le code suivant:

((tempVar instanceof ArrayList<Foo>) ? tempVar : null);

causes: 

Impossible d'effectuer la vérification instanceof par rapport au type paramétré ArrayList<Foo>. Utilisez plutôt le formulaire ArrayList<?> car d'autres informations de type génériques seront effacées lors de l'exécution.

Quelqu'un peut-il m'expliquer ce que l'on entend par "d'autres informations de type génériques seront effacées lors de l'exécution" et comment y remédier?

47
Caner

Cela signifie que si vous avez quelque chose qui est paramétré, par exemple. List<Foo> fooList = new ArrayList<Foo>();, les informations génériques seront effacées au moment de l'exécution. C’est à la place ce que la machine virtuelle Java verra List fooList = new ArrayList();.

C'est ce qu'on appelle type erasure . La machine virtuelle Java ne dispose d'aucune information de type paramétrée de la variable List (dans l'exemple) pendant l'exécution.

Une réparation? Étant donné que la machine virtuelle Java ne dispose pas d'informations de type paramétré au moment de l'exécution, vous ne pouvez pas utiliser une variable instanceof de ArrayList<Foo>. Vous pouvez "stocker" explicitement le type paramétré et y faire une comparaison.

50
Buhake Sindi

Vous pouvez toujours le faire à la place

try
{
    if(obj instanceof ArrayList<?>)
    {
        if(((ArrayList<?>)obj).get(0) instanceof MyObject)
        {
            // do stuff
        }
    }
}
catch(NullPointerException e)
{
    e.printStackTrace();
}
25
Greg

En raison de l'effacement du type, le type paramétré de ArrayList ne sera pas connu au moment de l'exécution. Le mieux que vous puissiez faire avec instanceof est de vérifier si tempVar est une ArrayList (de quelque chose). Pour ce faire, utilisez les méthodes suivantes: 

((tempVar instanceof ArrayList<?>) ? tempVar : null);
10
Paul Bellora

C'est suffisant: 

if(obj instanceof ArrayList<?>)
{
   if(((ArrayList<?>)obj).get(0) instanceof MyObject)
   {
       // do stuff
   }
}

En fait, instanceof vérifie si l'opérande de gauche est null ou non et renvoie false s'il est réellement null.
Donc: pas besoin d’attraper NullPointerException.

2
StøcciD

Vous ne pouvez pas réparer ça. Les informations de type pour Generics ne sont pas disponibles au moment de l'exécution et vous n'y aurez pas accès. Vous pouvez uniquement vérifier le contenu du tableau.

1
flob

instanceof opérateur fonctionne au moment de l'exécution. Mais Java ne porte pas les informations de type paramétrées au moment de l'exécution. Ils sont effacés au moment de la compilation. D'où l'erreur. 

1
deeKay

Vous pouvez utiliser

boolean isInstanceArrayList = tempVar.getClass() == ArrayList.class
0
Devishankar

Tu pourrais toujours faire ça

Créer une classe

public class ListFoo {
  private List<Foo> theList;

  public ListFoo(List<Foo> theList {
    this.theList = theLista;
  }

  public List<Foo> getList() {
    return theList;
  }
}

N'est-ce pas pareil mais ...

myList = new ArrayList<Foo>;
.....
Object tempVar = new ListFoo(myList);
....
((tempVar instanceof ListFoo) ? tempVar.getList() : null);
0
jmfm