How to declare mixedList
with generics for such snapshot without modifying the rest of the code?
List mixedList = new ArrayList();
if(flagA) {
开发者_如何学Go ClassA a = new ClassA(); //comes from elsewhere
mixedList.add(a)
} else {
List<ClassB> bList = new ArrayList<ClassB>(); //comes from elsewhere
mixedList = bList; //error
}
I can do:
List<Object> mixedList = new ArrayList<Object>();
if(flagA) {
...
} else {
...
mixedList.addAll(bList);
}
but is there a way to avoid changing the code?
It's not safe to assign bList
(List<ClassB>
) to mixedList
(List<Object>
).
The service from which you obtained bList
might retain a reference to it; this service will assume its list contains only ClassB
instances. If you were allowed to assign that list to a List<Object>
reference, you could then add any type of object to the list without a warning. But when the service, thinking that every element in its list was a ClassB
, attempted to access the elements, a ClassCastException
would be raised.
Creating a new List<Object>
, and adding elements to it with add()
or addAll()
, prevents this "type pollution". You can safely modify this copy of the list, and let the source of the list keep its own copy "pure."
I don't believe it can be done.
Rant:
Java Generics imo are simply not worth the headache beyond simple collection use. I can live with casts. And as we all know, generics give the veneer of type safety but under the covers there is type monkey patching.
/Rant done:
This works but you will need to do reference swizzling for one of the respective block - here I'm opting for a List<?>
for mixedList
and swizzling for the case flagA
:
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;
}
}
It's hard to know what you are asking, especially the part about "not changing the code" (why ask a question then). Nevertheless, it seems you can give some bounding to Class for your list:
List<? extends Class<?>> mixedList = new ArrayList<Class<?>>();
List<Class<String>> bList = new ArrayList<Class<String>>();
bList.add(String.class);
mixedList = bList;
This code compiles (String used for easy compile check)
精彩评论