类加载顺序

luqing414 2009-02-16 11:12:49
刚看到一个帖子有这样一个程序:

public class MyMain {
public static void main(String[] args){
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1="+obj.counter1);
System.out.println("obj.counter2="+obj.counter2);
System.out.println("obj.counter3="+obj.counter3);
}
}

class Singleton{
private static Singleton obj = new Singleton();
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;

private Singleton(){
counter1++;

counter2++;

counter3++;

}

public static Singleton getInstance(){

return obj;
}

}



结果为:
obj.counter1=100
obj.counter2=10
obj.counter3=1

但如果换下:

public class MyMain {
public static void main(String[] args){
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1="+obj.counter1);
System.out.println("obj.counter2="+obj.counter2);
System.out.println("obj.counter3="+obj.counter3);
}
}

class Singleton{

public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
private static Singleton obj = new Singleton();
private Singleton(){
counter1++;

counter2++;

counter3++;

}

public static Singleton getInstance(){

return obj;
}

}


结果则为:
obj.counter1=101
obj.counter2=11
obj.counter3=1

我有点糊涂了,生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化,请高手解释下这2个程序结果与原因
...全文
523 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Fish3812 2009-08-09
  • 打赏
  • 举报
回复
Java 虚拟机会先把类中所有的变量名声明,然后才会按顺序赋值
zhangpeixv 2009-02-16
  • 打赏
  • 举报
回复
先对静态变量初始化,然后再是函数
构造函数默认就是静态static的
njnu_zhoubo 2009-02-16
  • 打赏
  • 举报
回复
顶楼上,因为构造函数和变量都是静态的,所以按顺序来的,你的两个顺序不一样,因此结果不一样,跟构造函数和静态变量的执行顺序没有关系,因为你现在用的是sigleton模式,所以构造函数为静态的。如果在普通的类里,肯定是先初始化静态变量,然后在运行期执行构造函数 。
chiphuo 2009-02-16
  • 打赏
  • 举报
回复
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=" + obj.counter1);
System.out.println("obj.counter2=" + obj.counter2);
System.out.println("obj.counter3=" + obj.counter3);
}
}

class Singleton {

private static Singleton obj = new Singleton();

public static int counter1 = print(100, "counter1");

public static int counter2 = print(10, "counter2");

public static int counter3 = print(0, "counter3");



private Singleton() {

System.out.println("Singleton");

counter1++;
System.out.println("Inner Constructor counter1: " + counter1);
counter2++;
System.out.println("Inner Constructor counter2: " + counter2);
counter3++;
System.out.println("Inner Constructor counter3: " + counter3);
}

public static Singleton getInstance() {

return obj;
}

public static int print(int x, String s) {
System.out.println("Outer Constructor " + s + ": " + x);
return x;
}

}

Singleton
Inner Constructor counter1: 1
Inner Constructor counter2: 1
Inner Constructor counter3: 1
Outer Constructor counter1: 100
Outer Constructor counter2: 10
Outer Constructor counter3: 0
obj.counter1=100
obj.counter2=10
obj.counter3=0


public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=" + obj.counter1);
System.out.println("obj.counter2=" + obj.counter2);
System.out.println("obj.counter3=" + obj.counter3);
}
}

class Singleton {

public static int counter1 = print(100, "counter1");

public static int counter2 = print(10, "counter2");

public static int counter3 = print(0, "counter3");

private static Singleton obj = new Singleton();

private Singleton() {

System.out.println("Singleton");

counter1++;
System.out.println("Inner Constructor counter1: " + counter1);
counter2++;
System.out.println("Inner Constructor counter2: " + counter2);
counter3++;
System.out.println("Inner Constructor counter3: " + counter3);
}

public static Singleton getInstance() {

return obj;
}

public static int print(int x, String s) {
System.out.println("Outer Constructor " + s + ": " + x);
return x;
}

}

Outer Constructor counter1: 100
Outer Constructor counter2: 10
Outer Constructor counter3: 0
Singleton
Inner Constructor counter1: 101
Inner Constructor counter2: 11
Inner Constructor counter3: 1
obj.counter1=101
obj.counter2=11
obj.counter3=1


我改了一下,楼主看一下结果,应该就知道运行的顺序了。
believefym 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 luqing414 的回复:]
引用 3 楼 believefym 的回复:
引用楼主 luqing414 的帖子:
生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化

private static Singleton obj = new Singleton();
public static int counter1=100;

你问的问题不在点上,就是按顺序执行么,这几个static的变量, obj需要调构造函数,总不可能绕过去先初始化几个static int变量吧

不好意思,不大明白您的意思,如果是按顺序执行,这2个程序从…
[/Quote]

跟构造函数定义的位置有什么关系,你看调用顺序!
ty_fzpb 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 luqing414 的回复:]
引用 7 楼 frankboy_cpu 的回复:

如果有静态变量,那么先构造静态变量,如果有多个静态变量那么按顺序初始化,实际上构造函数也相当于一个静态方法。
上述Singleton obj = Singleton.getInstance(); 如果在前,则counter 1、2、3实际上并未被初始化只是被jvm
都预初始化为0,而在后的则三个变量都已被初始化,为100,10,0 所以有上述的结果

