Google Guice +仿制药:窗帘背后是否有一些魔力?

时间:2011-11-25 19:28:51

标签: java generics guice

在我看来,Guice实现在处理泛型时做了一些非常棘手的事情。看起来它在运行时知道关于在编译时使用的泛型类型。让我们看一个简单的例子:

@Inject
public void Bar(Provider<Foo> genericInjector){
...

在运行时,Guice将在此处注入Provider的正确实现(即提供Foo个实例的实现)。但据我所知,泛型类型在运行时被擦除(参见:Type Erasure)。所以Guice在运行时真正看到的就是:

@Inject
public void Bar(Provider genericInjector){
....

那么Guice怎么可能知道要注入哪个Provider实现呢?

2 个答案:

答案 0 :(得分:10)

不,类型擦除不会删除所有内容。您仍然可以获取字段类型,参数等。Provider<Foo>信息 在执行时仍然存在。例如,请参阅Method.getGenericParameterTypes

保留的是有关特定对象的类型信息。例如,如果我写:

List<String> list = new ArrayList<String>();
showType(list);

...


public static void showType(List<?> list)
{
    // ???
}

由于该对象不再具有该信息,因此无法确定它是ArrayList<String>

有关 lot 的更多信息,请参阅Java Generics FAQ

答案 1 :(得分:2)

一种常见的误解是,类型擦除的工作方式是编译器基本上删除了尖括号及其内部的内容,然后就像源是Java 1.4一样。事实并非如此。

通用参数不会从方法签名中删除 - 方法签名是“编译时”。 “运行时”构造中不存在通用参数 - 您无法分辨给定对象实例化的类型参数。