1

我刚开始学习 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,而可以使用上限通配符。我错过了什么吗?

4

4 回答 4

1

考虑

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

List<? super B> lb1 = la1;

现在,里面的对象lb1可以完全不相关,A只要B他们实现了X。编译器无法知道lb1.get(0)有一个 member y

一个更“具体”的例子:

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

有了这个层次结构,对象 inlb1可以是X没有 member的类型y

于 2014-08-08T04:14:34.210 回答
0

简而言之,您无法从使用关键字“SUPER”构造的列表中获取“TYPE”。

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

我想,以下应该工作

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

因为你只能从这个列表中得到一个 OBJECT ......你需要投射它来获得你的 'TYPE'

于 2014-08-08T05:34:04.140 回答
0

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

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

于 2014-08-08T04:19:51.033 回答
-1

只需更新行

((A)lb1.get(0)).y
于 2014-08-08T05:19:12.723 回答