繁体   English   中英

Java泛型:再次使用通配符

[英]Java Generics: wildcards again

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

    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>会接受newInstance对象,但是在我取回“ Test1值”时却发生了编译时错误? 有没有解决此问题的机会?

提前致谢。

UPDATE许多人注意到“ Test1<? extends Test1> ,其中?可能不等于Test2。” 我完全同意,但是据我所知,在这种情况下,我需要将提取的值类型转换为Test1<Test2> ,这意味着在这种情况下,泛型的全部意义都消失了。如果我错了,请纠正我。

因为当您list.get(1)返回Test1<? extends Test1> Test1<? extends Test1> ,在哪里? 可能不等于Test2

在另一方面, list.add(...)接受Test1<? extends Test1> Test1<? extends Test1> ,即使用具有泛型参数的Test1,它是Test1的继承者。

这是因为您可以将Test1 <>与类型为Test1的子对象的每个对象一起存储。 假设您有Test3类扩展了Test1,那么您将拥有

Test1<Test2> value = list.get(1);

但是列表如何确保索引为1的元素具有通用类型Test2,但没有通用类型Test3,因为它接受Test1()的每个子类型。

提取元素的正确方法是使用

Test1<? extends Test1> test1 = list.get(1);

您可以通过写来解决问题

Test1<? extends Test1> value = list.get(1);

代替

Test1<Test2> value = list.get(1);

或强制转换为Test1。

List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>();

这是一个只读列表,您只能在此列表中插入null

而是在下面使用:

List<Test1<? extends Test1>> list = new ArrayList<Test1<XXX>>();  where XXX extends Test1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM