如何在不修改其余代码的情况下为此类快照声明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);
}
但有没有办法避免更改代码?
答案 0 :(得分:3)
将bList
(List<ClassB>
)分配给mixedList
(List<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;
此代码编译(用于简单编译检查的字符串)