还有一个新手,试图理解Java Generics。 我发现,我观察了所有主题,但我仍然有很多问题。 能否请你解释一下以下事项:
<? 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);
}
}
类 Student
将会 ?
在我们的例子中。 ? extends Person
,确切地说。
然后我正在尝试将新学生添加到ArrayList,正如我从上面所写的那样,它应用所有类,它们是Person的子类:
Student clarissa = new Student("Clarissa Starling");
List<? extends Person> list = new ArrayList<>();
list.add(clarissa); //Does not compile
Eclipse说:
“该方法在类型中添加(捕获#3-of?extends Person) 列表不适用于 论据(学生)“
怎么可以上课 Student
当我们声明List,参数化时,不适用 <? extends Person>
,和 Student
完全扩展了类 Person
?
不过,以下代码:
List<? super Person> list = new ArrayList<>();
list.add(clarissa);
编译并运作良好(list.get(0)
,传递给println方法,向我展示了正确的结果 toString
调用)。
我认为, List<? super Person>
意思是,我可以传递给这个列表任何类型,这是我们的超级类型 Person
类(在我们的例子中是 Object
仅限课程)。但我们看到,与逻辑相反,我们可以轻松地将子类Student添加到我们的 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”)实例化到 List<? extends Person>
。这样做,我们的意思是,我们可以将子类存储在其超类的集合中。也许,我不了解一些基本的想法,但在这个阶段我没有看到将子类添加到其超类集合和将对象“clarissa”的引用分配给变量,类型Person之间没有任何区别。当我们想要使用我们的超类变量来处理其中一个方法时,我们可以减少可调用的方法。所以为什么 List<? extends SomeClass>
不同的方式,其中 List<? super SomeClass>
相反的工作?
- 我不明白两者之间的根本区别
<T>
(要么<E>
或来自JLS适当部分的任何其他信件)和<?>
。都<T>
和<?>
是 typeholders那么为什么我们有两个“关键字”(这个符号不是关键字,我只是用这个词来强调Java语言中两个符号的重要含义)是出于同样的目的?