Я только начал изучать подстановочные знаки и подтипы на 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
могут быть полностью не связаны с A
и B
если они реализуют X
Компилятор не знает, что 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
.
В более простых словах вы не можете получить "ТИП" из списка, который создается с использованием ключевого слова "SUPER"..
System.out.println(lb1.get(0).y); // Это неправильно, поскольку вы ожидаете тип A/B
Я думаю, следующее должно работать
System.out.println(. ((А) (lb1.get(0))) у);
Поскольку вы можете получить OBJECT только из этого списка... вам нужно бросить его, чтобы получить свой "ТИП",
Верхняя граница U
: должна быть как минимум U
Все, что U
имеет, вы можете использовать.
Нижняя граница L
: может быть не более L
(оставаясь в ее иерархии), но нет никакой гарантии, что это будет.
Просто обновить строку
((A)lb1.get(0)).y