理解类型为erasion的java递归泛型类型定义

时间:2016-06-16 06:57:28

标签: java generics inheritance

我对这行代码非常困惑:

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

我知道什么是<T>,什么是abstract,什么是继承,但我无法总结我在这一行中看到的所有内容。

请有人用简单的话来解释这个有趣的东西意味着什么? <T><?>的问题不重复。令人困惑的是ClasName出现两次。 提前谢谢。

2 个答案:

答案 0 :(得分:2)

所以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但不会&#34;销毁&#34;通用参数,所以我们接受一个ClassName会接受,在这种情况下T extends ClassName<?>。在extends ClassName<T>中,编译器会检查这个(ClassName2} T是否符合T ClassName的要求(请记住{ {1}}的定义)ClassName,所以这显然有效。

此外,我们T extends ClassName<?>延长ClassName2<?>,所以现在您可以根据需要混合使用这两种类型:

ClassName<?>

但是,如果你愿意,请说

ClassName2<ClassName<ClassName<ClassName<?>>>> test2;
ClassName2<ClassName<ClassName2<ClassName<?>>>> test3;

(公共和抽象修饰符并不真正影响这里的通用行为),你只能拥有像

这样的东西
class ClassName3<T extends ClassName3<?>> extends ClassName<T>

,因为ClassName3<ClassName3<ClassName3<ClassName3<?>>>> test4; ClassName2<ClassName<ClassName3<ClassName3<?>>>> test5; ClassName不会继承ClassName2

答案 1 :(得分:1)

public表示该类对所有其他类都可见。
abstract表示该类无法实例化(您必须为此找到一个非抽象的子类)
inheritance是面向对象编程中的一个重要概念。阅读有关OOP的书或咨询维基百科。

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) { ... }
}
相关问题