2016-06-16 41 views
1

我很困惑面对这行代码:了解Java是递归的类型抹除泛型类型定义

public abstract class ClassName<T extends ClassName<?>>{} 

我知道什么是<T>,什么是abstract,什么是继承,但我只是不能概括我所看到的就是这一行。

请有人可以用简单的话来解释这个有趣的事情是什么意思? 不是关于<T><?>的问题的重复。令人困惑的是ClasName出现两次。 在此先感谢。

回答

0

所以ClassName有一个通用的参数T这个参数需要满足一定的要求,在这种情况下延长某种类型S,这意味着, T必须继承S。现在在这种情况下有趣的是这个S

我们有SClassName<?>,所以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是否符合ClassNameT,这是要求(记住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; 

ClassNameClassName2不继承ClassName3

+0

哦,我不敢听到在这个上下文中的“递归”)))其实我下一个类有公共抽象类ClassName2 >扩展ClassName 。 –

+0

@Evgeniy Mishustin根据您的评论扩展了我的答案:-)我很高兴Type Erasure提示可以帮助您 – GreenThor

1

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) { ... } 
} 
+0

令人困惑的是抽象类如何才能继承它的类型类?这听起来像是无休止的故事 –

+0

不是。你只需要看看子类的外观如何...'类Foo扩展ClassName {}'和'class Bar extends ClassName {}'可以是两个这样的子类...... –

+0

@Evgeniy Mishustin通过Type Erasure ,泛型的重要概念。是的,这个永无止境的故事是很酷的,看到我的答案。甚至没有知道这种可能性之前:-D – GreenThor