我正在尝试创建一个只接受特定类的容器。使用泛型如下:
static class Test1<C extends Test1> {
C field = null;
public C getField() {
return field;
}
public void setField(C field) {
this.field = field;
}
}
static class Test2 extends Test1{
}
class MainTest {
public static void main(String[] args) throws Exception {
List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>();
Test1<Test2> newInstance = new Test1<Test2>();
list.add(newInstance);
Test1<Test2> value = list.get(1);
}
}
只想了解为什么这个List&gt;会接受newInstance对象,但是当我提取“Test1值”时会发生编译时错误吗? 有没有机会解决这个问题?
提前致谢。
UPDATE
许多人注意到“Test1<? extends Test1>
,其中?可能不等于Test2。”
我完全同意,但据我所知,在这种情况下,我需要将提取的值输入到Test1<Test2>
,这意味着在这种情况下,泛型的整点都丢失了......如果我是的话请纠正我错。
答案 0 :(得分:1)
因为当list.get(1)
返回Test1<? extends Test1>
时,?
可能不等于Test2
。
on onther hand list.add(...)
接受Test1<? extends Test1>
,即Test1使用任何generics参数,它是Test1的继承者。
答案 1 :(得分:0)
这是因为您可以存储Test1&lt;&gt;将每个作为Test1子节点的对象作为类型化参数。让我们说你有 Test3类扩展了Test1 那么你会有
Test1<Test2> value = list.get(1);
但是列表如何确保索引1的元素具有泛型类型Test2而不是Test3,因为它接受Test1()的每个子类型。
获取元素的正确方法是使用
Test1<? extends Test1> test1 = list.get(1);
答案 2 :(得分:0)
您可以通过编写
来解决问题Test1<? extends Test1> value = list.get(1);
而不是
Test1<Test2> value = list.get(1);
或通过对Test1进行强制转换。
答案 3 :(得分:0)
List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>();
这是一个只读列表,你只能在这个列表中插入null,没有别的
改为使用以下:
List<Test1<? extends Test1>> list = new ArrayList<Test1<XXX>>(); where XXX extends Test1