package tandey;
class Singleton{
public static Singleton singleton =new Singleton();
public static int count1;
public static int count2=0;
//public static Singleton singleton =new Singleton();
public Singleton() {
count1++;
count2++;
}
public static Singleton getSingleton(){
return singleton;
}
}public class Mytest { public static void main(String[] args) {
Singleton singleton=Singleton.getSingleton();
System.out.println(Singleton.count1);
System.out.println(Singleton.count2);
}
}如代码:
执行结果:
1
0
关于这个如何分析?求赐教
class Singleton{
public static Singleton singleton =new Singleton();
public static int count1;
public static int count2=0;
//public static Singleton singleton =new Singleton();
public Singleton() {
count1++;
count2++;
}
public static Singleton getSingleton(){
return singleton;
}
}public class Mytest { public static void main(String[] args) {
Singleton singleton=Singleton.getSingleton();
System.out.println(Singleton.count1);
System.out.println(Singleton.count2);
}
}如代码:
执行结果:
1
0
关于这个如何分析?求赐教
相当于2条语句
public static int count2; //定义
static {count2=0;} //赋值
定义语句在执行代码之前,因为定义语句就是把变量编译成相对地址(在java中就是索引号)
所以
定义语句先执行,然后
public static Singleton singleton =new Singleton(); //这里先执行,调用构造方法count1=1,count2=1
public static int count1; //然后这里没有执行代码
public static int count2=0;//然后这里执行static{count2=0;}使得count2又变成了0LZ自己体会一下以下的例子
public class A {
static {System.out.println("1");}
static A a = new A();
static {System.out.println("3");}
static int b = 3;
static {System.out.println("4");}
static {b = 4;}
public A () {System.out.println("2");} public static void main(String[] args) {
System.out.println(A.b);
}
}
载入Singleton 类 静态初始化 执行public static Singleton singleton =new Singleton();
那么count1++;count2++;所以他们都是1.然后继续 public static int count1;
public static int count2=0;count1还是1,count2被赋值成0;
在调用的时候才会初始化,你调用的时候,
count1++;++了,就初始化为1如主类非静态成员,才会自动初始化
public static Singleton singleton =new Singleton(); 调用构造器的时候还没有执行下面两个属性语句,构造器中的count1和count2从何而来 ?
由此也可以看出当类加载时,静态的变量先全部定义之后在执行静态代码块接着执行main方法内代码,可我还是有一点不明白,singleton这个变量用static这个关键字了,那这个变量是否也在date seg 内分一块内存,指向堆new 出来的内存?栈内没有singleton这个变量?
由于调用了Singleton的静态方法,属于"主动使用"的情况,因此会导致Singleton类的加载,它的加载分为三部:
1.加载
2.连接(在此阶段中,所有静态变量赋值为默认值,这里singleton为null,count1和count2为0)
3.初始化:
调用类初始化方法<clinit>,按照代码的顺序依次初始化,先对singleton变量初始化,会调用new Singleton();所以调用到了构造器导致count1和count2的值都变成了1;
再对count1进行初始化,由于这里count1没有初始化语句,所以什么也不做;
再对count2进行初始化,由于这里语句为"count2=0"所以count2又变成了0;打印出来的结果是1,0
static int i = j + 2;
static int j = 4;
}会报非法向前引用
而
class Z {
static int peek() { return j; }
static int i = peek();
static int j = 1;
}则不会报非法向前引用。
要问为什么?java语言规范里规定的……
The restrictions above are designed to catch, at compile time, circular or otherwise malformed initializations
我也理解的不太懂