views:

122

answers:

3

I'm trying to bind an interface to its implementation as read from a configuration file so that I can feed it to my IoC container. Here's roughly what I'm trying to do:

public class PropertyImplementationBinder<T> {
    // ...
    public Class getInterfaceClass() {
        return T.class; // OR Class<T>, note T is not newable
    }
    public Class getImplementationClass() {
        return /* read config file to get implementation class */;
    }
}

Is it somehow possible to get T.class?

+1  A: 

No it's not possible.

The only exception to Java's type erasure is that via reflection you can find out the parameterized type via reflection on a class's fields.

cletus
+4  A: 

You need to explicitly pass the class into the constructor (and store it yourself).

private final Class<T> clazz;

PropertyImplementationBinder(Class<T> clazz){
    this.clazz = clazz;
}

public Class<T> getInterfaceClass() {
    return clazz;
}
Thilo
I think that should have been obvious to me... but it wasn't. Thank you!
Kaleb Pederson
+3  A: 

You can get the actual type arguments for a generic superclass of a class. This blog post explores the possibilities presented by this, including a nice little trick using trivial anonymous inner classes. To quote directly:

It turns out that while the JVM will not track the actual type arguments for instances of a generic class, it does track the actual type arguments for subclasses of generic classes. In other words, while a new ArrayList<String>() is really just a new ArrayList() at runtime, if a class extends ArrayList<String>, then the JVM knows that String is the actual type argument for List's type parameter.

kloffy