Why does this use of Java Generics not compile?

You can't insert into collections that use wildcard types . This is because, while a List In your case, one might expect the compiler to know better as the definition of the collection is so visible, but it doesn't.

Up vote 3 down vote favorite share g+ share fb share tw.

For the life of me I cannot understand why the compiler won't let me do the following... import java.util. HashMap; import java.util. Map; public class TestMap { private final Map map = new HashMap(); public void put(Integer key, Long item) { this.map.

Put(key, item); } } Why does line this.map. Put(key, item) cause a compile error? I know that I can change the declaration of map to use Number rather than?

Extends Number to make it work but it seems to me that what I am doing is perfectly legal, and I would prefer to not allow Number objects in the map. I am using Java 1.6.0_13. Java generics link|improve this question edited Nov 24 '09 at 15:18unwind77.6k698186 asked Nov 24 '09 at 15:11John in MD5572920 94% accept rate.

Extends Number will allow Number objects. The? Extends X bounded wildcard means "X or a subclass of X".

– Pesto Nov 24 '09 at 15:21 Incidentally, Number is a so even if inserting into a wildcard list was possible, it wouldn't achieve what you want. The fact that Number is abstract will. – Andrew Duffy Nov 24 '09 at 15:22 You could do ((Map) map).

Put(key, item); if yu are sure about the type. – Tim Büthe Nov 24 '09 at 15:26 Thanks for pointing out that Number objects would be allowed in the map. It appears that I need to remove the wildcard and just use Number.

– John in MD Nov 24 '09 at 15:40.

You can't insert into collections that use wildcard types. This is because, while a List can be passed to a method that accepts List, it isn't safe to insert a Long into it. In your case, one might expect the compiler to know better as the definition of the collection is so visible, but it doesn't.

Explained here: java.sun.com/docs/books/tutorial/extra/g... – Pesto Nov 24 '09 at 15:22 1 The compiler can't allow it because it can't take responsibility for where that map ends up being passed or used. Sure as a human we can eyeball the program and say it isn't used in any way that matters, but the compiler can only look at the put against the type declaration. – Yishai Nov 24 '09 at 15:24 1 You can insert into collecitons that use wildcard types.

You just have to do it correctly. The PECS rule: Producer Extends Consumer Super, which means if you are getting from the collection, then use , if you are putting objects into it, then use . If you have List, you can insert a Long into it.

It allows you the flexibility to pass in List or List, etc. – Chris Lacasse Nov 24 '09 at 16:04 @Chris Lacasse A great example of why Java has deviated from its roots of being easy to understand! – John Topley Nov 24 '09 at 16:22 Joshua Bloch, who led the JSR that introduced generics, had stated that wildcards were a mistake: artima.com/weblogs/viewpost.jsp?thread=222021 – Andrew Duffy Nov 24 '09 at 16:34.

This is related to generics covariance. When you declare, Map map you can't insert anything to the map because you can't guarantee that? Extends Number is a Long, for instance.

Imagine this situation: Map map = new HashMap(); public void put(Integer key, Long item) { this.map. Put(key, item); } Here, Integer! = Long and yet both obey?

Extends Number.

Supplying the wildcard to a generic type effectively makes it read-only.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions