快速遗留给泛型转换问题

时间:2011-08-02 22:46:44

标签: java generics

如何在不修改其余代码的情况下为此类快照声明mixedList泛型?

List mixedList = new ArrayList();
if(flagA) {
    ClassA a = new ClassA(); //comes from elsewhere
    mixedList.add(a)
} else {
    List<ClassB> bList = new ArrayList<ClassB>();  //comes from elsewhere
    mixedList = bList; //error
}

我能做到:

List<Object> mixedList = new ArrayList<Object>();
if(flagA) {
    ...
} else {
    ...
    mixedList.addAll(bList);
}

但有没有办法避免更改代码?

3 个答案:

答案 0 :(得分:3)

bListList<ClassB>)分配给mixedListList<Object>)是不安全的。

您从中获得bList的服务可能会保留对它的引用;此服务将假定其列表仅包含ClassB个实例。如果 允许将该列表分配给List<Object>引用,则可以在不发出警告的情况下将任何类型的对象添加到列表中。但是当服务认为其列表中的每个元素都是ClassB时,试图访问这些元素时,会引发ClassCastException

创建新的List<Object>,并使用add()addAll()向其中添加元素,可以防止此“类型污染”。您可以安全地修改列表的这个副本,并让列表的源保持其自己的副本“纯粹”。

答案 1 :(得分:0)

我不相信它可以做到。

咆哮:

除了简单的收集使用之外,Java Generics imo只是不值得头疼我可以和演员一起生活。众所周知,仿制药给出了类型安全的贴面,但在封面下有类型猴子修补。

/ Rant完成:

这样做但你需要为相应的一个块进行参考调整 - 这里我选择List<?>mixedList并调整案例flagA:< / p>

public static void foo(boolean flagA) {
    List<?> mixedList = new ArrayList<Object>();
    if(flagA) {
        ClassA a = new ClassA(); //comes from elsewhere
        List<Object> mixedList2 = (List<Object>) mixedList; // mod
        mixedList2.add(a);
    } else {
        List<ClassB> bList = new ArrayList<ClassB>();  //comes from elsewhere
        mixedList = bList;
    }
}

答案 2 :(得分:-1)

很难知道你在问什么,特别是关于“不改变代码”的部分(为什么然后问一个问题)。然而,似乎你可以为你的列表给出一些限制:

List<? extends Class<?>> mixedList = new ArrayList<Class<?>>();
List<Class<String>> bList = new ArrayList<Class<String>>(); 
bList.add(String.class);
mixedList = bList;

此代码编译(用于简单编译检查的字符串)