I'd like to know how to represent a generic version of the following binding that won't fail with xxx cannot be used as a key it is not fully specified
install(new FactoryModuleBuilder().
implement(new TypeLiteral<SomeClass<T,?>>(){},
new TypeLiteral<SomeOtherClass<T, U>>(){}).
build(SomeFactory.class);
It seems that the implement
method isn't available with a parameterized type parameter.
This is not possible because of the way Guice uses type literal parameters. TypeLiterals require concrete types and, as you see from the exception, cannot accept generic parameters.
To quote @jesse-wilson
Note that Guice doesn't allow bindings for types that aren't fully-qualified. For example, you can bind a
Map<String, Integer>
but you can't bind aMap<K, V>
. https://stackoverflow.com/a/1117878/654187
You can "fully qualify" these bindings as described here: https://stackoverflow.com/a/1120990/654187
But I doubt this is what you want.
The good news is you can still write this factory without assisted injection easily:
public class SomeFactory{
@Inject
private SomeDependency someDependency;
public <T> SomeClass<T, ?> buildSomeClass(T t){
return new SomeOtherClass<T, Object>(t, someDependency);
}
}
Alen Vrečko posted :
Imho the best you can do with generics is something like
install(new Assist2<Payment, RealPayment>(PaymentFactory.class){});
or
install(new Assist3<SomeClass<Foo, Bar>, SomeOtherClass<Foo, Bar>, SomeFactory<Foo>(){});
Should be pretty easy to implement this approach. Just look in the source of TypeLiteral.
If you absolutely need type parameters something like:
install(new CustomAssist<Baz>(){});
where
CustomAssist<T> extends Assist<SomeClass<Foo,T>,SomeOtherClass<Foo,Bar>{...
might be possible but not trivial to implement. But a lot of fun.
To follow on from @johncarl
If you are just injecting someDependency then you'll be getting the instance when the factory is created. To make it work like a FactoryModuleBuilder constructed factory you'll need to inject the Injector
public class SomeFactory{
@Inject
private Injector injector;
public <T> SomeClass<T, ?> buildSomeClass(T t) {
return new SomeOtherClass<T, Object>(t, injector.getInstance(SomeDependency));
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.