<?扩展类>和<?超级类>Java中 - 为什么它以这种方式工作?
又一个新手,试图理解Java泛型。我发现,我已经观察了所有主题,但我仍然有很大的问题。你能不能给我解释一下以下几点:
-
<? extends SomeClass>
意味着,即“任何类型”,并且意味着,此任何类型只能是 的子类。好吧,我写了两个初级课程:?
extends SomeClass
SomeClass
abstract class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person {
public Student(String name) {
super(name);
}
}
类将在我们的示例中。,确切地说。然后,我正在尝试将新学生添加到ArrayList,正如我从上面所写的内容中了解到的那样,它适用于所有类,这些类是Person的子类:Student
?
? extends Person
Student clarissa = new Student("Clarissa Starling");
List<? extends Person> list = new ArrayList<>();
list.add(clarissa); //Does not compile
日食 说:
“方法 add(capture#3-of ?扩展人员)类型列表中不适用于参数(学生)”
当我们声明 List、由 、参数化并精确扩展类时,class 怎么可能不适用?Student
<? extends Person>
Student
Person
但是,以下代码:
List<? super Person> list = new ArrayList<>();
list.add(clarissa);
编译并运行良好(传递给println方法,向我展示了调用的正确结果)。据我所知,这意味着我可以将任何类型传递给此列表,即我们类的超类型(在我们的例子中,它只是类)。但是我们看到,与逻辑相反,我们可以很容易地将子类学生添加到我们的!list.get(0)
toString
List<? super Person>
Person
Object
List<? super Person>
好吧,抛开我们的情绪,让我们看看,克拉丽莎·斯塔林(Clarissa Starling)在我们的收藏中会发生什么。让我们把我们的类,并添加几个方法:Student
class Student extends Person {
private int grant;
public Student(String name) {
super(name);
}
public void setGrant(int grant) {
this.grant = grant;
}
public int getGrant() {
return this.grant;
}
}
然后,我们将一个对象(例如,我们的对象“clarissa”)从这个更新的类(例如,我们的对象“clarissa”)实例化)传递给 。这样做,我们的意思是,我们可以将子类存储在其超类的集合中。也许,我不理解一些基础的想法,但在这个阶段,我看不出将子类添加到其超类的集合与将对象“clarissa”的引用分配给可变的,类型化的Person之间有任何区别。当我们想要使用超类变量处理其中一个时,我们对可调用方法有相同的简化。那么,为什么不以相同的方式工作,其中相反地工作呢?List<? extends Person>
List<? extends SomeClass>
List<? super SomeClass>
- 我不明白(或,或JLS适当部分的任何其他字母)和之间的基本区别。两者都是类型持有者,那么为什么我们有两个“关键字”(这个符号不是关键字,我只是用这个词来强调Java语言中两个符号的重义)用于相同的目的?
<T>
<E>
<?>
<T>
<?>