Java generized class reference

2019-04-22 17:33发布

问题:

If you have a method with the signature:

Class<? extends List<String>> getObjectType()
{
        return ?????;
}

How do you return a proper generic version of the List class?

return List.class; //errors
return List<String>.class; //errors
return List.class<String>; //errors

what is the proper syntax to handle this?

回答1:

You need to explicitly cast it to the return type. This works:

return (Class<? extends List<String>>) List.class;

Yes it just looks wrong. This is just one of the many reasons Java's generics system is a mess.



回答2:

From the book "Effective Java" (Second Edition, page 137): "Do not use wildcard types as return types. Rather than providing additional flexibility for your users, it would force them to use wildcard types in their client code."

That said, to cast, you must first create a temporary variable:

@SuppressWarnings("unchecked")
Class<? extends List<String>> result = ....;
return result;

This works because you can have annotations on assignments. It doesn't work on return itself. You could also add that to the method but that would hide other problems as well.



回答3:

You have to return the class of something that extends List<String>. ArrayList<String> is one example. You can try:

ArrayList<String> myList = new ArrayList<String>();
...
return (Class<? extends List<String>>)myList.getClass();


回答4:

List.class and List<String>.class - in all this cases you need casting. Really you need a type, that has List<String> at runtime, somethig like this:

interface StringList extends List<String> {};

public Class<? extends List<String>> getObjectType() {
    return StringList.class;
}