Java 在GoogleGuice中,绑定到TypeLiteral是好的还是坏的做法
googleguice使用Java 在GoogleGuice中,绑定到TypeLiteral是好的还是坏的做法,java,dependency-injection,guice,Java,Dependency Injection,Guice,googleguice使用newtypeliteral(){}来克服我们不能使用C.class的事实 现在,以下情况很常见: bind(new TypeLiteral<C<T>>() {}).to(MyCSubclassTypedToT.class); bind(newtypeliteral(){}).to(MyCSubclassTypedToT.class); 然而,想象一个不同的场景。我们有一个想要注入的通用接口,我们的实现是由一个通用类提供的 Guice允许您这
newtypeliteral(){}
来克服我们不能使用C.class
的事实
现在,以下情况很常见:
bind(new TypeLiteral<C<T>>() {}).to(MyCSubclassTypedToT.class);
bind(newtypeliteral(){}).to(MyCSubclassTypedToT.class);
然而,想象一个不同的场景。我们有一个想要注入的通用接口,我们的实现是由一个通用类提供的
Guice允许您这样做:
bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
MyTypedClass extends MyGenericClass<T>
bind(MyGenericInterface<T>>() {}).to(MyTypedClass.class);
bind(new-TypeLiteral(){}).to(new-TypeLiteral(){});
另一种方法是像这样扩展MyGenericClass:
bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
MyTypedClass extends MyGenericClass<T>
bind(MyGenericInterface<T>>() {}).to(MyTypedClass.class);
MyTypedClass扩展了MyGenericClass
然后像这样绑起来:
bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
MyTypedClass extends MyGenericClass<T>
bind(MyGenericInterface<T>>() {}).to(MyTypedClass.class);
bind(MyGenericInterface>(){}).to(MyTypedClass.class);
如果MyGenericInterface被大量注入(尽管类型不同),并且每次注入时都使用MyGenericClass,则后一种方法会导致代码过于冗长。因此我倾向于使用前者
我非常希望听到其他人对在guice绑定的to子句中使用TypeLiteral的意见。我担心我可能会有点做空,因此看不到这种方法的缺陷。通常有两种情况:
MyGenericInterface
的所有实现绑定到MyGenericClass
MyGenericInterface
的实现bind(MyGenericInterface).to(MyGenericClass)代码>就足够了,简单易懂
对于第二个场景,您需要将特定类的实现绑定到特定的实现,TypeLiteral将发挥作用
此外,您问题中的代码不清楚T
是实际类还是泛型类型。如果是泛型类型
bind(new-TypeLiteral(){}).to(new-TypeLiteral(){})代码>
及
MyTypedClass扩展了MyGenericClass
不会编译,因为没有提供一些实际的类。在这种情况下,使用TypeLiteral
作为泛型实现会更好
让我这样说:“如果不使用Guice,子类MyTypedClass
是否存在?”。Guice的一个基本原则是:您不必修改实现类以适应DI框架(除了@Inject
注释)
对具体但泛型的类进行子类化有什么好处?一个巨大的损失是您必须在所有子类中复制MyGenericClass的构造函数。总而言之,它看起来像是没有多少收益的额外代码
总之,使用TypeLiteral
通常没有什么错。如果它在binding子句的.to(…)
部分(与bind(…)
相反),它甚至不会影响模块的绑定的公共可见部分,所以我认为没有什么好担心的。我不太理解泛型类如何提供非泛型接口的实现“适当键入时”。是否编译?能否显示一个示例?也许我简化了示例。我会更新它。@axtavt我希望问题现在更清楚。我有点困惑。对于第二个和第三个示例,您的意思是使用bind(new TypeLiteral(){}).
而不是bind(MyGenericInterface.class)…
?正如你在问题的顶部所说,做C.class
是没有意义的。那么,你的问题只是“我应该绑定到泛型类吗?还是应该绑定到非泛型类型的类?”@andrewmcname你是对的,我犯了一个错误。我的问题正如你所猜测的那样”我应该绑定到泛型类吗?与我应该绑定到非泛型类型的类相比?问题更多的是关于良好实践。您的示例处理bind()参数是泛型的情况。我的问题更多的是关于to()参数是泛型的情况。