【发布时间】:2013-12-11 09:05:27
【问题描述】:
我正在处理作者在泛型定义中使用原始类型的代码。当使用原始类型时,编译器似乎根本无法识别泛型类型,即使泛型类型是在原始类中显式定义的。
让我用一个例子来解释一下。我们有一个豆子:
class Bean<T> {
private List<String> list = new ArrayList<String>();
private T object;
public T getObject() {
return object;
}
public void setObject(T object) {
this.object = object;
}
public List<String> getList() {
return list;
}
}
还有一个包装器(代码使用的是 Apache Wicket,我只是将其抽象出来):
class Wrapper<S> {
private S wrapped;
public S getWrapped() {
return wrapped;
}
public void setWrapped(S wrapped){
this.wrapped = wrapped;
}
}
现在我们的人以一种半通用的方式使用 Wrapper,编译器没有给出警告(很遗憾):
Wrapper<Bean> wrapper = new Wrapper<Bean>();
wrapper.setWrapped(new Bean<Integer>());
// The next line returns a raw type even though the List<String>
// type is stated explicitly in Bean.class and known by the compiler
wrapper.getWrapped().getList();
当然,我们不应该使用原始类型,而是声明Wrapper<Bean<?>>。不过,我想知道为什么编译器对此如此严格。编译器在解析类型时是否设置了某种 raw 标志并忽略 all 通用信息,即使是已知的信息?这就是我的样子。阅读JLS 中的相应部分,我可以找到明确的答案。我也想知道这个决定背后是否有原因。
【问题讨论】:
-
不需要整个
Wrapper部分来证明这一点:仅访问(new Bean()).getList()也会返回原始List。 -
没错,我从一个实际的应用程序中简化了一些代码,但我做得还不够简单。
标签: java generics javac raw-types