自我递归类拼图

时间:2016-07-31 01:22:28

标签: java recursion

我一直想知道是否有可能在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"在终端。我错过了什么或出错了什么?如何整理它并获得适当的溢出?如果不是太广泛,你对这件事有什么想法吗?

小说明

我希望这段代码能够永远地在内部类中复制基本类,然后是内部类的内部类,依此类推。在某些时候,结构会比内存大。那是我失败的意图。

1 个答案:

答案 0 :(得分:1)

在其他步骤中,编译器以这种方式工作(简化):

  • 代码的词汇分析
  • 解析代码并构建抽象语法树
  • 类型检查
  • 杂项优化
  • 生成机器代码(本例中为Java字节码)

在类型检查期间,编译器将检查类型是否匹配并存在;在代码生成期间,它将创建包含用户定义类列表的VMT

解析步骤只执行一次并以递归方式工作,但它不会按照您预期的方式工作;它将在这里做的是它将看到类Void并将其添加到类列表中,然后它将检查内部并查看Inher。它看到Inher扩展Void,并且可以从当前范围访问Void;因此,它在VMT中添加了这个新类。

如果您在任何时候创建了Inher的实例,那么它将验证您是否属于Void函数的范围。但是编译器不执行递归检查,因为它不会返回检查先前的类,并递归地生成将溢出的VMT。它根据当前的背景单独处理它们。这就是编译成功的原因,因为它只是范围和类型检查的问题。

请注意,Inher是一个类声明,而不是实例。如果您在Void类中创建了一个Inher类的成员,Inher扩展Void,那么您可能会遇到编译失败或堆栈溢出,因为Void类的每次分配都会创建一个新的Inher,它本身会分配一个新的draw_layer (),依此类推。但是在这里,你只是定义一个类,这样的操作在任何时候都不需要递归构造;因此编译。

执行时,它是一样的;堆栈溢出的唯一方法是存在一些递归分配代码;但是类定义不需要任何已分配的内存,除了在代码生成步骤中成功构建的VMT。所以不会出现任何例外。