Javagenerics和inheritance递归

我遇到了以下使用generics和inheritance的Java代码。 我真的不明白以下代码片段的作用:

class A<B extends A> { ... } 

这段代码有什么作用?

(我从MapDB中的DBMaker那里得到了这个)

这几乎是清楚的,问题实际上分为两部分:

1)为什么B extends A

2)为什么A内部B extends A具有通用类型B

这些部分的答案将是:

1)在特定示例中,此类( A )是构建器类(称为DBMaker ),因此其大多数方法返回某种类型,这会扩展此构建器的类类型。 这解释了为什么B应该扩展A类。

2)但是,实际上,如果我们将隐藏第二部分...extends A ,我们将只收到class A 。 因此A具有B类型的变量。 这就是为什么在...extends A A被标记为具有类型变量B类型A

这告诉A 需要派生定义才能做一些工作:

 public abstract class A> { protected T instance; T getOne() { return instance; } } public class B extends A { public B() { instance = this; } } public static void test() { B b = new B(); b.getOne(); } 

这在接口定义中最常用,其中一个想要显式地使用在返回类型或参数中实现接口的类的实例,而不是接口本身:

 public interface TimeSeries> { T join(T ts); } public class DoubleTimeSeries implements TimeSeries { @Override public DoubleTimeSeries join(DoubleTimeSeries ts) { return null; } } 

所以我做了一些测试来解决这个问题,这是我的测试用例,看看如何使用这样的通用案例:

 public class A> { int x = 10; B test; void printX() { System.out.println(x); } void setB(B b) { test = b; } void printB() { System.out.println(test); } } public class B extends A { } public class Run { public static void main(String[] args) { A test = new A(); B myB = new B(); test.printX(); test.setB(myB); test.printB(); myB.printB(); } } 

我希望代码可能是自我解释的。 如果不发表评论,我会尝试解释发生了什么。 查看最后一行myB.printB(),这里我们将得到一个null,因为尚未为myB设置B,但仅用于测试。 这表明我们可以无限递归到A中的B类(对于那个问题,在B内)。

我们可以说:

 myB.test.printB(); 

这将得到一个错误(空指针),但表明我们现在可以从B中访问A类中的测试,并且我们可以根据需要递归到我们想要的尽可能多的情况。 所以A类的函数作为无限多B类的包装器。 这有意义吗?

这使得在定义方法返回类型时更容易,例如:

 class A> { public B getMe(){ return (B) this; } } 

这告诉Java编译器你在getMe()方法中返回类A的子类。

 class C extends A { } C c = new C(); c.getMe(); //returns C