2 sinat 28050007 sinat_28050007 于 2016.03.09 14:46 提问

java单例初始化为什么不一直循环初始化的问题

程序很简单:

 public class User {
    static User u=new User();
    public static User getUser(){
        return u;
    }

    User01 u01=User01.getUser01();

    public User(){
        System.out.println("User新建一次");
    }

}

public class User01 {
     static User01 u01=new User01();
    public static User01 getUser01(){
        return u01;
    }

    User u=User.getUser();

    public User01(){
        System.out.println("User01新建一次");
    }
}

public class Test {
    public static void main(String[] args) {
        User u=User.getUser();
        User01 u01=User01.getUser01();
            System.out.println(u.u01);
        System.out.println(u01.u);
    }
}

接着我运行test的main函数,得到结果如下:
User01新建一次
User新建一次
User01@40ac8360
null

为什么会有这个结果?为什么没有循环地一直初始化下去呢?为什么最后的u01.u是空指针呢?跪求大神解释一下整个程序运行过程中到底发生了什么!

4个回答

menghuanmusic
menghuanmusic   2016.03.09 14:59
已采纳

因为你把对象的初始化以静态的方式写了,所以不会每次调用都去new一下那个对象。

menghuanmusic
menghuanmusic 回复sinat_28050007: 这个涉及到了类的初始化顺序,其顺序是(静态变量、静态初始化块)>(变量、初始化块)>构造器,User类中调用构造方法前,已经提前调用了User01 u01=User01.getUser01();这句代码,因此会导致User01先输出。
接近 2 年之前 回复
menghuanmusic
menghuanmusic 回复sinat_28050007: 因为User01 u01=User01.getUser01();这句。你把这个注释了。就好了。
接近 2 年之前 回复
sinat_28050007
sinat_28050007 那为什么先输出的是User01新建一次呢?不应该是User新建一次先输出么?
接近 2 年之前 回复
xionglangs
xionglangs   Rxr 2016.03.09 14:50

你这个是单例,不是吧,单例最起码要构造发放私有法。

sinat_28050007
sinat_28050007 是要私有化,我这只是简化问题
接近 2 年之前 回复
xionglangs
xionglangs 构造方法
接近 2 年之前 回复
zhengnan110
zhengnan110   2016.03.09 23:12

user在加载的过程中进入user01,所以user01中的u是null。
先输出user01的原因是:在使用user类是会优先加载静态成员,你的静态成员new了user对象,新建对象后首先会加载其成员变量,然后才进入构造方法。所以new user01执行完了,才会执行user的构造方法。

sinat_28050007
sinat_28050007 user在加载的过程中进入user01,所以user01中的u是null。这个因为所以有点唐突~~~~
接近 2 年之前 回复
sinat_28050007
sinat_28050007   2016.05.06 00:14

关于这个问题的回答,我的博客的“java初始化小结讲得很清楚”

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!