[英]java generics - “extends” keyword -> not supporting add elements
[英]Why we cant add the elements in java generics using extends bounds?
我知道我们不能在列表中添加扩展边界类型的元素。 但我仍然不确定为什么 java 编译器不允许这样做。 因为编译器可以很容易地检查添加的新元素是否是 Generic 类型的子类型。 任何人都可以帮我解决这个问题吗?
这种情况称为协方差, extends
关键字允许您从Collection
读取元素,但不能添加它们。 这是因为编译器将add
操作视为不安全。 例如,您可以声明以下任何列表:
List<? extends Number> myNums = new ArrayList<Integer>();
List<? extends Number> myNums = new ArrayList<Float>();
List<? extends Number> myNums = new ArrayList<Double>();
您可以毫无问题地读取它们,因为无论列表包含什么,都可以向上转换为Number
。 但是,您不得将任何内容放入其中:
myNums.add(45L); //compiler error
这是因为编译器无法确定泛型列表的实际类型(在我们的示例中可能是Integer
、 Float
或Double
)。 因此,这是一个不安全的操作,您可能将Long
添加到Integer
列表,因此编译器不允许您这样做。
阅读这篇文章以获得更深入的解释。
我将使用对这里示例的修改:
List<String> ls = new ArrayList<String>();
List<? extends Object> l = ls;
l.add(l, new Object()); // not legal - but assume it was!
String s = ls.get(0); // ClassCastException - ls contains
// Objects, not Strings.
您非常正确地指出“编译器可以轻松检查添加的新元素是否是泛型类型的子类型”。 但即便如此,由于编译器无法确定列表l
的类型,接受l.add(l, new Object())
将导致列表ls
损坏。
因此编译器正在做它的工作,它比运行时检查更早地捕获错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.