[英]Java <? extends Collection>
我有以下Java代码:
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
...
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
但它给了我一个编译器异常(最后一个是红色)说:
类型不匹配:无法从List转换为捕获#2-of? 扩展集合
命令行说:
J:\WS\Java test>javac Main.java -Xdiags:verbose
Main.java:11: error: method replaceAll in interface List<E> cannot be applied to given types;
attributes.replaceAll((in) -> {
^
required: UnaryOperator<CAP#1>
found: (in)->{ Li[...]ut; }
reason: argument mismatch; bad return type in lambda expression
List<String> cannot be converted to CAP#1
where E is a type-variable:
E extends Object declared in interface List
where CAP#1 is a fresh type-variable:
CAP#1 extends Collection<String> from capture of ? extends Collection<String>
1 error
即?
capture,可能是List<String>
的子类型或兄弟,因此将List<String>
添加到List<? extends Collection>
是不安全的List<? extends Collection>
List<? extends Collection>
。 ...extends Collection
在这里...extends Collection
并不重要。
可能的方法:
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
...
List<List<String>> attribs2 = new ArrayList<>();
attributes.forEach((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
attribs2.add(out);
});
要么:
List<Collection<String>> attributes = new ArrayList<>(nrAttributes);
...
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
您的扩展只是确保您将从列表中读取 Collection<String>
。 但你不能写它。
有关非常好的解释,请参阅此链接 ,我从中获取以下内容:
你不能将任何对象添加到
List<? extends T>
List<? extends T>
因为你不能保证它实际指向哪种List,所以你不能保证该List中允许该对象。 唯一的“保证”是你只能读取它,你将获得T的T或子类。
您将attributes
变量定义为扩展字符串集合的列表 。 在编译时,编译器无法确定attributes
实际上是List<TreeSet<String>
的实例,还是List<LinkedList<String>
或甚至List<Vector<String>
的实例。 因此,编译器不允许您修改属性集合,因为存在将ArrayList<String>
添加到另一个字符串集合(例如TreeSet<String>
的集合的风险。
一般来说,如果你有一个List<? extends Something>
List<? extends Something>
,编译器不允许你修改集合(添加/删除/清除/ ...)。 任何列表的列表? extends T
? extends T
是只读的!
编译:
List<Collection<String>> attributes = new ArrayList<>(nrAttributes);
当你说List>你说“收集的特定子类型列表”所有这些? extends X在内部被命名为capture #n of? 扩展X(第一次捕获#1 ......,第二次捕获#2 ......等等),但每次都被认为是特定类型。 例如,以下代码也没有编译,但具有相同的错误
为什么需要仿制药? 以下示例可以包含Collection of String的任何子类(compiles,btw)
List<? extends Collection<String>> attributes = new ArrayList<HashSet<String>>(nrAttributes);
attributes.replaceAll((in) -> {
List<String> out = new ArrayList<>();
out.addAll(in);
return out;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.