相同的擦除但不是相同的类型。

时间:2017-01-22 18:15:32

标签: java generics casting erasure

如果ArrayList<Class<?>>具有相同的ArrayList<Object>删除但不能投射到它的情况怎么样?

我的代码目前正在两次日食错误之间切换。

GenericExclusiveSelectionPanel transport = 
                new GenericExclusiveSelectionPanel(StringConstants.TRANSPORT,
                    (ArrayList<Object>)TransportManager.getInstance().getTransportTypes());

显示:

Cannot cast from ArrayList<Class<Transportable>> to ArrayList<Object>

如果我删除了强制转换并创建了一个构造函数:
GenericExclusiveSelectionPanel(String, ArrayList<Class<Transportable>>)

我得到了日食错误:

Erasure of method GenericExclusiveSelectionPanel(String, 
   ArrayList<Class<Transportable>>) is the same as another method in type 
   GenericExclusiveSelectionPanel

然后突出显示构造函数(下面)作为冲突的构造函数。

GenericExclusiveSelectionPanel(String title, ArrayList<Object> arrayList)

1 个答案:

答案 0 :(得分:1)

如果我们首先了解 type erasure 对于Java中的 Generics 的含义,那么为什么会发生这种情况会更容易理解。在继续之前,请先查看Oracle文档中的type erasure

现在您已了解擦除类型的含义,让我们看一下Oracle文档对generics所说的内容。

从文档中可以清楚地看出, Generics 的主要目标是提供更严格的编译时间检查。如果编译器没有使用泛型强制检查强制转换,那将是相当矛盾的。为了便于讨论,假设允许以下陈述:

List<String> strings = new ArrayList<String>();//1
strings.add("123");//2
List<Object> objects = strings;//3
objects.add(1);//4

如果编译器未在步骤3中限制分配,则可以将Integer添加到String个对象的列表中。如果编译器没有在步骤3中抱怨任务,这反过来又允许我们继续执行第4步,那么 Generics 首先有什么用呢?

类似地,虽然ArrayList<Class<Transportable>>ArrayList<Object>具有相同的擦除,但编译器正好如上所述抱怨他们的分配。总之,使用 Generics 限制这些强制转换与限制具有相同擦除的构造函数/方法一样重要。