Java通用?扩展字符串

Java通用?扩展字符串,java,generics,Java,Generics,当我讨论一些泛型问题时,我遇到了这个例子。请解释一下为什么list.add(“foo”)和list=new ArrayList()包含比较问题 在我对的理解列表中?扩展字符串表示“扩展字符串的内容列表”,但字符串是最终的吗?只能是字符串。在list.add()中,我们添加了一个字符串“foo”。那么为什么会出现这个编译问题呢 public class Generics { public static void main(String[] args) { } public static void

当我讨论一些泛型问题时,我遇到了这个例子。请解释一下为什么
list.add(“foo”)
list=new ArrayList()
包含比较问题

在我对
的理解列表中?扩展字符串
表示“扩展字符串的内容列表”,但字符串是最终的吗?只能是字符串。在list.add()中,我们添加了一个字符串“foo”。那么为什么会出现这个编译问题呢

public class Generics {
public static void main(String[] args) {
}

public static void takelist(List<? extends String> list){
    list.add("foo"); //-- > error
    /*
     * The method add(capture#1-of ? extends String) in the 
     * type List<capture#1-of ? extends String> is not applicable 
     * for the arguments (String)
     */

    list = new ArrayList<Object>();
    /*
     * Type mismatch: cannot convert from ArrayList<Object> to List<? extends               String>
     */
    list = new ArrayList<String>();
    Object o = list;
}
公共类泛型{
公共静态void main(字符串[]args){
}

public static void takelist(List对于初学者来说,
java.lang.String
类是最终的,这意味着没有什么可以扩展它。因此,没有任何类可以满足一般要求
?extends String

我相信这个问题会导致您看到的所有编译器错误/警告

list.add("foo");                  // String "foo" does not extend String
list = new ArrayList<Object>();   // list cannot hold Object which does not extend String
list.add(“foo”);//字符串“foo”不扩展字符串
list=new ArrayList();//列表无法容纳不扩展字符串的对象

你说的是真的。字符串是最终的。所以你可以推断
列表当字符串是最终的时,这个信息不被使用

事实上,对于Java9,它可能不再是最终的(谣传Java9可能最终得到不同的更有效的字符串类型)


在不知道它是final的情况下,
List它不会导致第二个编译错误:即使参数是
List
,也无法进行该赋值。OP已经声明知道字符串是final的。语句List@Teto如果
T extends String
有效,那么为什么会出现错误w当将
“foo”
添加到列表中时?@Tim,在编译时,编译器不知道t是什么。如果您有一个t的列表,其中t扩展了字符串,则不能将字符串放入该列表中,因为在运行时t可能不是字符串。我不是建议用户从“?”切换到“t”。
list=new ArrayList();
是有效的,这一行没有编译错误。为了让您的答案更明确一点,我可以在“那种分析”之后加上:“编译器不区分非final类和final类的泛型”。我想您应该补充一点,没有检查
String
是否是编译时的最终类。因此编译器很乐意构建您的代码,但在运行时,因为没有任何东西扩展
String
(甚至
String
本身),您不能向列表中添加任何内容。@AndyTurner,谢谢您的帮助。我做了一些澄清。@TimBiegeleisen我不确定我是否理解您的评论。在运行时,泛型成为原始类型。实际上,它是列表。它将很高兴让我在运行时将任何我想要的东西放在其中。在编译时,我被阻止放置“某物列表”中的任何内容。如果允许我放入任何内容,即使是字符串,那么如果结果显示“某物”不是字符串,那么在运行时这将是一个问题。
对象
不扩展
字符串
,但它是一个
超级
类型。
String s = list.get(0);
void appendTo(List<? extends String> l) {
  l.append("nonempty");
}

appendTo(new ArrayList<EmptyStrings>());
void appendTo(List<? super String> l) {
  l.append("nonempty");
}

appendTo(new ArrayList<Object>());