TypeLiteral在java中的使用
请提供一些关于如何在Google Guice或Java EE中使用的基本信息,如果使用简单的代码来解释,这将非常有帮助,提前感谢TypeLiteral在java中的使用,java,jakarta-ee,guice,Java,Jakarta Ee,Guice,请提供一些关于如何在Google Guice或Java EE中使用的基本信息,如果使用简单的代码来解释,这将非常有帮助,提前感谢TypeLiteral类是一个解决办法,因为您不能将类文本用于泛型类型。(这来自Google Guice,但同名的Java EE类具有完全相同的用途)给出了一个如何使用它的示例: bind(new TypeLiteral<PaymentService<CreditCard>>() {}) .to(CreditCardPaymentSe
TypeLiteral
类是一个解决办法,因为您不能将类文本用于泛型类型。(这来自Google Guice,但同名的Java EE类具有完全相同的用途)给出了一个如何使用它的示例:
bind(new TypeLiteral<PaymentService<CreditCard>>() {})
.to(CreditCardPaymentService.class);
bind(新的TypeLiteral(){})
.to(CreditCardPaymentService.class);
这指定类型为PaymentService
的任何自动注入引用将由具体类CreditCardPaymentService
实现,而PaymentService
的选项将由其他类实现。如果没有TypeLiteral
,这是不可能的,因为Java编译器将只接受PaymentService.class
,而只接受PaymentService.class
请注意,这还需要使用匿名子类(new-TypeLiteral()
)之后的{}
),以解决类型擦除问题。in-Guice的目的是允许您将类和实例绑定到泛型类型(指定类型参数)避免泛型在Java中没有具体化这一事实所导致的问题,即擦除隐藏了运行时SomeInterface
和SomeInterface
之间的差异TypeLiteral
通过创建泛型类型的特殊子类,允许泛型参数的值在擦除后仍然有效
TypeLiteral
的示例用法:
bind(new TypeLiteral<SomeInterface<String>>(){})
.to(SomeImplementation.class);
bind(新的TypeLiteral(){})
.to(SomeImplementation.class);
这将SomeInterface
类型的参数绑定到SomeImplementation
类
有关一些背景信息,请查看超级类型标记和类型文本。这是一种在java中绕过泛型擦除的方法。当您想要将一些实现绑定到参数化(通用)接口时,您需要它。在Guice文档中找到一些用法:
bind(new TypeLiteral<PaymentService<CreditCard>>() {})
.to(CreditCardPaymentService.class);
bind(新的TypeLiteral(){})
.to(CreditCardPaymentService.class);
这种公认的奇怪构造是绑定参数化类型的方法。它告诉Guice如何满足PaymentService类型元素的注入请求。CreditCardPaymentService类必须实现PaymentService接口。Guice当前无法绑定或注入泛型类型,例如Set;所有类型参数都必须完全指定。与Guice中的任何东西一样-模块化、可重用性和删除样板文件是所有实用程序的核心概念。 当然,您在Guice中所做的任何事情都可以在Java中进行模仿-代价是大量的样板文件,所以。。。真正的问题是: 我们如何使用typeliteral来编写更多的模块化/可重用组件? Guice中TypeLiterals的强大之处在于,它允许您引用服务的实现,而无需定义该服务是什么 让我们从程序中的一个简单列表开始,其中我们有许多不同处理的列表类型:
List<String> myStringList = new ArrayList<String>();
因此,我可以使用工厂(带有一组if/else或case语句)为不同的数据类型定义处理器。对于使用这些处理器并需要访问各种处理器实现的对象,我的构造函数可能如下所示:
public MyClass(Processor<String> strProcessor, Processor<Integer> intProcessor)P
{
//Simple enough, but alot of boiler plate is required to launch this constructor.
}
//and to invoke
new MyClass(PRocessorFactory.get(....), ProcessorFactory.get(...));
publicMyClass(处理器strProcessor,处理器intProcessor)P
{
//很简单,但是启动这个构造器需要很多锅炉板。
}
//以及调用
新的MyClass(PRocessorFactory.get(…),PRocessorFactory.get(…);
到目前为止一切都很好。。。直到我们意识到有更好的方法:
在Guice世界中,我可以忘记编写这个工厂——相反,我可以显式地将类绑定到处理器。这样做的好处是不存在静态依赖关系—需要使用处理器实现的类不需要工厂上的任何静态依赖关系—而是直接注入类。因此,我可以轻松定义一个使用复杂依赖项的类,而无需构建工厂感知的类生成器。。。因此,我的样板文件要少得多:
@Inject
public MyClass(Processor<String> implStr, Processor<Integer> implInt)
{
//Now , this method will work magically, because Guice is capable of
//Using the loaded modules, which define bindings between generics and their implementations
}
//Elsewhere I simply define a single guice module that does the binding, and make sure to load it before my application launches.
@Inject
公共MyClass(处理器implStr、处理器implInt)
{
//现在,这个方法将神奇地工作,因为Guice能够
//使用加载的模块,这些模块定义泛型及其实现之间的绑定
}
//在其他地方,我只需定义一个进行绑定的guice模块,并确保在应用程序启动之前加载它。
这里有一个很好的关于接口实现和绑定示例的教程:TypeLiteral是Google的Guice框架的一部分,而不是Java标准API。我编辑了你的问题以反映这一点。@MichaelBorgwardt看。@Howard:啊,我没有想到直接检查Java EE库,Guice类是Google上的第一个热门。有趣的是,这两个类有着完全相同的用途。如何从注入器中获取用于上述绑定的实例或绑定?我不想使用@inject
@Inject
public MyClass(Processor<String> implStr, Processor<Integer> implInt)
{
//Now , this method will work magically, because Guice is capable of
//Using the loaded modules, which define bindings between generics and their implementations
}
//Elsewhere I simply define a single guice module that does the binding, and make sure to load it before my application launches.