2011-03-21 5 views
5

après recherché pendant un certain temps je ne pouvais pas encore trouver une réponse à ma question, même il y a quelques Generics sujet connexe, donc ici vous allez:supérieur générique lié à Java Generics

ArrayList<? super IOException> list = new ArrayList<Exception>(); 
list.add(new FileNotFoundException("this is ok.")); 
list.add(new IOException("This is ok")); 
list.add(new ClassCastException("compile err"));//why compile err? 
list.add(new Exception("compile err"));//why compile err? 

Pourquoi deux dernière ligne ne compile pas? Surtout la dernière ligne. J'ai fait pas mal de test sur ce sujet mais je n'arrivais toujours pas à comprendre la logique.

Merci.

Répondre

8

ArrayList<? super IOException> pourrait être l'un des suivants (car il y a une wild card):

ArrayList<IOException> 
ArrayList<Exception> 
ArrayList<Throwable> 
ArrayList<Object> 

Le code doit travailler avec les quatre possibilités.

Mais si c'est un ArrayList<IOException>, vous ne pouvez pas mettre un ClassCastException ou un Exception, d'où les erreurs de compilation.

Voici ce que je ne comprends pas: pourquoi celui-ci compile ------ >>> list.add (new FileNotFoundException ("this is ok.")); < < < ---- Je pense que FileNotFoundException est également sous la limite de IOException. mais il compile bien.

Non, FileNotFoundException est très bien, car il étend IOException et vous pouvez le mettre dans chacun des quatre types de listes.

Notez que pour des raisons historiques, les tableaux ne reçoivent pas la même vérification de type strict, vous pouvez compiler les éléments suivants (puis faire une exception du magasin de tableau à l'exécution):

Exception[] a = new IOException[4]; 
    a[0] = new FileNotFoundException("this is ok."); 
    a[1] = new IOException("This is ok"); 
    a[2] = new ClassCastException("compiles, but boom!"); 
    a[3] = new Exception("compiles, but boom!"); 
+0

@Kai cela aide à répondre à votre question clairement. – asgs

+0

Merci, Tom aussi, voici ce que je ne comprends pas: pourquoi celui-ci compile ------ >>> list.add (nouvelle FileNotFoundException ("this is ok.")); <<< ---- Je pense que FileNotFoundException est également sous la limite de IOException. mais il compile bien. –

+0

Après un moment de digest, finalement eu l'idée :) même après line1, list = new ArrayList (), mais les types de classe de base des éléments de la liste sont toujours restreints dans les classes satisfaites de la condition "? Super IOException", in un autre mot, la classe de base de l'élément doit être au moins (ou sous-classe de) IOException. –

1

Exception est la superclasse comme IOExceptionException étend. Vous pouvez utiliser:

List<Exception> list = new ArrayList<Exception>(); 
list.add(...); // any exception 

Ensuite, il compilera pour tous les types d'exception.

+0

oui, je sais, mais j'ai encore besoin de comprendre la raison de la question. de toute façon thanX :) –

+1

désolé, mais cela ne répond pas encore à ma question :(. –

+0

Je veux dire donné la validité de la première ligne (la définition de la liste était valide), et quelle est la logique pour le compilateur à échouer les deux derniers –

0

Je pense que la dernière des exceptions ne sont pas dérivées de la classe de base IOException

+0

Je pensais exactement le contraire: puisque 'super' indique que toute classe sur laquelle "IOException based-on" devrait être valide, par exemple 'Exception' ou 'Object', mais cela semble vrai seulement pour la première ligne, mais pas pour le reste, toujours hors de la logique X- (. –

4

Tenir compte de la même déclaration de list, mais avec une autre affectation:

ArrayList<? super IOException> list = new ArrayList<IOException>(); 

Aucun changement dans le type de list, mais maintenant ajouter un ClassCastException ou Exception est clairement faux.

+0

Pourriez-vous être plus précis? plus de détails s'il vous plaît, je pense que vous qui comprenez le noyau de ma question, alors s'il vous plaît donner plus de détails –

+0

@Kai Que c'est le type de la référence qui compte? Ou que vous ne devriez pas pouvoir ajouter une 'Exception' à' ArrayList 'ou que cela puisse, en général, être une autre référence' ArrayList' avec différents (mais correct) limites? –

+0

ou quelqu'un pourrait étendre cette réponse plus en détail s'il vous plaît, un exemple? –

0

Selon votre référence ArrayList générique déclaration, Vous pouvez uniquement ajouter une exception IOException (à cause de? super) ou les objets qui étend IOException dans la liste.

ClassCaseException et Exception ne sont pas dérivés de IOException, il échoue donc.

1

Pour moi, cela se réfère aux caractères génériques de la limite inférieure: <? super IOException>. Les caractères génériques avec une limite supérieure seraient <? extends IOException>.Le caractère générique dans votre exemple ne semble efficace que dans la ligne où le nouveau Object est affecté à la variable

Quand on y accède plus tard, il n'est évidemment plus efficace. Il est alors exactement le même que ArrayList<IOException>. Donc, votre explication à vous-même est apparemment erronée. Upper borned et lower borned signifie ce qu'il dit.