这个问题是关于接口与实现接口的类之间的关系。我看不出这个或这个如何回答这个问题。
我创建了一个接口 Boxed
和一个抽象泛型类 Box
,实现接口。然后我创建了两个具体的类 IntegerBox
以及 StringBox
. 然后我创建了一个元素列表 Box
带着一个 IntegerBox
值和a StringBox
价值观。到现在为止,一直都还不错。
现在我要分配 List<? extends Box>
至 List<Boxed>
. 我的期望是,这应该是有效的,因为无论什么 Box
工具也 Boxed
. 但是编译器不允许我。这是错误:
main.java:29: error: incompatible types: List<CAP#1> cannot be converted to List<Boxed>
List<Boxed> lb2 = laeb; // does not compile, although every value which extends Box implements Boxed
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Box from capture of ? extends Box
1 error
我可以复制列表:
List<? extends Box> laeb = List.of (new IntegerBox(42), new StringBox("answer"));
List<Boxed> lb1 = new ArrayList<> (laeb);
类型的每个元素 ? extends Box
如果类型 Boxed
. 但分配报告的类型不兼容。为什么?
import java.util.List;
import java.util.ArrayList;
public class main
{
static interface Boxed { }
static abstract class Box<T> implements Boxed
{
T content;
Box (T content) { this.content = content; }
}
static class IntegerBox extends Box<Integer> { IntegerBox (Integer content) { super (content); } }
static class StringBox extends Box<String> { StringBox (String content) { super (content); } }
public static void main (String ...arguments) throws Exception
{
IntegerBox i = new IntegerBox(42);
StringBox s = new StringBox("answer");
List<? extends Box> laeb = List.of (i, s);
Boxed b0 = i; // => IntegerBox is compatible with Boxed
Boxed b1 = s; // => StringBox is compatible with Boxed
List<Boxed> lb1 = new ArrayList<> (laeb); // List<Boxed> can be created by values of "? extends Box"
List<Boxed> lb2 = laeb; // does not compile, although every value which extends Box implements Boxed
}
}
2条答案
按热度按时间kmbjn2e31#
考虑一下:
在最后一行之后,
stringBoxList
将包含一个IntegerBox
,尽管最初是ArrayList<StringBox>
. 那太糟糕了。这就是编译器正在阻止的。
解决这个问题很简单
或者,你也可以写
…因为如果你不能修改列表,问题就会消失。
(但是,坦率地说,list是list的一个子类吗?为什么java泛型不是隐式多态的?涵盖了这一点,但不是
? extends
.)xxhby3vn2#
现在我要分配
List<? extends Box>
至List<Boxed>
.你不能那样做,因为
List<Boxed>
不是上界通配符的超类型<? extends Box>
.更改:
使用:
List lb1 = new ArrayList<>(laeb);