MAR*_*REK 5 java generics java-8
我有这样的代码:
public class A<T extends String> {
T field;
List<T> fields;
public T getField() {
return field;
}
public List<T> getFields() {
return fields;
}
public static void test(){
A a = new A();
String s = a.getField();
List<String> ss = a.getFields();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么在A没有泛型类型的getFiled情况下创建返回String但getFileds返回List<Object>?
我必须定义A为A<String> a = new A<>()使其正常工作.
谢谢,
T声明中类型参数的擦除T field是String因为T已经绑定:
<T extends String>
Run Code Online (Sandbox Code Playgroud)
而且任何subtype一个String也是String1.
但是,这不适用于通用List<T>.它源于仿制药不协变的事实:
List<String> str = new ArrayList<String>();
List<Object> obj = str; // Error: incompatible types (even though String extends Object)
Run Code Online (Sandbox Code Playgroud)
的擦除List<T>在声明List<T> fields是List,特别是因为List<T>可以保持String或它的subtypes1.并且鉴于它A是原始类型,编译器无法猜测getFields()方法返回的列表中的元素类型.
无论如何,这行代码:
List<T> fields;
Run Code Online (Sandbox Code Playgroud)
编译(擦除通用类型)到:
List fields;
Run Code Online (Sandbox Code Playgroud)
结果,当你写:
A a = new A(); instead of A<String> a = new A<>();
Run Code Online (Sandbox Code Playgroud)
你失去了类型安全性并获得"未经检查的分配"警告 - 在这种情况下,编译器不能保证它fields list完全是List<String>:
List<String> list = a.getFields(); // Unchecked assignment: 'List' to 'List<String>' ...
Run Code Online (Sandbox Code Playgroud)
PS不要使用原始类型!
1 - 如您所知,String课程是最终的,不能延长.如果您愿意,可以将其替换为任何可以扩展的类型.
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |