遍历泛型方法返回的某些列表

时间:2019-12-12 13:47:41

标签: java generics

我住了很久的东西,但我从未理解。.

问题是评论:

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

那我为什么需要演员表(列表)?

弗朗克

3 个答案:

答案 0 :(得分:0)

像这样实例化

Test2<String> test2 = new Test2<>();

出于演示目的,我使用<String>作为一种类型

如前所述,您需要指定Test2

的类型

答案 1 :(得分:0)

您需要使用通用参数类型指定所有参数,否则编译器将还原为<>之前的语义,其中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);
        }
    }

答案 2 :(得分:0)

我认为这是具有泛型和类型擦除功能的编译器中的一个怪癖。 当编译器编译泛型类时,它将执行所有类型检查,然后剥离所有<>并创建基本上看起来像

的字节码
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

编译器可以进行一些类型检查,并推断出getStrings是String类型,因此可以编译

  for (String string : test2.getStrings()) {
            System.out.println(string);
        }

看看here以供进一步阅读