我有以下代码:
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>();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,类Generic
使用泛型类型参数声明,但generic
方法中的变量main
属于擦除类型,即没有类型参数.我不明白的是为什么编译器抱怨分配的行List<String>
:
Warning:(6, 56) java: unchecked conversion
required: java.util.List<java.lang.String>
found: java.util.List
Run Code Online (Sandbox Code Playgroud)
该方法明确返回a List<String>
,独立于类的泛型参数.这就是变量所stringList
期望的.似乎不在类级别上使用泛型参数来generic
关闭所有泛型处理,而不仅仅是取决于类的类型参数.
我正在使用标准的Oracle Java 1.7.0_55编译器,如果这很重要的话.
我不是在问如何摆脱警告.我知道我应该声明变量类型Generic<Integer>
,或者可以使用@SuppressWarnings("unchecked")
.我的问题如下:
这种行为是否有记录?
这种奇怪行为的原因是什么?
Jon*_*eet 13
当您使用类型的擦除时,它会删除所有泛型的痕迹 - 而不仅仅是类型参数的使用T
.所以你的generic
变量就好像它指的是这种类型:
// 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();
}
}
Run Code Online (Sandbox Code Playgroud)
这在JLS中有记录 - 从4.6节开始并按照链接进行操作.它并不像它可能那样清晰,但它有记载.
原因是,如果您使用原始类型,编译器希望您根本不了解泛型 - 因为它可能正在编译传统的Java-5之前的代码.随着时间的推移,这被证明有点不切实际,但我相信这是规范的动机.
归档时间: |
|
查看次数: |
490 次 |
最近记录: |