Pourquoi la conversion d’un générique ArrayList dans une super-classe ne fonctionne-t-elle pas?

Quelqu’un peut-il m’expliquer s’il vous plaît pourquoi la ligne marquée //this line gives a comstack error (why?) Dans l’exemple de code suivant ne fonctionne pas?

 import java.util.ArrayList; public class GenericCastCheck { class A{ } class B extends A{ } public static void main(Ssortingng[] args) { A aObject = new A(); B bObject = new B(); //this line works fine aObject = bObject; //this line gives a comstack (expected) bObject = aObject; ArrayList aList = new ArrayList(); ArrayList bList = new ArrayList(); //this line gives a comstack error (why?) aList = bList; //this line gives a comstack error (expected) bList = aList; } } 

Plus précisément, lorsque nous disons que bList est de type ArrayList , cela ne signifie-t-il pas que chaque élément de celle-ci est une instance de B ? Si tel est le cas, quel est le problème pour le ArrayList en ArrayList , si nous pouvons convertir des instances individuelles de B en A ?

Merci.

Le problème est le suivant:

 ArrayList aList = new ArrayList(); ArrayList bList = new ArrayList(); aList = bList; // if this were valid... aList.add(new A()); // ...what should happen here? B b = bList.get(0); // ...and here? 

Si vous faites la même chose avec les tableaux, vous obtenez une exception ArrayStoreException sur la ligne 4 au moment de l’exécution. Pour les collections génériques, il a été décidé d’empêcher ce genre de chose au moment de la compilation.

Parce que les génériques sont ssortingcts. ils ne sont pas covarient

ArrayList aList ne peut faire référence qu’à un ArrayList de type A


Depuis le wiki

Contrairement aux tableaux, les classes génériques ne sont ni covariantes ni contravariantes. Par exemple, ni List ni List sont un sous-type de l’autre:

 // a is a single-element List of Ssortingng List a = new ArrayList(); a.add("foo"); // b is a List of Object List b = a; // This is a comstack-time error 

Cependant, les parameters de type générique peuvent contenir des caractères génériques (un raccourci pour un paramètre de type supplémentaire utilisé une seule fois). Exemple: étant donné que la méthode requirejse pour une méthode opère sur des listes, quel que soit l’object, les seules opérations pouvant être effectuées sur l’object sont celles pour lesquelles les relations de type peuvent être garanties comme sûres.

 // a is a single-element List of Ssortingng List a = new ArrayList(); a.add("foo"); // b is a List of anything List b = a; // resortingeve the first element Object c = b.get(0); // This is legal, because we can guarantee // that the return type "?" is a subtype of Object // Add an Integer to bbadd(new Integer (1)); // This is a comstack-time error; // we cannot guarantee that Integer is // a subtype of the parameter type "?" 

Les caractères génériques peuvent également être liés, par exemple ” ? extends Foo ” ou ” ? super Foo ” pour les limites supérieure et inférieure, respectivement. Cela permet d’affiner les performances autorisées. Exemple: donné une List List , puis un élément peut être récupéré et affecté en toute sécurité à un type Foo (covariance). Étant donné une List List , un object Foo peut être ajouté en toute sécurité en tant qu’élément (contravariance).

Animesh,

Même si la classe B est le sous-type de A, ArrayList n’est pas un sous-type de ArrayList . Son sur la même ligne que dans B [] n’est pas un sous-type de A []. Ce sont deux types indépendants non liés.

Comme il n’existe pas en Java de relation de sous-type entre C et C , même si A est un supertype de B ou inversement.

Si vous êtes intéressé par la recherche de détails corrélation / corrélation dans Wikipedia.

Notez que dans Java, les tableaux sont co-variant, ce qui signifie que A[] est un supertype de B[] si A est un supertype de B C’est la raison pour laquelle vous obtenez parfois une exception de dissortingbution étrange avec les tableaux.