我很困惑面对这行代码:了解Java是递归的类型抹除泛型类型定义
public abstract class ClassName<T extends ClassName<?>>{}
我知道什么是<T>
,什么是abstract
,什么是继承,但我只是不能概括我所看到的就是这一行。
请有人可以用简单的话来解释这个有趣的事情是什么意思? 不是关于<T>
和<?>
的问题的重复。令人困惑的是ClasName
出现两次。 在此先感谢。
我很困惑面对这行代码:了解Java是递归的类型抹除泛型类型定义
public abstract class ClassName<T extends ClassName<?>>{}
我知道什么是<T>
,什么是abstract
,什么是继承,但我只是不能概括我所看到的就是这一行。
请有人可以用简单的话来解释这个有趣的事情是什么意思? 不是关于<T>
和<?>
的问题的重复。令人困惑的是ClasName
出现两次。 在此先感谢。
所以ClassName
有一个通用的参数T
这个参数需要满足一定的要求,在这种情况下延长某种类型S
,这意味着, T
必须继承S
。现在在这种情况下有趣的是这个S
。
我们有S
为ClassName<?>
,所以T
必须用通配符从ClassName
继承。对于通配符aka问号,请查看Michael Markidis在对您的问题发表评论时给出的链接。
真正的乐趣是现在,这个定义
public abstract class ClassName<T extends ClassName<?>>
允许递归泛型类型确定指标。所以,你可以有类似
ClassName<ClassName<ClassName<ClassName<?>>>> test;
不管什么是值得:)
编辑:鉴于
ClassName2<T extends ClassName<?>> extends ClassName<T>
多数民众赞成在比较相对容易。我们希望继承ClassName
但不能“销毁”泛型参数,所以我们接受一个ClassName
会接受,在这种情况下为T extends ClassName<?>
。在extends ClassName<T>
编译器检查这个(即ClassName2
的)T
是否符合ClassName
的T
,这是要求(记住ClassName
的定义)T extends ClassName<?>
,所以这显然有效。
另外,我们有ClassName2<?>
延伸ClassName<?>
,所以现在你可以混合使用,但是你想将两种类型:
ClassName2<ClassName<ClassName<ClassName<?>>>> test2;
ClassName2<ClassName<ClassName2<ClassName<?>>>> test3;
但是,如果你会,说
class ClassName3<T extends ClassName3<?>> extends ClassName<T>
(公和abstrac修饰符并不真正影响这里的通用行为),你只能拥有像
ClassName3<ClassName3<ClassName3<ClassName3<?>>>> test4;
ClassName2<ClassName<ClassName3<ClassName3<?>>>> test5;
自ClassName
和ClassName2
不继承ClassName3
。
public
表示该类对所有其他类都可见。
abstract
意味着该类不能实例化(您必须为此找到一个非抽象的子类)
inheritance
是面向对象编程中的一个重要概念。阅读关于面向对象的书或咨询维基百科。
T extends ClassName<?>
表示在类型参数T
上存在上限,因此T
需要是ClassName<?>
的子类。 ?
表示无限类型参数。
我会提供一个更有意义的例子,可以使它更容易理解使用有界递归类型参数的概念。假设你有一个类Thingy
。您希望Thingy
的所有子类都具有可比性,但仅适用于相同的子类。也就是说你想钉相媲美的指甲,但没有自行车:
interface Thingy<T extends Thingy<T>> extends Comparable<T> {}
class Nail implements Thingy<Nail> {
@Override public int compareTo(Nail o) { ... }
}
class Bike implements Thingy<Bike> {
@Override public int compareTo(Bike o) { ... }
}
令人困惑的是抽象类如何才能继承它的类型类?这听起来像是无休止的故事 –
不是。你只需要看看子类的外观如何...'类Foo扩展ClassName
@Evgeniy Mishustin通过Type Erasure ,泛型的重要概念。是的,这个永无止境的故事是很酷的,看到我的答案。甚至没有知道这种可能性之前:-D – GreenThor
哦,我不敢听到在这个上下文中的“递归”)))其实我下一个类有公共抽象类ClassName2>扩展ClassName 。 –
@Evgeniy Mishustin根据您的评论扩展了我的答案:-)我很高兴Type Erasure提示可以帮助您 – GreenThor