首页 新闻 会员 周边

java的一个问题,看下下面的程序为啥a是1,b是0呢?

0
悬赏园豆:5 [已解决问题] 解决于 2013-07-30 14:37

public class Singleton {

 public static Singleton singleton = new Singleton(); 
    public static int a; 
    public static int b = 0;
    private Singleton() { 
         super(); 
         a++; 
         b++; 
     } 
    public static Singleton GetInstence() { 
         return singleton; 
     } 
   
    public static void main(String[] args) { 
         Singleton mysingleton = Singleton.GetInstence(); 
         System.out.println(mysingleton.a); 
         System.out.println(mysingleton.b); 
     } 
}

huazhiliange的主页 huazhiliange | 菜鸟二级 | 园豆:203
提问于:2013-07-30 11:59
< >
分享
最佳答案
0

1、public static Singleton singleton = new Singleton(); 这句代码把最原始的a,没赋值系统默认为0,通过a++赋值为1,b通过b++赋值为1

2、public static int a; 初始化a,因为a没被赋值则维持原来的1

3、public static int b = 0;初始化b,因为有赋值则,b的值由1改为0

收获园豆:3
xiao3er | 菜鸟二级 |园豆:207 | 2013-07-30 12:53
其他回答(3)
0

JAVA字节码查看,a的初始化在构造函数中,b是在static中的,详细参考如下:

public class Main {
public static Main singleton = new Main();
public static int a;
public static int b = 0;
public int aa;
public int bb = 0;
private Main() {
super();
a++;
b++;

aa++;
bb++;
}

D:\>"C:\Program Files\Java\jdk1.6.0_43\bin\javap.exe" -classpath c:\ -c Main
Compiled from "Main.java"
public class Main extends java.lang.Object{
public static Main singleton;

public static int a;

public static int b;

public int aa;

public int bb;

public static Main GetInstence();
Code:
0: getstatic #6; //Field singleton:LMain;
3: areturn

public static void main(java.lang.String[]);
Code:
0: invokestatic #7; //Method GetInstence:()LMain;
3: astore_1
4: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
7: aload_1
8: pop
9: getstatic #3; //Field a:I
12: invokevirtual #9; //Method java/io/PrintStream.println:(I)V
15: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: pop
20: getstatic #4; //Field b:I
23: invokevirtual #9; //Method java/io/PrintStream.println:(I)V
26: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: getfield #5; //Field aa:I
33: invokevirtual #9; //Method java/io/PrintStream.println:(I)V
36: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
39: aload_1
40: getfield #2; //Field bb:I
43: invokevirtual #9; //Method java/io/PrintStream.println:(I)V
46: return

static {};
Code:
0: new #10; //class Main
3: dup
4: invokespecial #11; //Method "<init>":()V
7: putstatic #6; //Field singleton:LMain;
10: iconst_0
11: putstatic #4; //Field b:I
14: return

}

2012 | 园豆:21230 (高人七级) | 2013-07-30 13:03
0

要明白static的作用,暂且把它作为c语言包里卖弄的全局变量,所以要知道创建单个实例无法改变变量,在变量声明中,a尚未赋值,b已赋值为0,所以在你主方法里面无法改变,至于a在super被赋值,相当于已经在内存中赋值了,随后也不可改变,所以a=1,b=0

收获园豆:2
江边流客 | 园豆:5 (初学一级) | 2013-07-30 13:38

a应该不是在super中被赋值的吧,我把super去掉,也是一样的结果。

支持(0) 反对(0) huazhiliange | 园豆:203 (菜鸟二级) | 2013-07-30 14:34
0

你这个问题可以用一句话回答!

切记:如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问。

解答:你的a 没有初始化,而你的b初始化为0;

Singleton mysingleton = Singleton.GetInstence(); 

上面的这句话的意思就是调用静态方法new 的Object 而已!

用这句话:如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问。

显然而在静态new之前,你的a,b已经在内存之中,只不过,a没有初始化,而b初始化了!

其实你的mysingleton.a值指向的是构造器赋值后的,而mysingleton.b指向的就是默认初始化后的!

 

不行你可以初始化a=0看看a输出是多少!固然也是0  

 

 

 

 

Beyond-bit | 园豆:2885 (老鸟四级) | 2013-07-30 14:39

哥哥你结贴有点早了!

支持(0) 反对(0) Beyond-bit | 园豆:2885 (老鸟四级) | 2013-07-30 14:39

啊,是我理解错啦?我以为

Singleton mysingleton = Singleton.GetInstence(); 

这句new一个对象后,就会调用构造方法,将a和b都设置为1,b最后才赋值为0的。原来是b的值没有变化,a的值是通过构造器赋值的啊。   那这样的话:     

System.out.println(mysingleton.a);    //这句a通过构造器赋值为1
System.out.println(mysingleton.b);   //为啥b不会通过构造器赋值,而是指向默认初始化的呢

支持(0) 反对(0) huazhiliange | 园豆:203 (菜鸟二级) | 2013-07-31 16:57

@huazhiliange: 

你都接结贴了!分都散了,我不掺和了!

一句话:如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问。

意思就是你调用的是 new之前的,声明的static 变量!

支持(0) 反对(0) Beyond-bit | 园豆:2885 (老鸟四级) | 2013-07-31 17:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册