2011-10-15 9 views
6

Kontekst: Java korzystania Guice (ostatnia wersja)TypeLiteral zastrzyk z refleksji

Witam wszystkich, jest to możliwe, aby wprowadzić pewne TypeLiteral z Guice w ten sposób:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    //how to Inject MyClass with type a & b ? 
    //e.g : injector.getInstance(MyClass<"a class","b class">) 
} 

public interface MyClass<S,T> 
{ 
    public T do(S s); 
} 

public class ClassOne implements MyClass<String,Integer> 
{ 
    public Integer do(String s) 
    { 
      //do something 
    } 
} 

Module : 
bind.(new TypeLiteral<MyClass<String,Integer>(){}).to(ClassOne.class); 
bind.(new TypeLiteral<MyClass<String,Double>(){}).to(ClassTwo.class); 
... 

Jaki jest najlepszy sposób na poradzenie sobie z tym problemem (z Guice)?

Dziękujemy!

+1

duplikat ysdx

Odpowiedz

3

Tworzenie ParameterizeType dla danego typu:

// It's supposed to be internal. 
// You could use sun.reflect.generics.reflectiveObjects but it is not portable. 
// Or you can implement it yourself (see below) 
ParameterizedType type = new com.google.inject.internal.MoreTypes.ParameterizedTypeImpl(null, MyClass.class, a, b); 

Utwórz TypeLiteral od niego:

TypeLiteral typeLiteral = TypeLiteral.get(type); 

teraz tworzyć wstrzykuje instancję:

return (MyClass<A,B>) injector.getInstance(Key.get(typeLiteral)) 

W praktyce chcesz wdrożyć ParameteriedType sam:

final Type[] types = {a, b}; 
ParameterizedType type = ParameterizedType() { 
    @Override 
    public Type[] getActualTypeArguments() { 
    return types; 
    } 

    @Override 
    public Type getOwnerType() { 
    return null; 
    } 

    @Override 
    public Type getRawType() { 
    return MyClass.class; 
    }; 
} 

EDIT: Faktycznie, można użyć:

Types.newParameterizedType(MyClass.class,a,b) 

zobaczyć Guice module with type parameters

+0

Wielki człowiek pracy, to działa! Dziękuję Ci ! – overflow

0

W rzeczywistości myślę, że to niemożliwe. Generics nie są reifikowane w czasie wykonywania. Oznacza to, że informacje nie są obecne w czasie wykonywania. Więc nie obchodzi go, jaki typ rodzajowy mu dajesz.

Uważam, że ta metoda nie jest potrzebna. Wystarczy coś takiego:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    return new MyClass(); 
    // Or maybe something like this, if you use custom constructors 
    // return injector.getInstance(); 
} 

Od MyClass jest interfejsem, co chcesz osiągnąć jest całkowicie bezużyteczny i niemożliwe. W jaki sposób utworzyć instancję z określonym zachowaniem, gdy określa się tylko typ parametru i typ zwracany.
Myślę, że powinieneś spróbować znaleźć inny sposób pracy.

+0

Dodałem więcej szczegółów do mojego pytania, dziękuję – overflow