public class InstanceBuilder {
private static final InstanceBuilder INSTANCE = new InstanceBuilder();
private static String name = null;
private InstanceBuilder() {
System.out.println("Setting cons()");
name = "Testing";
}
public static String getName() {
return name;
}
}
public class Driver {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("value is " + InstanceBuilder.getName());
}
}
输出:
Setting cons()
value is null
为什么它将值打印为null
,即使我在构造函数中设置了static
变量,并按预期调用它。如果我尝试在构造函数中打印,则会打印Testing
,但如果我从public static
方法调用,则为null
。我知道如果我将其更改为INSTANCE.name
,它就可以了。
但我想理解为什么如果我直接访问static
变量它不起作用,因为应该共享相同的副本。
我在这里缺少什么?
答案 0 :(得分:8)
因为根据声明顺序在构造函数调用之后会修改name的值。
让我们看看发生了什么:
1)当您致电InstanceBuilder.getName()
时,InstanceBuilder
课程正在加载。作为该过程的一部分,INSTANCE
和name
实例变量正在初始化。
2)初始化INSTANCE
时,
private static final InstanceBuilder INSTANCE = new InstanceBuilder();
InstanceBuilder
类的构造函数被调用&正在打印Setting cons()
语句,并使用name
初始化Testing
变量。
3)由于以下声明,下一个name
再次被null
重新初始化
private static String name = null
;
因此,当方法调用返回Driver
类时,name
的值为null
并且null
正在打印。因此,即使name
被声明为static
,静态也不会在该上下文中发挥作用。
注意:强>
检查下面的链接,了解应该声明哪些类成员的顺序
http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-141855.html#1852
答案 1 :(得分:0)
这里的值为null,因为静态初始化是按顺序声明的, 首先你的
`private static final InstanceBuilder INSTANCE = new InstanceBuilder();`
代码执行并将值赋值给“testing”,然后是
`private static String name = null;`
代码异常并将值覆盖为null(因为静态变量只有每个类的coppy),所以最终值将为null。
所以这里的行为只是因为静态变量的执行顺序