pagetop
Javablog
by Java coders, for Java codersRSS

Class as a generic type

April 27th, 2007 by

I just learnt something great about generics and thought I’d share it.

We have several systems that take care of persistence and caching, which usually involve getting hold of a store through a factory method something like this

public static <K extends Serializable, V extends Serializable> Store<K, V>
    getInstance(String name, Class keyClass, Class valueClass)

Up until now, I was very frustrated that there was no way to check that the Class parameters are actually related to the generic types K and V, and I had to explicitly check they extended Serializable.

But it turns out that the Class object itself can have a generic type K forced upon it. For example Class<List> will only accept the class of an object that implements List. The method then becomes

public static <K extends Serializable, V extends Serializable> Store<K, V>
    getInstance(String name, Class<K> keyClass, Class<V> valueClass)

and suddenly things become a lot cleaner… specifically there is no need to check that the Classes are subclasses of Serializable or that generic objects can be cast to one of the Class parameters in every set method. That said, it would be much better to be able to lose the Class parameters altogether and allow runtime access of generic types, but unfortunately Java’s legacy fails us there.

Oh, and while I have you in generic mode, isn’t the “Type mismatch” error here just the most annoying thing ever?

List<Object> stooges = Arrays.asList("Larry", "Moe", "Curly");
We all know it is perfectly fine to go and do this
List<Object> stooges = new ArrayList();
stooges.add("Larry");
stooges.add("Moe");
stooges.add("Curly");
A correction is to do
List<? extends Object> stooges = Arrays.asList("Larry", "Moe", "Curly");
but having to explicitly say the type extends is just annoying. Does anyone know of a valid case where it would be bad to allow a sub-type to be assigned in place of a type?


This entry was posted by by on Friday, April 27th, 2007 at 6:22 pm, and is filed under Factories, Generics, Java. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.



6 comments on “Class as a generic type”
List<Object> stooges = Arrays.<Object>asList("Larry", "Moe", "Curly");

Set your IDE to show use of a ‘raw type’ as a warning/error.

“Does anyone know of a valid case where it would be bad to allow a sub-type to be assigned in place of a type?”

List<Number> numbers=new ArrayList<Double>(); //not allowed, but imagine
List<Double> doubles=numbers;
numbers.add(5);
double d=doubles.get(0); //ClassCastException, we don't want this.

The case you are looking for is (almost) exactly the one you have shown.

List<String> strList = new ArrayList<String>() // Valid
List<Object> objList = strList; // NOT valid 
objList.add("Bob"); // This would be safe
objList.add(Boolean.TRUE); // This is OK for a string list,
                           // but not for an object list

That last line if the reason why the 2nd line is not allowed. And that’s the same reason why your examples aren’t allowed.

Thanks Tim and Ricky, I think that covers the bad use example just fine. :-)

I had forgotten that extends in generic types would mean that List<? extends Object>.add() can’t take String parameters anymore, so in fact Ricky’s correction (setting the generic type of Arrays.asList) is a much better solution. (Tim, I think you meant to say List<String> can’t take the Boolean.TRUE, not List<Object>)

Yes, you are correct, I got my comment backwards.

Regarding Class and its generic type, I find it most helpful to think of Class<T> as a factory for instances of T (via newInstance() or even getConstructor()).

links for 2007-05-03 | Urubatan`s Weblog wrote:

[…] Javablog » Class as a generic type Popularity: 1% […]

Leave a comment

Markdown is supported.

To include code snippets in your comment, use

<pre><code># lang java
... code here ...
</code></pre>

or use 4 spaces at the start of the line instead of using code and pre tags.

Comment feed: RSS