【问题标题】:An example when List<?> is not the same as List<Object> [duplicate]List<?> 与 List<Object> 不同时的示例 [重复]
【发布时间】:2023-03-14 17:46:01
【问题描述】:

它是用java制作的,泛型不会自动从Generic&lt;A&gt;转换为Generic&lt;SupeclassOfA&gt;

比如如果写一个方法

public static void printList(List<Object> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

它不会接受List&lt;Integer&gt;。我需要为List&lt;?&gt; 重写标题,尽管代码相同,但它会开始工作。

那么,为什么要这样做?

假设我重新设计了Java,使List&lt;?&gt; 的含义始终与List&lt;Object&gt; 相同。我会遇到什么问题?

【问题讨论】:

  • 尝试在列表中添加一些东西。
  • 这个问题在 SO 上被问了几十次。请先搜索现有问题。

标签: java generics type-conversion


【解决方案1】:

假设采用List&lt;Object&gt; 的方法接受List&lt;Integer&gt;。这意味着List&lt;Integer&gt;List&lt;Object&gt; 的子类型。如果这是真的,你可以这样做:

List<Integer> intList = new ArrayList<Integer>();
List<Object> objList = (List<Object>) intList;
objList.add("foo");
int a = intList.get(0);  // This would fail at runtime because intList.get(0) is a String.

因此,如果您可以将 List&lt;Integer&gt; 强制转换为 List&lt;Object&gt;,您将失去泛型提供的编译时类型安全性。

List&lt;?&gt;List&lt;Object&gt; 不同。 List&lt;?&gt; 是某个未知类型 TList。由于T 未知,因此无法向List&lt;?&gt; 添加任何内容(null 除外)。这与您可以添加任何内容的List&lt;Object&gt; 完全相反。

一般来说,List&lt;Object&gt; 很少是您需要的。大多数情况下,您需要List,其中所有项目都具有相同的类型,例如List&lt;Integer&gt;List&lt;String&gt;。如果您正在编写类型不重要的方法,例如仅打印项目的示例,则参数应具有类型List&lt;?&gt;

【讨论】:

    【解决方案2】:

    您还可以声明一个上限。所以你说:

    List<? extends Foo> list
    

    这将导致您只能访问列表中作为 foo 子类的事物。 在你的情况下写扩展对象。所以 Integer 是一个可以插入的子类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 2010-09-28
      相关资源
      最近更新 更多