【问题标题】:Why can't I add to a List<? extends String> in Java?为什么我不能添加到 List<?在Java中扩展字符串>?
【发布时间】:2015-08-29 06:04:26
【问题描述】:

在下面的 sn-p 中,将“Hulooo”添加到列表中会产生编译器错误,因为 String 不扩展 String。 但是,对字符串的 ArrayList 进行类型转换是有效的。但是对对象的 ArrayList 进行类型转换是行不通的。

有人可以解释为什么会这样吗? 什么适用于字符串(在此上下文中)不适用于对象?

public static void takeList(List<? extends String> list)
{
    list.add("Hulloo");//ERROR
    list=new ArrayList<String>();
    list=new ArrayList<Object>();//ERROR
}

【问题讨论】:

  • 第一个错误是因为编译器不够聪明,无法意识到String 没有子类。您提供的list 可能是List&lt;SuperString&gt; 类型(如果SuperString 以某种方式扩展String),在这种情况下,如果您设法添加一个普通的旧String,则会产生不一致。至于第二个错误,? extends Stringmenas "String or a subclass of String",不是严格意义上的"subclass of String",所以String符合描述,而Object不符合。跨度>
  • 谢谢。现在我明白了。但是您的意思是第一个错误是预期该列表可能具有 String 的子类对象,因此不允许添加?这很奇怪。如果它毕竟是一个字符串列表呢?
  • @Brindha ? extends String 表示它可能是字符串,也可能不是。它可以是任何扩展的东西(即使它是final class)编译器不能让你做一些可能或可能不正确的事情。
  • 你不能从java.lang.String扩展...见docs.oracle.com/javase/8/docs/api/java/lang/String.html:public final class String extends Object implements Serializable, Comparable&lt;String&gt;, CharSequence

标签: java generics arraylist


【解决方案1】:

问号? 是所谓的通配符运算符。 List&lt;? extends String&gt; 表示:任何类型List&lt;T&gt;,其中TStringString 的子类型。 String 是 final 类,因此没有 String 的子类型,但编译器不看这个。因此,编译器假定该列表可能是String 的某个子类型的列表,并且不可能将Strings 添加到这样的列表中。

让我们用一个非最终类A 模拟您的示例,该类有一个子类B

class A { 
    // empty
}

class B extends A {
    void f();
}

现在考虑与您的方法等效的方法:

public static void takeList(List<? extends A> list) {
    list.add(new A());
}

这不会编译,原因如下。假设你这样调用这个方法:

List<B> myList = new ArrayList<>();   // line 1
takeList(myList);                     // line 2
B element = myList.get(0);            // line 3
B.f();                                // line 4

由于BA 的子类,因此第2 行中的函数调用是合法的。但是takeList 方法将A 添加到不是B 的列表中。然后Bs 的列表包含一个不是B 的元素,第 3 行和第 4 行分解。

类型系统用于防止输入错误,因此如果有一种情况可以将错误类型的对象添加到列表中,则类型系统必须禁止它。

【讨论】:

  • 如果您想编辑您的答案,请务必先登录:P
  • @QPaysTaxes 不是我试图编辑答案,但编辑是正确的。如代码上面的那行所述,B 应该是A 的子类。
  • 哦,很公平。是的,我同意编辑是正确的;回想起来,我不知道我为什么拒绝它。
猜你喜欢
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多