0

我了解 PECS(生产者扩展,消费者超级)的概念,但仍然对这些符号感到困惑:

public class PECSTest {
    public static void main(String[] args) {
        //List<? extends Object> ProducerList = new ArrayList<String>();
        //ProducerList.add("1"); // Line 1 :compileTimeError

        PECSTest myTest = new PECSTest();
        List<String> myList = new ArrayList<String>();
        myList.add("abc");
        myTest.printMyList(myList);
    }

    private void printMyList(List<? extends Object> myList) {
        // TODO Auto-generated method stub
        int i=0;
        while(i<myList.size()) {
            System.out.println(myList.get(i).getClass()); //Line 2
            System.out.println(myList.get(i).charAt(0)); // Line 3
            System.out.println(myList.get(i).equals(new String("abc")));
            i++;
        }
    }
}
  • 即使我已经创建了一个可以接受任何扩展 Object 类的对象的列表,但是当我尝试添加字符串时,它在第 1 行给出了编译时错误。为什么?
  • 在第二种情况下,当我将 List 传递给 printMyList 方法时,它会在第 2 行打印 String 中的每个元素类类型,但是在第 3 行,为什么我无法调用任何 String 类特定的方法,例如charAt。还有为什么不需要对 String 进行强制转换。

同样在消费者的情况下

 List<? super Number> myList = new ArrayList<Object>();
 myList.add(new Object());// compile time error

为什么我不能在 myList 中添加对象。因为如果我们使用 super 这意味着这个列表可以包含等于和高于 Java 类层次结构中的数字的对象。所以 new Object() 应该根据该语句添加到列表中。

谢谢。

4

1 回答 1

0

List已经是 Generic 所以你不应该将它的类型设置为泛型;如果您希望它接受所有类型,请将其类型设置为Object;此外,您不应该在实例化中指定类型,因为 Java 可以从类型声明中推断出它:

List<Object> ProducerList = new ArrayList<>();

感谢 Java PolymorphismProducerList现在允许所有类型,因为所有类都是Object类的特化。

由于printMyList's 参数myList接受不止一种类型,因此您必须在强制转换之前检查其传递的类型,以便调用其方法,例如charAt()for String

if (myList.get(i) instanceof String) { 
    System.out.println(((String)myList.get(i)).charAt(0)); // Line 3
}

完整的工作代码:

import java.util.*;

class PECSTest
{
    public static void main(String[] args) {
        List<Object> ProducerList = new ArrayList<>();
        ProducerList.add("1"); // Line 1

        PECSTest myTest = new PECSTest();
        List<String> myList = new ArrayList<String>();
        myList.add("abc");
        myTest.printMyList(myList);
    }

    private void printMyList(List<? extends Object> myList) {
        int i=0;
        while(i<myList.size()) {
            System.out.println(myList.get(i).getClass()); //Line 2
            if (myList.get(i) instanceof String) { 
                System.out.println(((String)myList.get(i)).charAt(0)); // Line 3
            }
            System.out.println(myList.get(i).equals(new String("abc")));
            i++;
        }
    }
}

输出:

class java.lang.String
a
true

Number附注:为什么在( )上使用下界通配符List<? super Number>?可能是List<? extends Number>允许每个子类Number而不是每个Object不是Number...

于 2019-11-25T11:32:30.867 回答