请提供一些如何在Google Guice或Java中使用TypeLiteral的基本信息,如果使用简单的代码来解释它将是非常有帮助的,提前谢谢
发布于 2011-12-28 20:42:51
Guice中TypeLiteral的目的是允许您将类和实例绑定到泛型类型(通过指定类型参数),避免由于泛型在Java语言中没有具体化而产生的问题,即擦除在运行时隐藏了SomeInterface<String>和SomeInterface<Integer>之间的差异。通过创建泛型类型的即席子类,TypeLiteral允许泛型参数的值保留擦除。
TypeLiteral的用法示例
bind(new TypeLiteral<SomeInterface<String>>(){})
.to(SomeImplementation.class);这会将SomeInterface<String>类型的参数绑定到SomeImplementation类。
对于一些背景信息,可以看看关于超类型标记的this blog post和关于类型文字的then this one。
发布于 2011-12-29 03:31:10
就像Guice中的任何东西--模块化、可重用性和消除样板是所有实用程序的核心概念。
当然,您在Guice中所做的任何事情都可以在Java中模仿--代价是大量的样板文件,所以……真正的问题是:
如何使用TypeLiterals编写更多模块化/可重用的组件?
TypeLiterals在Guice中的强大之处在于,它允许您引用服务的实现,而无需定义该服务是什么。
让我们从一个程序中的一个简单的列表开始,在这个程序中,我们有许多类型的列表被不同地处理:
List<String> myStringList = new ArrayList<String>();现在,我应该如何处理这些字符串呢?在运行时,没有办法“知道”它是一个字符串列表。所以,很多时候我可能会创建一个工厂,就像这样,为我获取处理对象:
ProcessorFactory.get(String.class).process(myStringList); 因此,我可能会使用一个工厂(带有一堆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(...)); 到目前为止一切都很好。直到我们意识到有更好的方法:
在Guice的世界中,我可以忘记编写这个工厂-相反,我可以显式地将类绑定到处理器。这样做的好处是没有静态依赖--需要使用处理器实现的类不需要对工厂-rather的任何静态依赖,类是直接注入的。因此,我可以很容易地定义一个使用复杂依赖项的类,而不必构建工厂感知的类构建器……因此,我的样板文件要少得多:
@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. 这方面有一个很好的教程,包含接口实现和绑定示例,这里是:http://thejavablog.wordpress.com/2008/11/17/how-to-inject-a-generic-interface-using-guice/
发布于 2011-12-28 20:42:05
对于泛型类型不能具有类文字这一事实,TypeLiteral类是一种解决方法。API doc of Binder (来自Google Guice,但同名的Java类具有完全相同的用途)给出了一个如何使用它的示例:
bind(new TypeLiteral<PaymentService<CreditCard>>() {})
.to(CreditCardPaymentService.class);这指定了任何类型为PaymentService<CreditCard>的自动注入引用都将由具体的类CreditCardPaymentService实现,而PaymentService<Coupon>的选项则由不同的类实现。如果没有TypeLiteral,这是不可能的,因为Java编译器将接受PaymentService<CreditCard>.class,只接受PaymentService.class。
注意,这也需要使用匿名子类(new TypeLiteral<PaymentService<CreditCard>>()之后的{} )来解决类型擦除问题。
https://stackoverflow.com/questions/8655921
复制相似问题