Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics and parameterized types in Java

Tags:

java

The below code causes a compile time error :

The method add(capture#1-of ? extends Object) in the type List is not applicable for the arguments (String)

code :

List<? extends Object> a1 = new ArrayList();
a1.add("string");

Error is at line :

a1.add("string");

Since class String extends from Object why ref a1 not accept a String type ?

like image 428
blue-sky Avatar asked Jan 13 '23 13:01

blue-sky


1 Answers

I recommend reading this article, http://java.dzone.com/articles/covariance-and-contravariance. (Italic additions are mine)

In summary, we use covariance <? extends Object> when we only intend to take generic values out of a structure. We use contravariance <? super Object> when we only intend to put generic values into a structure and we use an invariant <Object> when we intend to do both.

You defined your list as holding a covariant Object type, which means you can write Object o = a1.get(1) but you can't write a1.add("foo"). If you want to be able to add Objects but not get them back, then you would need to define your list like this:

List<? super Object> a1 = new ArrayList<>();

It's a bit unfortunate, in my opinion, language authors used the terms extend and super to indicate covariance and contravariance, especially in the above example since there is no super type of Object.

like image 198
bdkosher Avatar answered Feb 01 '23 14:02

bdkosher