今天遇到下面的代碼,感覺很奇怪,特意記錄下:
代碼如下:
public class Test {
private static List objs = new ArrayList();
static {
objs.add(new Test(Test.S_NAME,Test.NAME,Test.COUNT));
objs.add(new Test(Test.S_NAME,Test.NAME,Test.COUNT));
}
private final static String S_NAME = "aaa";
private final static String NAME = new String("bbb");
private final static Long COUNT = 1l;
private String name;
private String title;
private Long count;
public Test(String name,String title,Long count) {
this.name = name;
this.title = title;
this.count = count;
}
public static void main(String[] args) {
System.out.println(objs);
}
@Override
public String toString() {
return "Test [name=" + name + ", title=" + title + ", count=" + count
+ "]";
}
}
運行結果如下:
感覺到特別奇怪,特意解釋下:
1,靜態變量聲明和初始化是兩個過程;
2, String字面常量有個pool, 每次有新的常量出現的時候, 先把它放入pool, 然后直接把變量引用指向pool中的位置;
3. java中的字面常量在編譯的時候被替換成真實的值,具體表現為字符串常量和基本類型常量。
4, static 塊java language specification是保證happen before的,也就是有順序的。
所以代碼等同于:
private static List objs = null;
private final static String S_NAME = "aaa"; //String pool.
private final static String NAME = null;
private final static Long COUNT = null;
static {
objs = new ArrayList();
objs.add(new Test(Test.S_NAME,Test.NAME,Test.COUNT));
objs.add(new Test(Test.S_NAME,Test.NAME,Test.COUNT));
NAME = = new String("bbb");
COUNT = = 1l;
}
這樣就很好理解了。變量的聲明和初始化是兩個過程,這樣就能理解NAME為什么是null了,而S_NAME有值。