Java Generics:再次使用通配符

时间:2011-12-28 15:33:49

标签: java generics

我正在尝试创建一个只接受特定类的容器。使用泛型如下:

    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>,这意味着在这种情况下,泛型的整点都丢失了......如果我是的话请纠正我错。

4 个答案:

答案 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