63

is there a way in java to get an instance of something like Class<List<Object>> ?

0

7 Answers 7

79

how about

(Class<List<Object>>)(Class<?>)List.class
Sign up to request clarification or add additional context in comments.

7 Comments

I like that idea. It causes unchecked cast warning, but it can be easily ignored I guess. Thanks for sharing!
This is brilliant. Exaclty what I needed to solve a difficult generics problem today.
Is (Class<?>) really needed ? In my tests it seems like (Class<List<Object>>)List.class is enough.
@MonkeySupersonic: If you get "The type List is not generic", you have the wrong "List" type (probably the class java.awt.List instead of the interface java.util.List). Check your imports.
This question was asked in 2009 and I still see no proper solution even today in 2022... shame on Java!
|
36
public final class ClassUtil {
    @SuppressWarnings("unchecked")
    public static <T> Class<T> castClass(Class<?> aClass) {
        return (Class<T>)aClass;
    }
}

Now you call:

Class<List<Object>> clazz = ClassUtil.<List<Object>>castClass(List.class);

3 Comments

Not a bad idea. This is basically the same as doing (Class<List<Object>>)(Class<?>)List.class but if you need several class objects, you will only have one unchecked cast inside the ClassUtil.
I like it, because you do not create new objects. Cool. Thanks.
To provide some type safety, you could require the parameter to be super of T. public static <T> Class<T> castClass(Class<? super T> aClass)
10

Because of type erasure, at the Class level, all List interfaces are the same. They are only different at compile time. So you can have Class<List> as a type, where List.class is of that type, but you can't get more specific than that because they aren't seperate classes, just type declarations that are erased by the compiler into explicit casts.

Comments

6

As mentioned in other answers, Class represents an erased type. To represent something like ArrayList<Object>, you want a Type. An easy way of getting that is:

new ArrayList<Object>() {}.getClass().getGenericSuperclass()

The generic type APIs introduced in 1.5 are relatively easy to find your way around.

5 Comments

bizarre... no way to do this w/o creating an object?
Not only creating a new object, a new class (in this case an anonymous inner class). But that example should be new ArrayList, no? Making an anonymous list would require you to implement all the methods.
Yishai: Erm yes. And it's getGenericSuperclass not getGenericSupertype. And then there's the issue of implementing multiple interfaces.
Jason S: One object who cares? There's ways of doing it without the new, but you are using plenty of memory for code.
But you still have to do an unchecked conversion here
2

You could use Jackson's ObjectMapper

ObjectMapper objectMapper = new ObjectMapper();
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, ElementClass.class)

No unchecked warnings, no empty List instances floating around.

Comments

0

You can get a class object for the List type using:

Class.forName("java.util.List")

or

List.class

But because java generics are implemented using erasures you cannot get a specialised object for each specific class.

Comments

0
List.class

the specific type of generics is "erased" at compile time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.