简体   繁体   中英

Why we cant add the elements in java generics using extends bounds?

I understand we can't add the element on the list which is the type of the extends bounds. But I am still not sure why the java compiler doesn't allow this. since the compiler can easily check that whether the adding new element is the subtype of the Generic type. Can anyone please help me on this?

This case is called Covariance, the extends keyword allows you to read elements from a Collection , but not to add them. This is because the compiler treats the add operation as unsafe. For instance, you could declare any of the following lists:

List<? extends Number> myNums = new ArrayList<Integer>(); 
List<? extends Number> myNums = new ArrayList<Float>(); 
List<? extends Number> myNums = new ArrayList<Double>();

You would be able to read from them without problems, because whatever the list contains, can be upcasted to Number . However, you are not allowed to put anything into any of them:

myNums.add(45L); //compiler error

This is due to the compiler not being able to determine the actual type of the of the generic list (could be of Integer , of Float or of Double in our example). This is therefore an unsafe operation, you could be adding a Long to an Integer list, so the compiler doesn´t allow you.

Read this article for a deeper explanation.

I'll use a modification of an example from here :

List<String> ls = new ArrayList<String>();
List<? extends Object> l = ls;
l.add(l, new Object()); // not legal - but assume it was!
String s = ls.get(0); // ClassCastException - ls contains
                      // Objects, not Strings.

You pointed very correctly that "the compiler can easily check that whether the adding new element is the subtype of the Generic type". But even so, since the compiler can not determine the type of the list l , accepting l.add(l, new Object()) will cause a corruption of list ls .

Thus the compiler is doing its job, it catches errors earlier than a run-time checking does.

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