java 将本类对象声明为全局变量是报错?报错-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

java 将本类对象声明为全局变量是报错?报错

爱吃鱼的程序员 2020-06-14 18:28:12 40

偶然一次尝试中发现,如果在本类中将本类对象声明成为一个全局变量时,如果本类对象为static一切正常,但是当本类对象不为static修饰时,等到项目执行则会stackOverFlowError截图和代码如下:如果将MachineDriver driver声明为static则执行成功;这个是什么原因呢,说来也惭愧搞java也有一段时间了,还是第一次发现这种问题

 

public class startProcessDriver implements MachineDriver{

//	public static MachineDriver driver = new startProcessDriver();
	public MachineDriver driver = new startProcessDriver();
	
	public void shutDown(){

		System.out.println("shutdown");
	}
	
	public static void main(String[] args) {
		startProcessDriver start = new startProcessDriver();
		start.shutDown();
	}
}


 

Java
分享到
取消 提交回答
全部回答(1)
  • 爱吃鱼的程序员
    2020-06-14 18:28:28

    如果不声明为static那就是实例域,实例域是和对象绑定的而不是和类绑定的,这样如果你在main方法中newStartProcessDriver()的时候,在调用构造器之前会执行实例域的初始化,即就是driver=newStartProcessDriver(),此时的newStartProcessDriver()又会去初始化他自己的实例域driver,这样就一直在递归的调用构造函数,你知道函数实在栈中执行的,那么栈总是有个最大深度的,超过了最大深度就会报StackOverflow
    不声明为staic,会导致new的时候再去new一个新的对象,如此造成了死循环,于是调用栈就溢出了static域是类持有的,与具体对象无关。没有static,就是说每个实例都会持有一个该类型对象。恰好你的这个类型又是类本身,你又在初始化时默认new了一个该对象。可想而知,你第一步new了一个对象,这个对象要给自己new一个成员变量,这个成员变量又要给自己new一个成员变量,就这么无限递归下去,再大内存也扛不住。

    你应该声明static时候,不用new。

    new就会在创建实例时候重新创建自己。

    应该考虑单例模式。你这个是想做驱动的。

    如果不是static的话,创建一次实例,都会执行new<spanstyle="font-family:Consolas,'BitstreamVeraSansMono','CourierNew',Courier,monospace;font-size:14px;line-height:15.3999996185303px;background-color:#FFFFFF;">startProcessDriver()……一层层的递归下去,当然会出现<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">StackOverflow了。要么静态、要么用以下方式

    <spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">

    <preclass="brush:java;toolbar:true;auto-links:false;">publicclassStartProcessDriverimplementsMachineDriver{MachineDrivermachineDriver;publicStartProcessDriver(MachineDriver){this.machineDriver=machineDriver;}……}




    <divclass='ref'>

    引用来自“Jackson_Mu”的评论

    如果不是static的话,创建一次实例,都会执行new<spanstyle="font-family:Consolas,'BitstreamVeraSansMono','CourierNew',Courier,monospace;font-size:14px;line-height:15.3999996185303px;background-color:#FFFFFF;">startProcessDriver()……一层层的递归下去,当然会出现<spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">StackOverflow了。要么静态、要么用以下方式

    <spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:normal;background-color:#FFFFFF;">

    <preclass="brush:java;toolbar:true;auto-links:false;">publicclassStartProcessDriverimplementsMachineDriver{MachineDrivermachineDriver;publicStartProcessDriver(MachineDriver){this.machineDriver=machineDriver;}……}




    <divclass='ref'>

    引用来自“Shazi199”的评论

    不声明为staic,会导致new的时候再去new一个新的对象,如此造成了死循环,于是调用栈就溢出了<divclass='ref'>

    引用来自“纠结名字”的评论

    static域是类持有的,与具体对象无关。没有static,就是说每个实例都会持有一个该类型对象。恰好你的这个类型又是类本身,你又在初始化时默认new了一个该对象。可想而知,你第一步new了一个对象,这个对象要给自己new一个成员变量,这个成员变量又要给自己new一个成员变量,就这么无限递归下去,再大内存也扛不住。<divclass='ref'>

    引用来自“ihuotui”的评论

    你应该声明static时候,不用new。

    new就会在创建实例时候重新创建自己。

    应该考虑单例模式。你这个是想做驱动的。

    0 0
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

推荐文章
相似问题
推荐课程