tags:

views:

329

answers:

4

Is there any way to store the generic parameter type passed in at construction to a parameter. My goal:

class generic<T> {
    Class<T> type;
    public generic() {
        super();
        this.type = //Something that gets class from T
    }
}

What I'm currently doing is this:

class generic<T> {
    Class<T> type;
    public generic(Class<T> type) {
        super();
        this.type = type;
    }
}

It seems silly to have to specify the class twice, but I'm not sure of how else to do it. I think this might be possible with reflection, but I haven't investigated that yet. Is there a more straightforward way? If not (as an aside) why the information loss?

+2  A: 

I think you can't do it because of type erasure.

pgb
+3  A: 

Because Java generics are implemented with Type Erasure

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

bruno conde
+1  A: 

They type is not preserved at runtime, so you cannot take it as a parameter. Generics in java are strictly a compile-time concept (for backwards compatability reasons). This is called Type Erasure.

One of the reasons the class object takes a type parameter is precisely to work around this problem, so you can take the class object to represent the type programatically.

Yishai
+3  A: 

If you use a static creation method with type inference instead of the constructor, then the type does not need to be specified twice.

final class Generic<T> {
    private final Class<T> type;
    private Generic(Class<T> type) {
        super();
        if (type == null) {
            throw new NullPointerException();
        }
        this.type = type;
    }
    public static <T> Generic<T> newInstance(Class<T> clazz) {
        return new Generic<T>(clazz);
    }
}
...
    someFunction(Generic.newInstance(SomeType.class));

Of course, if you want to store the result in a variable, you are probably going to repeat the type anyway!

Tom Hawtin - tackline