Nelson Tatius
Nelson Tatius

Reputation: 8043

Generic type checking at compile time

Let's see some Set<E>'s methods declarations.

public boolean add(E e);
public E get(int index);

And let's try to use this.

List<Boolean> list = new ArrayList<Boolean>();
Integer i = list.get(0);              //Predictably, here we get a compile error.
list.contains(new Integer(3));        //But this line is allowed. Why?

Even in non-generic equivalent of this code (as I know, it'll simply transformed into it), we get compile errors in both lines.

List s = new ArrayList();
s.contains((Boolean)(new Integer(3)));
Integer i = (Boolean)s.get(3);

So why do not I get the error in the generic case?

Upvotes: 0

Views: 1178

Answers (4)

Alex Stybaev
Alex Stybaev

Reputation: 4693

From List interface API:

E get(int index)

So it returns the object of generic type. While contains gets Object as a param:

boolean contains(Object o) 

so it's all about methods signatures. See more on List

Upvotes: 1

Shivan Dragon
Shivan Dragon

Reputation: 15219

Well, this line:

s.contains((Boolean)(new Integer(3)));

has compile time error simply because you can't cast what's clearly an Integer instance to Boolean. It has nothing to do with List's generics.

Then, the contains(Object o) is not generically typed (inside java.util.Collection), that's why you don't get a compile time warning. This has to do with covariance and contra-variance.

Upvotes: 1

Pavel Veller
Pavel Veller

Reputation: 6115

contains is not generified. Its signature remains:

boolean contains(Object o)

http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#contains(java.lang.Object)

here's some more: http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html

Upvotes: 5

Rob I
Rob I

Reputation: 5737

See the answer to this question.

basically the contains(), remove(), etc methods only care that the objects being compared against and removed are equal, not that they have the same type.

Upvotes: 3

Related Questions