当前位置: 首页 > 知识库问答 >
问题:

泛型:下界通配符与上界通配符

凌成天
2023-03-14
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++;
        }
    }
}
    null
 List<? super Number> myList = new ArrayList<Object>();
 myList.add(new Object());// compile time error

为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。

多谢了。

共有1个答案

司空浩邈
2023-03-14

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

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

由于Java多态性,ProducerList现在允许所有类型,因为所有类都是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

附带说明:为什么在number(list<?super number>)上使用下限通配符?可能是列表<?扩展number>,允许number的每个子类代替不是number的每个对象...

 类似资料:
  • 上限通配符下限通配符 有人能帮我理解一下吗?

  • 这个问题的答案表明,当方法采用通配符泛型类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特) 据我所知,方法do1有,因此d2只能被访问,不能被修改。方法d2具有,因此可以访问和修改c2,并且没有编译错误。 通用指南

  • 问题内容: 我有一个接口将对象转换为字符串: 以及用于存储所有可用转换器的地图: 现在,我有了要转换的异构数据列表,如下所示: 但是此代码无法编译: 我应该如何更改代码? 问题答案: 您面临的问题称为通配符捕获。Java无法识别将从数据中接收的类型。尝试以两种方式中的任何一种重构代码 方法1:如下 更改您的界面 方法2: 通过类型推断来捕获通配符的Helper方法 创建如下的帮助方法, 如下调用此

  • 问题内容: 您好直接从Oracle http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html提供的Java教程中 我知道编译时的类型擦除。而且我也知道,一个类型(无界)将被Object取代。知道在编译时如何使用无界通配符进行编译吗?只是删除它,因为它是原始类型? 提前致谢。 问题答案: 假设我们有一个

  • 根据Joshua Bloch的“有效Java”一书,关于如何/何时在泛型中使用有界通配符有一个规则。这个规则就是PECS(productor-extends,Comsumer-Super)。当我研究以下示例时: 根据PECS规则,上述声明是错误的。但是我希望有一个的,并向这个传递一个。为什么不做呢? 为什么要始终使用关键字?为什么使用是错误的? 当然,这也代表了Comsumer的观点。为什么消费者

  • 我正在与Java8通配符泛型作斗争。 假设一个名为的泛型类(来自Core Java book) 是因为Java8编译器转换吗?超级经理反对,因此任何事情都是允许的?