【问题标题】:Using java generic types with wild card "?"使用带有通配符“?”的 java 泛型类型
【发布时间】:2014-09-25 00:26:03
【问题描述】:

在尝试了解 java 泛型类型和通配符“?”的用法时,我尝试了以下方法:

  1. List<?> li = new ArrayList<Integer>();
  2. List<Integer> li2 = new ArrayList<Integer>();
  3. li2.add(new Integer(6));
  4. li = li2;

以上编译并运行良好。但如果我尝试:

li.add(new Integer(5));

我收到以下编译错误(使用 Oracle JDeveloper 作为 IDE):

Error(24,9):  cannot find method add(java.lang.Integer)

为什么上面没有编译但是赋值li=li2 没问题?另外,如果我想调用li.add(...) 什么是可接受的参数值?

【问题讨论】:

    标签: java generics wildcard


    【解决方案1】:

    ? 是通配符类型,包含所有引用类型。将要分配给? 类型的值必须可以分配给任何引用类型。 Integer 不能分配给所有引用类型(例如,String s = new Integer(1); 失败)。事实上,在 Java 中,唯一可以分配给所有引用类型的值是 null,这是您可以添加到 List<?> 的唯一值

    其他有趣的组合:

    ? super Number 是一个包含ObjectNumber 类型的范围。当你写这样一个值时,它必须同时是ObjectNumber,即。 Integer 可以。读取这样的值时,它将是ObjectNumber(即Object)。

    ? extends Number 是一个范围,包括类型 Number 及其所有子类型。当你写这样一个值时,它必须是 Number 的所有子类型的类型,即。它必须是null。当读取这样一个值时,它将是一个Number

    【讨论】:

      【解决方案2】:

      对“li”的调用不会影响您是否为它分配了ArrayList<Integer>LikedList<String>,它只适用于声明的类型,即List<?>

      当您声明一个泛型参数时,它可以应用于返回类型和方法参数。例如,在List<String> 中,您将拥有String get(int i)void add(String) 方法。

      两者都是安全的,因为使用此方法您只能从列表中添加(和检索)字符串。

      List<?> 上,您将拥有Object get(int i) 方法,因为列表中的任何内容都可以安全地转换为对象,无论是整数还是字符串。

      但是,提供void add(Object) 方法是不安全的,因为它允许您将字符串添加到整数列表,反之亦然(或任何其他东西)。

      【讨论】:

        猜你喜欢
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多