JAVA中static成员变量赋值的神奇问题

Gitar520 2012-01-11 08:17:58
1
2 class data{
3 private static final data mInstance = new data();
4 private static int mx = 0;
5 private data()
6 {
7 System.out.println("mx=" + mx);
8 mx = getVersion();
9 }
10 public static data getInstance()
11 {
12 return mInstance;
13 }
14 public int getVersion()
15 {
16 int v = 0;
17 if (v == 0)
18 {
19 v = 7;
20 }
21 return v;
22 }
23 public int getmx()
24 {
25 return mx;
26 }
27 }
28
29 class Test
30 {
31 public static void getData(StringBuffer sb)
32 {
33 sb.append("hello world ");
34 }
35 public static void main(String args[])
36 {
37 System.out.println(data.getInstance().getmx());
38 }
39 }
~
~
打印结果:
mx=0
0
这样的结果怎么得到了,求教

...全文
4354 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojiang0805 2014-04-14
  • 打赏
  • 举报
回复
谢谢,你们讲的很好的
Gitar520 2012-01-12
  • 打赏
  • 举报
回复 1
[Quote=引用 3 楼 sbios 的回复:]

其实这个问题很简单,牵扯到类加载顺序以及类中代码执行的顺序问题。
类的初始化顺序如下:
父类静态变量
父类静态块
子类静态变量
子类静态块
父类变量
父类普通块
父类构造函数(子类实例化时先要调用父类构造函数)
子类变量
子类普通块
子类构造函数

如果有多个初始化块,则按照代码先后顺序执行。
因此此问题解释如下:
1.date中的静态变量data会在类加载的时候首……
[/Quote]
这种顺序我试过,可以的!
Gitar520 2012-01-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dracularking 的回复:]

原理就是在执行此static initializer时:
private static final data mInstance = new data();

jvm已经知道初始化体中所涉及变量的类型了(感觉类型初始化早就完成了),这里就是mx被当做int型了,且被赋予了int型的默认值0

最后还会执行
private static int mx = 0;

但看来仅仅相当于m……
[/Quote]
你好象对jvm最了解,能说详细点吗?如果顺序不变,把private static int mx = 0;改为只声明private static int mx; 这样也会得到正确结果
dracularking 2012-01-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 gitar520 的回复:]

引用 2 楼 dracularking 的回复:

原理就是在执行此static initializer时:
private static final data mInstance = new data();

jvm已经知道初始化体中所涉及变量的类型了(感觉类型初始化早就完成了),这里就是mx被当做int型了,且被赋予了int型的默认值0

最后还会执行
private sta……
[/Quote]
我也不太清楚 只是通过这个案例才知道了一些
如果感兴趣可以去看深入jvm这本书
如果改成那样,mx最后就等于7了

从这里似乎可以得到一个结论:初始化中的类型初始化部分是最先完成的,都给一个对应类型的默认初始值,然后再去按顺序执行赋值操作,没有的就不执行了
qybao 2012-01-11
  • 打赏
  • 举报
回复
就是一个执行顺序的问题
3 private static final data mInstance = new data(); //这里会调用getVersion使得mx为7
4 private static int mx = 0;//但是这里又重新给mx赋值为0了
sbios 2012-01-11
  • 打赏
  • 举报
回复
其实这个问题很简单,牵扯到类加载顺序以及类中代码执行的顺序问题。
类的初始化顺序如下:
父类静态变量
父类静态块
子类静态变量
子类静态块
父类变量
父类普通块
父类构造函数(子类实例化时先要调用父类构造函数)
子类变量
子类普通块
子类构造函数

如果有多个初始化块,则按照代码先后顺序执行。
因此此问题解释如下:
1.date中的静态变量data会在类加载的时候首先初始化,因此初始化的时候调用date构造函数,将会将m赋值为7,
2.然后执行private static int mx = 0进行初始化m操作,因此此时m又成了0.
楼主可以将private static int mx = 0这句放在private static final data mInstance = new data();前面执行,结果就会不一样了。

另外楼主可以在private static final data mInstance = new data();
后面加上
static{
System.out.println("static");
}
然后执行看看初始化的先后顺序如何
dracularking 2012-01-11
  • 打赏
  • 举报
回复
原理就是在执行此static initializer时:
private static final data mInstance = new data();

jvm已经知道初始化体中所涉及变量的类型了(感觉类型初始化早就完成了),这里就是mx被当做int型了,且被赋予了int型的默认值0

最后还会执行
private static int mx = 0;

但看来仅仅相当于mx=0
赋值而已
Gitar520 2012-01-11
  • 打赏
  • 举报
回复
希望得到原理上解答

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