Generics:LowerBounded通配符vs UpperBounded通配符

问题描述 投票:0回答:1

我了解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行给出了编译时错误。为什么这样?
  • 在第二种情况下,当我将我的列表传递给printMyList方法时,它在第2行的String中打印每个元素类类型,但是在第3行中,为什么我不能调用任何特定于String类的方法,如charAt。以及为什么不需要强制转换为String。

也针对消费者

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

为什么我不能在myList中添加对象。因为如果我们使用super,则意味着该列表可以包含相等且高于Java类层次结构中的number的对象。因此,应按照该语句将新的Object()添加到列表中。

谢谢。

java generics wildcard pecs
1个回答
0
投票
List<Object> ProducerList = new ArrayList<>();

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

由于printMyList的参数myList接受一种以上的类型,因此您必须在强制转换之前检查其传递的类型,以调用其方法,例如charAt()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

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

© www.soinside.com 2019 - 2024. All rights reserved.