Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java generics covariance

I am having trouble understanding the following article: http://www.ibm.com/developerworks/java/library/j-jtp01255.html

Under,

Generics are not covariant

the author states,

Because ln is a List, adding a Float to it seems perfectly legal. But if ln were aliased with li, then it would break the type-safety promise implicit in the definition of li -- that it is a list of integers, which is why generic types cannot be covariant.

I can't understand the part where it says "if ln were aliased with li". What does the author means by alias?(reference?). The code snippet above the quoted line seems to illustrate WHAT is illegal in java and not WHY. It would be very helpful to me if somebody could explain with an example. Thanks in advance.

like image 729
soocracy42 Avatar asked Apr 18 '10 02:04

soocracy42


2 Answers

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

In Java, Integer inherits from Number(java.lang.Number), so intuitively, anything that is an Integer(java.lang.Integer) is also a number, but what that article points out is that with generics it does not work that way, because considering that example, you could end up putting a float (which is a Number) into a List<Integer>, which is illegal because a float is not an integer.

Conclusion: Generics are not covariant.

Note: I recommend you read Effective Java (2nd Edition) Chapter 5: Generics.

like image 55
bakkal Avatar answered Nov 18 '22 12:11

bakkal


If you could do something like this:

List<Float> foo;
List<Object> bar;

foo = new ArrayList<Float>();
bar = foo;

foo.add(1.0f);
bar.add("Hello");

things would go VERY wrong. In this example bar is an alias for foo, and if you could do it you would lose the type safety that are the main reason that generics exist.

like image 11
TofuBeer Avatar answered Nov 18 '22 11:11

TofuBeer