考虑以以下内容开头的类定义class Pokemon extends Playable<Pokemon>
这与更常见的class Pokemon implements Comparable<Pokemon>
相似,后者仅对Pokemons施加了整体排序。
尽管我已经看到并编写了一段时间,但我意识到(提出问题后)至少从理论上讲,如果不小心,解析可能会存在无限循环的风险。
考虑一下:
步骤1:编译器或类加载器尝试解析(或加载)Pokemon
,但是看到它需要首先解析Playable<.>
。
步骤2:然后,编译器意识到,由于Playable
是由Pokemon
参数化的,因此需要加载或解析Pokemon
。现在我们发现自己进入了第一步,并且建立了一个永无止境的循环。
实际上,我们知道并非如此,因为它可以工作。那么如何打破周期?我的理论是,在第2步结束时,编译器或类加载器将停止并使用对Pokemon的“引用”,而不是提取Pokemon源代码。但是我对javac
或Classloaders
的了解不足以确认这一点。有人可以称重吗?
最佳答案
这类似于此声明中的“循环”:
class LinkedListNode {
private String data;
private LinkedListNode next;
...
}
为了处理
private LinkedListNode next
字段,编译器只需知道LinkedListNode
是一种类型即可。此时,它不必具有完整的类型,因为类型名称提供了足够的信息来声明该字段。同样,当您声明一个泛型类将其自身的类型引用为其继承结构的一部分时,编译器不需要完整的类型即可完成对声明的解析。