带有ArrayList的Java Generic 添加元素

我有ABCD类,其中B延伸AC延伸AD延伸A

我有以下ArrayList每个都有几个元素:

 ArrayList b; ArrayList mix = b; 

我打算让变量mix包含BCD类型的元素。 我尝试将类型C的元素添加到这样的mix

 mix.add(anElementOfTypeC); 

但IDE不允许我这样做,它说:

anElementOfTypeC不能通过调用转换的方法转换为CAP#1,其中CAP#1是一个新的类型变量:CAP#1从捕获?扩展A? 延伸A.

我用的是 正确 ? 我该如何解决这个问题?

ArrayList ArrayList表示ArrayList的某种未知类型的ArrayList。
该类型可能不是C ,因此您无法将C添加到ArrayList。

实际上,由于您不知道ArrayList应该包含什么,因此您无法向ArrayList添加任何内容

如果您想要一个可以包含任何inheritanceA类的ArrayList ,请使用ArrayList

在使用的集合中添加元素是不可能的? extends ? extends

ArrayList ArrayList意味着这是一个ArrayList的类型( 恰好是一种类型)的ArrayList 。 所以你可以肯定,当你调用get方法时,你会得到一些东西。但你不能添加东西,因为你不知道究竟是什么包含ArrayList

我用的是 正确

List list; 表示’list’指的是一个对象实现的接口List,该列表可以包含从A类inheritance的元素(包括A)。 换句话说,以下陈述是正确的:

 List listA1 = new ArrayList(); List listB1 = new ArrayList(); List listC1 = new ArrayList(); List listD1 = new ArrayList(); 

Javagenerics是一种编译时强类型检查。 编译器使用generics来确保您的代码不会将错误的对象添加到集合中。

您试图在ArrayList添加C

 listB1.add(new C()); 

如果允许,则对象ArrayList将包含不同的对象类型(B,C)。
这就是参考 listB1以’只读’模式工作的原因。 另外你可以看看这个答案 。

怎么解决这个?

 List list = new ArrayList(); 

你可以宣布:

 ArrayList mix = new ArrayList(); 

您可以将A类或其任何子类的任何元素添加到此类列表中。 只是当你从该列表中获得时,你将只能调用A可用的方法。

请注意, A不仅限于“完全成熟”类:它可以是抽象类,甚至是接口。

您可以创建超类类型的数组列表。 所以你可以做到这一点。

 ArrayList arrayList=new ArrayList(); 

查看此示例并根据您的要求进行选择

 package com.generic; import java.util.ArrayList; public class SuperExtendTest { /** * @param args */ public static void main(String[] args) { } public void test() throws Exception { ArrayList parents=new ArrayList<>(); parents.add(new Parent()); parents.add(new Child()); //parents.add(new GrandParent()); Not allowed ArrayList p=new ArrayList<>(); ArrayList c=new ArrayList<>(); ArrayList 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 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 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 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 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{ }