记一次jvm类加载相关的问题

今天同学问了一个问题:为什么类的static引用可以指向一个自己的类实例。

所以我们先做个实验,看一下如果不是static的引用会发生什么

记一次jvm类加载相关的问题

发生了栈溢出。

那么如果是static引用呢?

记一次jvm类加载相关的问题

可以看到,程序没有问题。

翻看了周志明先生的《深入理解Java虚拟机》,我似乎找到了答案。

记一次jvm类加载相关的问题

记一次jvm类加载相关的问题

总结一下。
不是静态的类成员变量,在对象实例化的时候随对象一起分配在Java堆中。
那么类的成员变量,在准备阶段就会分配内存,在初始化阶段就会执行static语句。

那么回到这个问题。
当引用是实例变量时,引用在实例化的时候才会进行赋值,就会引发一个新的实例化,然后就递归的引发实例化,导致栈溢出了,本质是由递归造成的。
当引用是类变量的时候(static),在类加载的准备阶段就会为类变量分配内存,在初始化阶段就会执行static的语句,也就是() 方法,会实例化一个对象。而实例化的对象并没有static的成员变量,所以就直接返回了对象。