首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeLiteral在java中的使用

TypeLiteral在java中的使用
EN

Stack Overflow用户
提问于 2011-12-28 20:27:52
回答 5查看 17.8K关注 0票数 19

请提供一些如何在Google Guice或Java中使用TypeLiteral的基本信息,如果使用简单的代码来解释它将是非常有帮助的,提前谢谢

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-12-28 20:42:51

Guice中TypeLiteral的目的是允许您将类和实例绑定到泛型类型(通过指定类型参数),避免由于泛型在Java语言中没有具体化而产生的问题,即擦除在运行时隐藏了SomeInterface<String>SomeInterface<Integer>之间的差异。通过创建泛型类型的即席子类,TypeLiteral允许泛型参数的值保留擦除。

TypeLiteral的用法示例

代码语言:javascript
复制
bind(new TypeLiteral<SomeInterface<String>>(){})
    .to(SomeImplementation.class);

这会将SomeInterface<String>类型的参数绑定到SomeImplementation类。

对于一些背景信息,可以看看关于超类型标记的this blog post和关于类型文字的then this one

票数 21
EN

Stack Overflow用户

发布于 2011-12-29 03:31:10

就像Guice中的任何东西--模块化、可重用性和消除样板是所有实用程序的核心概念。

当然,您在Guice中所做的任何事情都可以在Java中模仿--代价是大量的样板文件,所以……真正的问题是:

如何使用TypeLiterals编写更多模块化/可重用的组件?

TypeLiterals在Guice中的强大之处在于,它允许您引用服务的实现,而无需定义该服务是什么。

让我们从一个程序中的一个简单的列表开始,在这个程序中,我们有许多类型的列表被不同地处理:

代码语言:javascript
复制
List<String> myStringList = new ArrayList<String>();

现在,我应该如何处理这些字符串呢?在运行时,没有办法“知道”它是一个字符串列表。所以,很多时候我可能会创建一个工厂,就像这样,为我获取处理对象:

代码语言:javascript
复制
ProcessorFactory.get(String.class).process(myStringList); 

因此,我可能会使用一个工厂(带有一堆if/else或case语句)来为不同的数据类型定义处理器。我的构造函数,对于使用这些处理器的对象,需要访问不同的处理器实现,可能如下所示:

代码语言:javascript
复制
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的任何静态依赖,类是直接注入的。因此,我可以很容易地定义一个使用复杂依赖项的类,而不必构建工厂感知的类构建器……因此,我的样板文件要少得多:

代码语言:javascript
复制
@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/

票数 4
EN

Stack Overflow用户

发布于 2011-12-28 20:42:05

对于泛型类型不能具有类文字这一事实,TypeLiteral类是一种解决方法。API doc of Binder (来自Google Guice,但同名的Java类具有完全相同的用途)给出了一个如何使用它的示例:

代码语言:javascript
复制
 bind(new TypeLiteral<PaymentService<CreditCard>>() {})
     .to(CreditCardPaymentService.class);

这指定了任何类型为PaymentService<CreditCard>的自动注入引用都将由具体的类CreditCardPaymentService实现,而PaymentService<Coupon>的选项则由不同的类实现。如果没有TypeLiteral,这是不可能的,因为Java编译器将接受PaymentService<CreditCard>.class,只接受PaymentService.class

注意,这也需要使用匿名子类(new TypeLiteral<PaymentService<CreditCard>>()之后的{} )来解决类型擦除问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8655921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档