繁体   English   中英

Java上的通配符和子类型

[英]Wildcards and Subtyping on Java

我刚刚开始研究Java上的通配符和子类型,并尝试测试我所学到的东西。

假设:

Class A { public int y=1; }
Class B extends A { public int x=2; }

在主要方面:

List<B> lb = new ArrayList<>();
lb.add(new B());
System.out.println(lb.get(0).y); //Displays member y of Class A
List<? extends A> la = lb;
System.out.println(la.get(0).y); //Can access member y of Class A

List<A> la1 = new ArrayList<>();
la1.add(new A());
System.out.println(la1.get(0).y); //Displays member y of Class A
List<? super B> lb1 = la1;
System.out.println(lb1.get(0).y); //Cannot access member y of Class A? Why?

我不明白为什么我无法使用“下界通配符”来访问成员y,而有可能使用“上界通配符”。 我想念什么吗?

考虑

Interface X { ... }
Class A { public int y=1; }
Class B extends A implements X { public int x=2; }

List<? super B> lb1 = la1;

现在,只要lb1的对象实现了X ,它们就可能与AB完全无关。 编译器无法知道lb1.get(0)具有成员y

一个更“具体”的例子:

Class X { ... }
Class A extends X { public int y=1; }
Class B extends A { public int x=2; }

使用此层次结构, lb1对象可以是类型X ,没有成员y

U上限:必须至少为U 什么U有,你可以使用。

L下限:最多可以为L (同时保持其层次结构),但是不能保证一定会。

简单来说,您无法从使用关键字“ SUPER”构造的列表中获得“ TYPE”。

的System.out.println(lb1.get(0).Y); //这是您期望的A / B类型的错误

我猜,以下应该起作用

的System.out.println(((A)(lb1.get(0)))Y);

由于您只能从此列表中删除一个对象,因此需要将其强制转换为“ TYPE”

只需更新行

((A)lb1.get(0)).y

暂无
暂无

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

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