是不是这个意思,第一种情况:
Java code

private static Singleton obj = new …
[/Quote]

对了
luqing414 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 frankboy_cpu 的回复:]
如果有静态变量,那么先构造静态变量,如果有多个静态变量那么按顺序初始化,实际上构造函数也相当于一个静态方法。
上述Singleton obj = Singleton.getInstance(); 如果在前,则counter 1、2、3实际上并未被初始化只是被jvm
都预初始化为0,而在后的则三个变量都已被初始化,为100,10,0 所以有上述的结果
[/Quote]
是不是这个意思,第一种情况:

private static Singleton obj = new Singleton();
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;


先执行private static Singleton obj = new Singleton();,完后跳到构造函数执行,返回来再执行
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;

而第二种情况:

public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
private static Singleton obj = new Singleton();

先执行
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
再执行private static Singleton obj = new Singleton();
最后才调到构造函数?
ty_fzpb 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 luqing414 的回复:]
引用 2 楼 ty_fzpb 的回复:

程序一:
因为属性都是静态的,所以会依次初始化……
1.初始化属性obj ,在此之前属性counter1、 counter2、counter3都未显示初始化 故都为0;之后都为1
2.再依次初始化counter1、 counter2

程序二的结果就可想而知了

这个执行顺序我明白,我不明白的是为什么这2个程序执行顺序不一样
[/Quote]

因为属性都是静态的,所以会依次初始化……
混沌君子 2009-02-16
  • 打赏
  • 举报
回复
如果有静态变量,那么先构造静态变量,如果有多个静态变量那么按顺序初始化,实际上构造函数也相当于一个静态方法。
上述Singleton obj = Singleton.getInstance(); 如果在前,则counter 1、2、3实际上并未被初始化只是被jvm
都预初始化为0,而在后的则三个变量都已被初始化,为100,10,0 所以有上述的结果
爱摸鱼de老邪 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 believefym 的回复:]
就是赋值的顺序问题
第一个赋值之后又被重新置回去了
第二个相反
[/Quote]
顶~
luqing414 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ty_fzpb 的回复:]
程序一:
因为属性都是静态的,所以会依次初始化……
1.初始化属性obj ,在此之前属性counter1、 counter2、counter3都未显示初始化 故都为0;之后都为1
2.再依次初始化counter1、 counter2

程序二的结果就可想而知了
[/Quote]
这个执行顺序我明白,我不明白的是为什么这2个程序执行顺序不一样
luqing414 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 believefym 的回复:]
引用楼主 luqing414 的帖子:
生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化

private static Singleton obj = new Singleton();
public static int counter1=100;

你问的问题不在点上,就是按顺序执行么,这几个static的变量, obj需要调构造函数,总不可能绕过去先初始化几个static int变量吧
[/Quote]
不好意思,不大明白您的意思,如果是按顺序执行,这2个程序从位置上来说,都是静态变量在构造函数前面,那怎么结果不一样呢
believefym 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用楼主 luqing414 的帖子:]
生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化[/Quote]

private static Singleton obj = new Singleton();
public static int counter1=100;

你问的问题不在点上,就是按顺序执行么,这几个static的变量, obj需要调构造函数,总不可能绕过去先初始化几个static int变量吧
ty_fzpb 2009-02-16
  • 打赏
  • 举报
回复
程序一:
因为属性都是静态的,所以会依次初始化……
1.初始化属性obj ,在此之前属性counter1、 counter2、counter3都未显示初始化 故都为0;之后都为1
2.再依次初始化counter1、 counter2

程序二的结果就可想而知了
believefym 2009-02-16
  • 打赏
  • 举报
回复
就是赋值的顺序问题
第一个赋值之后又被重新置回去了
第二个相反
jinchishuxue 2009-02-16
  • 打赏
  • 举报
回复

其实,这个是一个“数据(当然也包括构造函数)初始化问题”!

具体的顺序是这样的:

对于没有继承的情形----》

先初始化静态的成员变量(域),然后再初始化非静态的成员变量,然后才是构造方法。若是有几个静态
变量(或几个非静态的变量),不论其在什么位置(比如说有的在构造器之后),都是按顺序初始化的。

对于有继承的情形------》

上面的东西不变,只是在调用导出类的构造方法时,系统会先主动的向上到基类,一直到最顶层,然后一层层按上面没有继承的情形来进行初始化。


至于上面提出的问题,是几个静态成员变量的初始化问题,当然是按照顺序来初始化了!

要想很好的理解数据初始化,不妨参考《THINKING IN JAVA》第四版,P94-98,P159,P163.
海盗船长4.0 2009-02-16
  • 打赏
  • 举报
回复
第一个代码块里counter3为什么是1而不是0啊
chc314 2009-02-16
  • 打赏
  • 举报
回复
一句话,顺序赋值,第一个被覆盖,第二个没有啊,支持12楼的
ZiSheng 2009-02-16
  • 打赏
  • 举报
回复
把你的域变量的声明和域的静态初始化分开来,一切一目了然。
joking520 2009-02-16
  • 打赏
  • 举报
回复

简单的说区别:第一个是先运算再赋值;第二个是先赋值再运算。
加载更多回复(2)

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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