简体   繁体   English

Java上的通配符和子类型

[英]Wildcards and Subtyping on Java

I just started studying Wildcards and Subtyping on Java and try to test what I learn. 我刚刚开始研究Java上的通配符和子类型,并尝试测试我所学到的东西。

Suppose: 假设:

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

In main: 在主要方面:

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?

I don't understand why I cannot access the member y using Lower Bounded Wildcards while it is possible using Upper Bounds Wildcards. 我不明白为什么我无法使用“下界通配符”来访问成员y,而有可能使用“上界通配符”。 Am I missing something? 我想念什么吗?

Consider 考虑

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

List<? super B> lb1 = la1;

Now, the objects in lb1 could be completely unrelated to A and B as long as they implemented X . 现在,只要lb1的对象实现了X ,它们就可能与AB完全无关。 There's no way for the compiler to know that lb1.get(0) has a member y . 编译器无法知道lb1.get(0)具有成员y

A more "concrete" example: 一个更“具体”的例子:

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

With this hierarchy objects in lb1 could be of type X which has no member y . 使用此层次结构, lb1对象可以是类型X ,没有成员y

Upper bound of U : Has to be at least a U . U上限:必须至少为U Anything U has, you can use. 什么U有,你可以使用。

Lower bound of L : Can be at most L (while staying in its hierarchy), but there's no guarantee that it will be. L下限:最多可以为L (同时保持其层次结构),但是不能保证一定会。

In simpler words, you cannot get 'TYPE' from a list which is constructed using keyword 'SUPER'.. 简单来说,您无法从使用关键字“ SUPER”构造的列表中获得“ TYPE”。

System.out.println(lb1.get(0).y); 的System.out.println(lb1.get(0).Y); // This wrong as you are expecting type A / B //这是您期望的A / B类型的错误

I guess, the following should work 我猜,以下应该起作用

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

As you can only get an OBJECT out of this list... you need to cast it to get your 'TYPE' 由于您只能从此列表中删除一个对象,因此需要将其强制转换为“ TYPE”

只需更新行

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

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

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