TypeLiteral injection with reflection

Context: java using guice (latest version)

Greetings, is it possible to introduce some TypeLiteral in this way using Guice:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) { //how to Inject MyClass with type a & b ? //eg : 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); ... 

What is the best way to deal with this problem (with Guice)?

Thanks!

+6
source share
2 answers

Create a ParameterizeType parameter for your type:

 // It 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); 

Create TypeLiteral from it:

 TypeLiteral typeLiteral = TypeLiteral.get(type); 

Now create the entered instance:

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

In practice, you yourself will want to implement ParameteriedType:

  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: In fact, you can use:

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

see Guice module with type parameters

+3
source

In fact, I think this is impossible. Generics are not confirmed at runtime. This means that information is missing at runtime. So no matter what general type you give it to him.

So, I think this method is not needed. Just something like this:

 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(); } 

Since MyClass is an interface, what you want to achieve is completely useless and impossible. How do you want to instantiate an object with specific behavior when you specify only the type of the parameter and the type of the return value.
I think you should try to find a different way of working.

0
source

Source: https://habr.com/ru/post/899353/


All Articles