我很难理解泛型通配符的概念。
据我了解<?>
引入未知类型来解决泛型不支持的协方差,它应该适合任何类型的集合和<?extends T>
意味着您可以拥有类型的集合 T
或扩展 T.<?super T>
的类意味着你可以拥有类型的集合 T
或 T
的上级.
如有错误请指正
当我尝试这样写时:
import java.util.*;
public class Gclass {
static Gclass t;
public void write(List< ?super String > lw){
lw.add("b");
}
public void read(List< ? extends String> lr){
String s=lr.get(2);
System.out.println(s);
}
public static void main(String[] args) {
t=new Gclass();
List<String> l=new ArrayList<String>();
l.add("a");
l.add("");
System.out.println(l);
t.write(l);
System.out.println(l);
t.read(l);
System.out.println(l);
}
}
它有效,但我怀疑的地方是:
根据我的理解,(extends 和 super)都包含声明的类型,所以在这个特殊情况下,我的
List
类型为String
.我可以互换 extends 和 super,但出现编译错误?如果写
? super Object
不管用?它应该工作,因为它是String
的 super ?我没有检查 read as
String
不能扩展,但我想我在这里也缺少一个概念。
我已经阅读了与此问题相关的所有关于 SO 的答案,但我仍然无法很好地理解它。
最佳答案
String 确实是一个不好的例子,因为它是 final
类,但考虑像 Number
这样的东西相反。
如果方法采用 List<? extends Number>
类型的参数然后你可以传递一个 List<Number>
或 List<Integer>
或 List<BigDecimal>
等等。因此,在方法主体中,可以将列表中的内容 取出(如您所知,它们必须是 Number
的实例),但您不能将任何内容放入 因为您不知道它是否安全(例如,编译器不能让您冒险将 Integer
放入 List<Float>
中)。
相反,如果该方法采用 List<? super Number>
然后你可以传递一个 List<Number>
或 List<Object>
- 你不能从这个列表中取出任何东西,因为你不知道它是什么类型*,但你知道放置一个 Number
绝对是安全的在。
* 从技术上讲,您可以取出东西,但您可以将它们分配给的唯一类型是 Object
关于java - 为什么有必要在泛型通配符中读取和 super 写入的情况下进行扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21209830/