今天遇到下面的代码,感觉很奇怪,特意记录下:
代码如下:
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有值。