了解Java中的静态变量初始化

时间:2016-09-16 03:12:53

标签: java

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变量它不起作用,因为应该共享相同的副本。 我在这里缺少什么?

2 个答案:

答案 0 :(得分:8)

因为根据声明顺序在构造函数调用之后会修改name的值。

让我们看看发生了什么:

1)当您致电InstanceBuilder.getName()时,InstanceBuilder课程正在加载。作为该过程的一部分,INSTANCEname实例变量正在初始化。

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。

所以这里的行为只是因为静态变量的执行顺序