Java 在GoogleGuice中,绑定到TypeLiteral是好的还是坏的做法

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允许您这

googleguice使用
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()参数是泛型的情况。