问题
I'm trying to inject instances with generics and i'm getting the following error:
HasOne<ModelClass> cannot be used as a key; It is not fully specified.
I've read elsewhere that safest way to do this is to explicitly name the class to be used in the generic when using the injector to get an instance but i'd like to be a little cleaner. I'm trying to create Relationship
objects between Models
.
Here is my simplified Model
class
public class Model {
@Inject
Injector injector;
public <ModelClass extends Model> HasOne<ModelClass> hasOne(Class<ModelClass> clazz) {
HasOne<ModelClass> hasOne = injector.getInstance(Key.get(new TypeLiteral<HasOne<ModelClass>>() {
}));
hasOne.init(clazz);
return hasOne;
}
}
My HasOne
relationship
public class HasOne<T extends Model> {
Class clazz;
public void init(Class<T> clazz){
this.clazz = clazz;
}
@Inject
Injector injector;
public T get(){
return (T) injector.getInstance(clazz);
}
}
Test Model
#1
public class TestModel extends Model {
public HasOne<ExampleModel> exampleModel(){
return hasOne(ExampleModel.class);
}
}
Test Model
#2
public class ExampleModel extends Model {
}
I get the error when doing this
TestModel testModel = RoboGuice.getInjector(context).getInstance(TestModel.class);
HasOne<ExampleModel> relationship = testModel.exampleModel();
I'm trying to hide away the ugly relationship creation and keep it in the Model
class
回答1:
You cannot use new TypeLiteral<T>() { }
if T
is a type parameter, it has to be a fully-specified type. Luckily, since you have an instance of Class<ModelClass>
, you can do this:
(Key<HasOne<ModelClass>>) Key.get(TypeLiteral.get(Types.newParameterizedType(HasOne.class, clazz)))
You'll get a warning on the cast but it is safe to suppress it.
来源:https://stackoverflow.com/questions/17617005/injecting-generics-with-roboguice