循环访问泛型类方法返回的某个列表



我生活了很长时间,但我从来没有理解过的东西。

问题是评论:

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);
}

查看此处以获取进一步阅读

最新更新