J'ai les classes A
, B
, C
et D
où B
s'étend A
, C
étend A
et D
étend A
.
J'ai la ArrayList
s suivante avec chacun quelques éléments:
ArrayList<B> b;
ArrayList<? extends A> mix = b;
Je voulais que la variable mix
contienne des éléments de type B
, C
ou D
. J'ai essayé d'ajouter un élément de type C
dans mix
comme ceci:
mix.add(anElementOfTypeC);
Mais le IDE ne me permet pas de le faire et dit:
anElementOfTypeC ne peut pas être converti en CAP n ° 1 par la méthode d’invocation conversion où CAP # 1 est une nouvelle variable type: CAP # 1 étend A à partir de capture de? étend A
Ai-je utilisé le <? extends A>
correctement? Comment puis-je résoudre ça?
ArrayList<? extends A>
désigne une ArrayList d'un type inconnu qui étend A
.
Ce type peut ne pas être C
, vous ne pouvez donc pas ajouter C
à ArrayList.
En fait, puisque vous ne savez pas ce que ArrayList est censé contenir, vous ne pouvez pas ajouter rien à ArrayList.
Si vous voulez une ArrayList pouvant contenir n'importe quelle classe qui hérite de A
, utilisez un ArrayList<A>
.
Il n'est pas possible d'ajouter des éléments dans la collection qui utilisent ? extends
.
ArrayList<? extends A>
signifie qu'il s'agit d'une ArrayList
de type ( exactement un type) qui étend A
. Vous pouvez donc être sûr que lorsque vous appelez la méthode get
, vous obtiendrez quelque chose qui est A. Mais vous ne pouvez pas ajouter quelque chose car vous ne savez pas exactement ce qui contient ArrayList
.
Ai-je utilisé le
<? extends A>
correctement?
List<? extends A> list;
signifie que la «liste» fait référence à une liste d'interface implémentée par un objet et que la liste peut contenir des éléments hérités de la classe A (y compris A). En d'autres termes, les affirmations suivantes sont correctes:
List<? extends A> listA1 = new ArrayList<A>();
List<? extends A> listB1 = new ArrayList<B>();
List<? extends A> listC1 = new ArrayList<C>();
List<? extends A> listD1 = new ArrayList<D>();
Les génériques Java sont une vérification de type forte au moment de la compilation . Le compilateur utilise des génériques pour s’assurer que votre code n’ajoute pas les mauvais objets à une collection.
Vous avez essayé d'ajouter C
dans ArrayList<B>
listB1.add(new C());
S'il était autorisé, l'objet ArrayList<B>
contiendrait différents types d'objet (B, C).
C'est pourquoi la liste reference listB1 fonctionne en mode "lecture seule". De plus, vous pouvez regarder cette réponse .
comment résoudre cela?
List<A> list = new ArrayList<A>();
Vous pouvez simplement déclarer:
ArrayList<A> mix = new ArrayList<A>();
Vous pouvez ajouter n'importe quel élément de la classe A ou l'une de ses sous-classes dans une telle liste. C'est juste que lorsque vous obtenez de cette liste, vous ne pourrez appeler que des méthodes disponibles sur A
.
Notez que A
ne se limite pas à être une classe "à part entière": il peut s'agir d'une classe abstraite ou même d'une interface.
Vous pouvez créer la liste de tableaux du type super classe. afin que vous puissiez le faire.
ArrayList<A> arrayList=new ArrayList<A>();
Regardez cet exemple et choisissez selon vos besoins
package com.generic;
import Java.util.ArrayList;
public class SuperExtendTest {
/**
* @param args
*/
public static void main(String[] args) {
}
public void test() throws Exception {
ArrayList<Parent> parents=new ArrayList<>();
parents.add(new Parent());
parents.add(new Child());
//parents.add(new GrandParent()); Not allowed
ArrayList<Parent> p=new ArrayList<>();
ArrayList<Child> c=new ArrayList<>();
ArrayList<GrandParent> gp=new ArrayList<>();
testExtendP(p);
//testExtendP(c); Not allowed only super type allowed no child
testExtendP(gp);
testExtends(c);
testExtends(p);
//testExtends(gp); Not allowed because GrantParent does not extends Parent
}
/**
* This Method allowed get operations for Parent
* No add
*
*/
public void testExtends(ArrayList<? extends Parent> list) throws Exception {
/* list.add(new Child());
list.add(new Parent());
list.add(new GrandParent());
// can not add
*/
Child c=(Child) list.get(0);
Parent parent=list.get(0);
GrandParent gp=list.get(0);
/**
* Unsafe collection way
*/
ArrayList list2=new ArrayList();
list.addAll(list2);
}
/**
* This Method allowed add operations for Parent and it's sub types and on get it gives Object type
*
*/
public void testExtendP(ArrayList<? super Parent> list) throws Exception {
list.add(new Child());
list.add(new Parent());
//list.add(new GrandParent());
/*can not add because GrandParent can not be converted to Parent type
*
* The method add(capture#3-of ? super Parent) in the type ArrayList<capture#3-of ? super Parent> is not applicable for the arguments (GrandParent)
*
*/
Child c=(Child) list.get(0);
Parent parent=(Parent) list.get(0);
GrandParent gp=(GrandParent) list.get(0);
Object obj=list.get(0);
/**
* Unsafe collection way
*/
ArrayList list2=new ArrayList();
list.addAll(list2);
}
/**
* This Method allowed all operations for Parent and it's sub types
*
*/
public void testDirect(ArrayList<Parent> list) throws Exception {
list.add(new Child());
list.add(new Parent());
//list.add(new GrandParent());
/*
* Can not add GrandParent (Normal generic rule)
*/
}
}
class GrandParent{
}
class Parent extends GrandParent{
}
class Child extends Parent{
}