参见英文答案 >
Why won’t this generic java code compile?4个
我有以下代码:
我有以下代码:
public class Main { public static void main(String[] args) { Generic generic = new Generic<Integer>(5); List<String> stringList = generic.getStringList(); // this line is where the compiler complains } } public class Generic<T> { private T member; public Generic(T member) { this.member = member; } public T getMember() { return member; } public List<String> getStringList() { return new ArrayList<String>(); } }
请注意,类Generic使用通用类型参数声明,但方法main中的变量generic属于擦除类型,即i.即没有类型参数.我不明白的是为什么编译器会抱怨分配列表< String> ;::
Warning:(6,56) java: unchecked conversion required: java.util.List<java.lang.String> found: java.util.List
该方法清楚地返回一个列表< String>独立于该类的通用参数.这就是stringList所期望的变量.似乎没有在类级别上使用泛型参数对变量通用开关进行所有泛型处理,而不仅仅是依赖于类的类型参数.
我正在使用标准的Oracle Java 1.7.0_55编译器,如果重要.
我不是问如何摆脱警告.我知道我应该将变量类型声明为Generic< Integer>,或者可以使用@SuppressWarnings(“unchecked”).我的问题如下:
这个行为记录在案吗?
这个奇怪行为的原因是什么?
解决方法
当您使用类型的擦除时,它会删除泛型的所有痕迹,而不仅仅是类型参数T的使用.因此,您的通用变量的行为就好像指向此类型:
// After type erasure public class Generic { private Object member; public Generic(Object member) { this.member = member; } public Object getMember() { return member; } public List getStringList() { return new ArrayList(); } }
这在JLS中记录 – 从section 4.6开始,并按照链接.它不是那么清楚,但它被记录在案.
原因是,如果您使用的是原始类型,编译器会希望您根本不知道泛型,因为它可能是编译旧的Java-5代码.这被证明是有点不切实际的,但我相信这是规范的动机是它的方式.