This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Java in General and the fly likes Help with Java Generics... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Help with Java Generics..." Watch "Help with Java Generics..." New topic
Author

Help with Java Generics...

Landon Blake
Ranch Hand

Joined: Oct 15, 2004
Posts: 43
I was hoping you guys might be able to give me a little help with Java
Generics. I'm trying to track down a null pointer exception in my
pluggable rendering code, and I think it may result from improper use
of Generics.

In one of my classes I store a HashMap. The keys for this
HashMap are Strings. The values stored in the HashMap
are the references to any class which implements an interface. (I'll call the interface SomeInterface for this example.) I want the HashMap to be able to store any implementation of the SomeInterface.

Here is my attempt at defining the HashMap using Java Generics:



Eclipse is giving me an error on this statement. It says that it
"Can't instantiate the type HashMap<String,? extends
SomeInterface>".

I'm guessing this is becuase I'm trying to use an interface and not a
class as the upper bound of my wild card in the generics declaration.
Is there a way around this, other than defining a default
class that must be extended by all other
implementations of SomeInterface.

I'm really surprised that you can't use interfaces in this type of
statement. Unless of course, I've got another mistake staring me in
the face.

Thanks in advance for the help.

Landon
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
try:



Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
The wildcard in
private HashMap<String, ? extends SomeInterface> indicates a parameterized HashMap where the second parameter is some specific implementation (or subclass if SomeInterface were a concrete class) of SomeInterface. For instance if you have an implementing class:


and a method signature:



then a HashMap<String, SomeClass> would qualify as a parameter to this method. However you wouldn't be ablt to add anything to the map because the specific type of the class that implements SomeInterface isn't known at compile time.

Also since parametrized types arent covariant, a HashMap<String, SomeClass> could not be passed to a method that expected a HashMap<String, SomeInterface>.

I'm not sure if that was helpful or more confusing...
Landon Blake
Ranch Hand

Joined: Oct 15, 2004
Posts: 43
Thanks for the responses Garett.

Another Java programmer suggested that I try this:

private HashMap<String, ? extends SomeInterface> myHashMap = new HashMap<String, SomeInterface>();

This made the error disappear in Eclipse, although I don't know if the code will work properly when compiled. I'll let you find out.

What I'm trying to do is have a HashMap that can store any class implementing SomeInterface.I also need to be able to add instances of classes implementing SomeInterface to. I think I can accomplish this with the above definition of the HashMap and a genric method that adds elements to the HashMap. I'll report back on how this works.

Thanks again for the help.

Landon
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Then what you really want is a HashMap<String, SomeInterface>, the wildcards serve no purpose here.
Landon Blake
Ranch Hand

Joined: Oct 15, 2004
Posts: 43
Garrett,

I can see now that you were correct. I didn't need to use wildcards because I was dealing with an interface.

I think i'd need to use the wildcard if I wanted to allow subclasses of a class, instead of implementations of an interface.

Thanks,

Landon
[ May 17, 2007: Message edited by: Landon Blake ]
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
I think i'd need to use the wildcard if I wanted to allow subclasses of a class, instead of implementations of an interface.


No, a reference of type HashMap<String, Object> will compile without warning and allow you to store any type of Object as a value in the map. For the most part, I usually see wildcards in method parameters. Since generic types aren't covariant you cant do this:

ArrayList<Object> objectList = new ArrayList<String>();//NOT ALLOWED

An ArrayList<String> is not a subtype of ArrayList<Object>. Therefore, an ArrayList<String> is not a valid argument for a method who's signature is:

But in most cases what is really meant by that line of code is "This method will accept a parameterized ArrayList of any type and we will treat the elements of that ArrayList as Objects". With generics in Java one way to express that is:



[ May 17, 2007: Message edited by: Garrett Rowe ]

[ May 17, 2007: Message edited by: Garrett Rowe ]
[ May 17, 2007: Message edited by: Garrett Rowe ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Help with Java Generics...
 
Similar Threads
Generics
Generics
Generics
generics
Generics using interfaces