class Singleton {
private static Singleton s = new Singleton();
public static int a;
public static int b = 0; private Singleton() {
a++;
b++;
} public static synchronized Singleton getInstance() {
return s;
}
}public class Test {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
System.out.println("Singleton.a=" + Singleton.a);
System.out.println("Singleton.b=" + Singleton.b);
}
}
不能通过编译啊
private static Singleton s = new Singleton();
完a=1,b=1
但后面又b=0所以b是0
public static int a;
public static int b = 0;
private static Singleton s = new Singleton();
输出就是1和1
之后 执行 public static int a;
public static int b = 0;
所以 最后a=1,b=0
正解
public static int a;
public static int b = 0;
private static Singleton s = new Singleton(); 这样就ok了
private Singleton() {
a++;
b++;
}
执行后a1,b=1;然后执行:
private static Singleton s = new Singleton();
public static int a;
public static int b = 0;
这样a是1,b又被置为0了。所以你输出的是1和0。其实在你不知道程序怎么走的时候,自己打断点看一下就很清楚了。
构造函数其实是private static Singleton s = new Singleton();调用的
所以过程是这样的:
类加载,静态变量和函数一起加载,然后初始化变量
private static Singleton s = new Singleton();会调用构造函数
于是
private Singleton() {
a++;
b++;
}
接着继续初始化变量
public static int a;
public static int b = 0;
其实这一句分两步,private static Singletion s为第一步,此时a=0,b=0;new Singleton()为第二步,此时a=1,b=1;然后再public static int a;
public static int b = 0;
class A0 {
A0() {
System.out.println("父类的构造函数被调用(初始化父类)");
}
}
class A1 extends A0 {
static final int b = print1();
static {
System.out.println("静态块被执行");
}
int a = print();
{
System.out.println("非静态块被执行");
}
A1() {
System.out.println("A1 的构造函数被调用");
}
private int print() {
System.out.println("A1中非静态变量被初始化");
return 1;
}
final static int print1() {
System.out.println("A1中静态变量被初始化");
return 1;
}
}
class A2 extends A1 {
A2() {
System.out.println("A2构造函数被调用");
}
}
public class DeriveDemo {
public static void main(String[] args) {
System.out.println("这是A1类的初始化顺序");
A1 a = new A1();
System.out.println("\n这是A2类的初始化顺序");
A2 a1 = new A2();
System.out.println("\n这是A2类的初始化顺序(注意静态变量)");
A2 a2 = new A2();
System.out.println("");
System.out.println("我们还注意到静态变量被A2全盘继承下来了");
}
} 运行结果为
这是A1类的初始化顺序
A1中静态变量被初始化
静态块被执行
父类的构造函数被调用(初始化父类)
A1中非静态变量被初始化
非静态块被执行
A1 的构造函数被调用
这是A2类的初始化顺序
父类的构造函数被调用(初始化父类)
A1中非静态变量被初始化
非静态块被执行
A1 的构造函数被调用
A2构造函数被调用
这是A2类的初始化顺序(注意静态变量)
父类的构造函数被调用(初始化父类)
A1中非静态变量被初始化
非静态块被执行
A1 的构造函数被调用
A2构造函数被调用
我们还注意到静态变量被A2全盘继承下来了
Singleton.a=1
Singleton.b=0
执行顺序如下:private static Singleton s = new Singleton();被分为两步:
private static Singleton s;
执行public static int a; 给a付默认值0。
执行public static int b = 0;给b付值为0.
然后执行
s = new Singleton();
调用
private Singleton() {
a++;
b++;
}
这时候 a和b的值都为1.再执行
public static int a; 不该变a的值。
再执行
public static int b = 0;b的值变为0.
Singleton.a=1
Singleton.b=0
更正:
执行顺序如下:private static Singleton s = new Singleton();被分为两步:
private static Singleton s;
执行public static int a; 不是给a付默认值,只收集变量信息,如果不是static,则会付初始值。
执行public static int b = 0;不是给b付值为0,只收集变量信息,如果不是static,则会付值。
然后执行
s = new Singleton();
调用
private Singleton() {
a++;
b++;
}
这时候 a和b的值都为1. 再执行
public static int a; 不该变a的值。
再执行
public static int b = 0;b的值变为0
我比较认同这位楼主的看法呀
就是要自己处理呀,MYEclipse IDE都可以Debug进行打段点的,进行调试的呀!
class initialization order.
very good
class Singleton {
private static Singleton s = new Singleton();
public static int a = printf("a");
public static int b = printf("b"); private static int printf(String str){
System.out.println(str);
return 0;
}
private Singleton() {
System.out.println("constructor");
a++;
b++;
} public static synchronized Singleton getInstance() {
return s;
}
}public class Test {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
System.out.println("Singleton.a=" + Singleton.a);
System.out.println("Singleton.b=" + Singleton.b);
}
}输出结果:
constructor
a
b
Singleton.a=0
Singleton.b=0
可以看出执行的次序。最先是singleton构造函数,接下来是static a 再b,之后是main方法中的输出
package com.pattern;class Singleton {
// private static Singleton s = new Singleton(); public static int a;
public static int b = 0;
private static Singleton s = new Singleton(); private Singleton() {
System.out.println("a= "+a+" b= "+b);
a++;
b++;
System.out.println("a= "+a+" b= "+b); } public static synchronized Singleton getInstance() {
return s;
}
}public class Test {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
System.out.println("Singleton.a=" + Singleton.a);
System.out.println("Singleton.b=" + Singleton.b);
}
}
public static int b = 0;
a,b好像都是静态的 怎么在private Singleton() {
a++;
b++;
}
要想调用a,b的值必须实例化。
所以就编译不过去