I am trying to understand the behavior of lower as well as upper bound wild cards.
Got an issue while trying to compile the below code.
Collection<? extends Object> c = new ArrayList<Object>();
c.add(new Object()); // Compile time error
For figuring out the issue, I simply tried the lower bound wild card as well. Fortunately or unfortunately, code compiles fine but created so many confusion.
Collection<? super Object> c = new ArrayList<Object>();
c.add(new Object()); // Compiles fine
Can somebody explain me, how these two code snippets are working. It would be great if someone can provide additional examples/links.
Please correct me if I did something wrong above.
Thanks in advance.
?
means an "unknown type".
Collection<? extends Object>
represents a collection of some type of object. This "some type" can be any type that is a subclass of Object
or Object
itself. Which type exactly? The compiler does not know.
When you try to add a new Object
to the collection, you can't. This is because the collection's type is not known. It can be an ArrayList<String>
. It can be a HashSet<Integer>
. So the compiler says
"What if the collection is
ArrayList<String>
? You can't put anObject
in there!"
Basically, the compiler is too cautious to let you do that.
Collection<? super Object>
represents a collection of some type of object. This "some type" can be any type that is a superclass of Object
or Object
itself. It can only be one thing here - Object
, because Object
does not have a superclass. That's why you can add a new Object
to the collection.
Even if Object
has a superclass, you would still be able to add a new Object()
. Let's call the superclass of Object
MyClass
. Now, the collection can either be a collection of MyClass
or Object
. Whichever it is, you will be able to add an Object
to it.