我生活了很长时间,但我从来没有理解过的东西。
问题是评论:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static class Test1 {
public List<String> getStrings(){
List<String> s = new ArrayList();
s.add("test1");
return s;
}
}
public static class Test2<PARAM> {
public List<String> getStrings(){
List<String> s = new ArrayList();
s.add("test2");
return s;}
}
public static void main(String[] args) {
Test1 test1 = new Test1();
Test2 test2 = new Test2();
for (String string : test1.getStrings()) {
System.out.println(string);
}
// Why do I need this cast (List<String>) ?
for (String string : (List<String>)test2.getStrings()) {
System.out.println(string);
}
}
}
那么为什么我需要演员表(列表(?
弗兰克
像这样实例化它
Test2<String> test2 = new Test2<>();
我使用<String>
作为演示目的的类型
如前所述,您需要指定Test2
的类型
您需要使用泛型参数类型指定所有参数,否则编译器将恢复为预<>
语义,其中List
仅提供Object
元素。
public static class Test1 {
public List<String> getStrings(){
List<String> s = new ArrayList<>(); // ***
s.add("test1");
return s;
}
}
public static class Test2<PARAM> {
public List<String> getStrings(){
List<String> s = new ArrayList<>(); // ***
s.add("test2");
return s;}
}
public static void main(String[] args) {
Test1 test1 = new Test1();
Test2<Integer> test2 = new Test2<>(); // ***
for (String string : test1.getStrings()) {
System.out.println(string);
}
// Why do I need this cast (List<String>) ?
for (String string : test2.getStrings()) { // ***
System.out.println(string);
}
}
我认为这是编译器中的一个怪癖,带有泛型和类型擦除。 当编译器编译泛型类时,它会执行所有类型检查,然后去除所有<>
并创建基本上看起来像的字节代码
List list = new ArrayList();
请注意没有类型参数。
该类将编译为
public static class Test2 {
}
如果您有类型参数:
public T returnT(){
return T;
}
编译为
public Object returnT(){
return Object;
}
看来,如果您创建一个没有类型的泛型类
Test2 test2 = new Test2<>();
编译器知道有问题,并要求您显式强制转换。
for (String string : (List<String>)test2.getStrings()) {
System.out.println(string);
}
如果添加类型
Test2<Integer> test2 = new Test2<>(); // can put any type here as we're not actually using the type
编译器可以进行一些类型检查,并推断getString的类型是String,因此它可以编译
for (String string : test2.getStrings()) {
System.out.println(string);
}
查看此处以获取进一步阅读