简体   繁体   中英

Generics in java wildcards

List<Integer> ints = new ArrayList<Integer>();
 ints.add(1); ints.add(2);
 List<? extends Number> nums = ints;
 nums.add(3.14);   // compile-time error
assertints.toString().equals("[1, 2, 3.14]");

Why we are getting compile time error?

This is because of type erasure in java generics. You can't add new elements to listbecause its type parameter is undefined at compile time. The list List<? extends Number> nums List<? extends Number> nums means that you can't call add method on it.

List<? extends Number> List<? extends Number> means that we don't know what type is in the list, other than the fact that it is a Number .

In this case, it is a List<Integer> . Even when you assign it to a List<? extends Number> List<? extends Number> , it fundamentally remains a List<Integer> . And you can't add 3.14 to such a list.

If this were allowed, the following code would be valid:

List<Integer> ints = new ArrayList<Integer>();
ints.add(1); ints.add(2);
List<? extends Number> nums = ints;
nums.add(3.14);
Integer third = ints.get(2);

But ints.get(2) is not an integer, so it would throw an exception here. Better to catch these kinds of issues at compile time.

I think the important part here is the instantiation ( new ArrayList<Integer>() ), which clearly passes Integer to the List class. The left-hand side diamond notation doesn't really matter that much as long as it's compatible. Since you later on defined the generic as an upper boundary of Integer , mainly Number and its subtypes, Java is okay with that, because it still can deal with the Integers. The object essentially still is a List<Integer> .

This is like assigning a String to an Object. It will work because Object is a supertype of String . Here the List<? extends Number> List<? extends Number> is kind of like a supertype of List<Integer> . (I know the word "supertype" is incorrect here, so feel free to correct me.)

The instantiation with generics is sort of like an instantiation of the class itself and an object. Some other languages, eg Python are using the term "metaclasses" for this sort of behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM