扫码关注官方订阅号
学习是最好的投资!
public class A { A a = new A(); public static void main(String[] args) { A a = new A(); } }
上面这段代码编译成字节码在翻译回来就像下面这样:
public class A { public A(){ A a = new A();//这里重复调用了自己 } public static void main(String[] args) { A a = new A(); } }
最简单的回答应该是每次new A()时都会创建一个对象。
new A()
下面分析一下稍微详细一点的过程1.程序执行后首先进入main函数,然后第一次执行new A();2.由于没有显示的构造函数,编译器在编译的时候会生成一个无参构造函数
main
public A(){ }
3.进入上面的构造函数后先要初始化成员变量,也就是 A a = new A();4.这里就到的问题的关键,成员变量A初始化还是new A()继续调用2中的构造函数。5.接着就会重复2、3、4的步骤,直到这个线程的栈空间不够用,抛出StackOverflowError错误。
A a = new A();
A
StackOverflowError
这里还要普及一点方法调用的知识,在JVM中,每个线程都会分配一定的栈空间(非共享),这个栈空间可以是固定的可以是动态扩展的,不同的JVM这里的实现方式可以不同。线程中每执行一个方法,这个方法就会以栈帧的形式压入线程栈中。
JVM
上面出现StackOverflowError就是因为一直不断的调用构造方法,然后一直创建栈帧压入线程栈,最后栈空间不够用,导致栈溢出。
楼上两位已经解释的很清楚了,简单的说就是你为类A增加了一个自身的实例变量a,这本身没什么问题,但是你将a的初始化放在了实例初始化的过程中,这样的话只要调用一次new A()就会进去一个无限调用的循环,所以就栈溢出了。
非常明显的递归调用,而且没有结束条件,肯定就内存溢出。递归就是方法里调用方法本身,而你给出的案例特殊一点,是构造方法,原因就是这么简单。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
上面这段代码编译成字节码在翻译回来就像下面这样:
最简单的回答应该是每次
new A()时都会创建一个对象。下面分析一下稍微详细一点的过程
1.程序执行后首先进入
main函数,然后第一次执行new A();2.由于没有显示的构造函数,编译器在编译的时候会生成一个无参构造函数
3.进入上面的构造函数后先要初始化成员变量,也就是
A a = new A();4.这里就到的问题的关键,成员变量
A初始化还是new A()继续调用2中的构造函数。5.接着就会重复2、3、4的步骤,直到这个线程的栈空间不够用,抛出
StackOverflowError错误。这里还要普及一点方法调用的知识,在
JVM中,每个线程都会分配一定的栈空间(非共享),这个栈空间可以是固定的可以是动态扩展的,不同的JVM这里的实现方式可以不同。线程中每执行一个方法,这个方法就会以栈帧的形式压入线程栈中。上面出现
StackOverflowError就是因为一直不断的调用构造方法,然后一直创建栈帧压入线程栈,最后栈空间不够用,导致栈溢出。楼上两位已经解释的很清楚了,简单的说就是你为类A增加了一个自身的实例变量a,这本身没什么问题,但是你将a的初始化放在了实例初始化的过程中,这样的话只要调用一次new A()就会进去一个无限调用的循环,所以就栈溢出了。
非常明显的递归调用,而且没有结束条件,肯定就内存溢出。递归就是方法里调用方法本身,而你给出的案例特殊一点,是构造方法,原因就是这么简单。