我一直想知道是否有可能在Java中构建一个自递归类。显然,它是。
public class Void {
static Inher i = new Inher();
static {
System.out.println("ok");
}
public static void main (String... args) {}
private static class Inher extends Void {}
}
然而,我预计堆栈溢出或其他一些失败,我得到的只是一个" ok"在终端。我错过了什么或出错了什么?如何整理它并获得适当的溢出?如果不是太广泛,你对这件事有什么想法吗?
小说明
我希望这段代码能够永远地在内部类中复制基本类,然后是内部类的内部类,依此类推。在某些时候,结构会比内存大。那是我失败的意图。
答案 0 :(得分:1)
在其他步骤中,编译器以这种方式工作(简化):
在类型检查期间,编译器将检查类型是否匹配并存在;在代码生成期间,它将创建包含用户定义类列表的VMT。
解析步骤只执行一次并以递归方式工作,但它不会按照您预期的方式工作;它将在这里做的是它将看到类Void
并将其添加到类列表中,然后它将检查内部并查看Inher
。它看到Inher
扩展Void
,并且可以从当前范围访问Void
;因此,它在VMT中添加了这个新类。
如果您在任何时候创建了Inher
的实例,那么它将验证您是否属于Void
函数的范围。但是编译器不执行递归检查,因为它不会返回检查先前的类,并递归地生成将溢出的VMT。它根据当前的背景单独处理它们。这就是编译成功的原因,因为它只是范围和类型检查的问题。
请注意,Inher
是一个类声明,而不是实例。如果您在Void
类中创建了一个Inher
类的成员,Inher
扩展Void
,那么您可能会遇到编译失败或堆栈溢出,因为Void
类的每次分配都会创建一个新的Inher
,它本身会分配一个新的draw_layer ()
,依此类推。但是在这里,你只是定义一个类,这样的操作在任何时候都不需要递归构造;因此编译。
执行时,它是一样的;堆栈溢出的唯一方法是存在一些递归分配代码;但是类定义不需要任何已分配的内存,除了在代码生成步骤中成功构建的VMT。所以不会出现任何例外。