简体   繁体   English

为什么我不能添加到列表 <? extends String> 在Java中?

[英]Why can't I add to a List<? extends String> in Java?

In the snippet below, adding "Hulooo" to the list generates a compiler error since String doesnt extend String. 在下面的代码段中,将“ Hulooo”添加到列表中会生成编译器错误,因为String不会扩展String。 However, typecasting an ArrayList of strings works. 但是,对字符串的ArrayList进行类型转换是可行的。 But typecasting an ArrayList of objects doesn't work. 但是类型转换对象的ArrayList不起作用。

Can someone explain why this is happening? 有人可以解释为什么会这样吗? What applies to String(in this context) that doesn't apply to Object? 什么适用于String(在这种情况下)而不适用于Object?

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

The question mark ? 问号? is a so-called wild-card operator. 是所谓的通配符运算符。 List<? extends String> List<? extends String> means: any type List<T> where T is String or a sub-type of String . List<? extends String>是指:任何类型的List<T>其中TString或一个子类型的String String is a final class, and thus there are no sub-types of String , but the compiler does not look at this. String是最后一个类,因此没有String子类型,但是编译器没有考虑这一点。 And thus, the compiler assumes that the list could be a list of some sub-type of String , and it would not be possible to add String s to such a list. 因此,编译器假定该列表可能是String的某些子类型的列表,并且不可能将String添加到这样的列表中。

Let's simulate your example with a non-final class, A , which has a sub-class, B : 让我们用一个非最终类A模拟您的示例,该类具有一个子类B

class A { 
    // empty
}

class B extends A {
    void f();
}

And now consider the equivalent to your method: 现在考虑与您的方法等效的方法:

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

This will not compile, for the following reason. 由于以下原因,它将无法编译。 Suppose you call this method as follows: 假设您按以下方式调用此方法:

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

Since B is a sub-class of A the function call in line 2 is legal. 由于BA的子类,因此第2行中的函数调用是合法的。 But the method takeList adds an A to the list which is not a B . 但是方法takeListA添加到列表中,而不是B An then the list of B s contains an element which is not a B , and line 3 and 4 break down. 然后B的列表包含一个不是B的元素,并且第3行和第4行分解。

The type system is there to prevent typing errors, so if there is one scenario where you could add an object of the wrong type to a list, the type system must forbid it. 那里有类型系统来防止键入错误,因此,在一种情况下,您可以将错误类型的对象添加到列表中,类型系统必须禁止它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能将SuperType添加到List <T> 哪里 <T extends SuperType> ? - Why can't I add SuperType to List<T> where <T extends SuperType>? 为什么Java编译器不能推断Iterable<string> 从约束Iterable<!--? extends CharSequence--> 和 () -&gt; (迭代器<string> )</string></string> - Why can't the Java compiler infer Iterable<String> from the contraints Iterable<? extends CharSequence> and () -> (Iterator<String>) 为什么我不能将子列表传递给接受List <?的方法?扩展父>? - Why can't I pass a list of children into a method that accepts List<? extends Parent>? 为什么不能列出<!--? extends Animal-->替换为列表<animal> ?</animal> - Why can't List<? extends Animal> be replaced with List<Animal>? 为什么我不能将字符串放入扩展Object的字段中 - Why i can't put string into a field which is something that extends Object 为什么我不能向 ByteBuffer 添加字符串? - Why can't I add a String to a ByteBuffer? 为什么我不能创建Java列表? - Why can't I create the Java list? Java:无法使用通用列表 <? extends Parent> 我的列表 - Java: Can't to generic List<? extends Parent> mylist 如何添加到列表<? extends Number>数据结构? - How can I add to List<? extends Number> data structures? 无法传递地图 <Long, String> 一个带参数Map的构造函数 <? extends Object, ? extends Object> 。 为什么? - Can't pass a Map<Long, String> to a constructor with the argument Map<? extends Object, ? extends Object>. Why?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM