解析 <T extends Interface<T>> 并结束潜在的无限循环

Parsing <T extends Interface<T>> and ending a potential infinite cycle

考虑以

开头的 class 定义

class Pokemon extends Playable<Pokemon>

这与更常见的 class Pokemon implements Comparable<Pokemon> 类似,它只是对 Pokemon 施加了总排序。

虽然我看到这个和写这个已经有一段时间了,但我意识到(在回答一个问题之后)至少从理论的角度来看,如果不小心的话,解析中可能存在无限循环的风险.

考虑一下:
第 1 步:编译器或 classloader 尝试解析(或加载)Pokemon,但发现它需要先解析 Playable<.>
第二步:编译器随后意识到因为PlayablePokemon参数化了,需要加载或解析Pokemon。现在我们发现自己进入了第 1 步,并且建立了一个永无止境的循环。

实际上,我们知道情况并非如此,因为它有效。那么循环是如何被打破的呢?我的理论是,在第 2 步结束时,编译器或 classloader 只是停止并使用 "reference" 到 Pokemon 而不是提取 Pokemon 源代码。但我对 javacClassloaders 的了解还不够,无法证实这一点。有人可以称重吗?

这类似于此声明中的 "loop":

class LinkedListNode {
    private String data;
    private LinkedListNode next;
    ...
}

为了处理private LinkedListNode next字段,编译器只需要知道LinkedListNode是一个类型。此时不需要完整的类型,因为类型名称提供了足够的信息来声明该字段。

类似地,当您声明一个泛型 class 并引用其自身类型作为其继承结构的一部分时,编译器不需要完整的类型来完成对声明的解析。