静态初始化

时间:2013-11-20 17:44:07

标签: java instance-variables static-initialization

编译代码时遇到了问题。当我编译我的代码时foo2.var在类foo中返回null,我似乎无法弄清楚为什么。我是如何在foo2类中进行静态初始化以使foo2.var在foo类中为null的?

感谢任何帮助。

public class foo extends bar {
  public final static String blah = foo2.var;
  ...
}

public abstract class bar {
  ...
}

public class foo2 extends bar {
  public final static String var;

  static {
    var = "newstring";
  }
  ...
}

此示例中foo2.var行上的空指针错误。

5 个答案:

答案 0 :(得分:3)

您尚未为var尝试public final static String VAR;

指定类型

然后为什么不只是

public class foo2 extends bar {
  public final static String var = "newstring";

答案 1 :(得分:2)

var没有类型。 Java中的常量也是按惯例大写的。成功:

public class Foo2 {
  public final static String VAR;

  static {
    VAR = "newstring";
  }
  ...
}

答案 2 :(得分:2)

访问静态字段(其值不是编译时常量表达式)将触发声明该字段的类的初始化,在该字段期间执行静态初始化程序。但是,如果初始化器之间没有循环依赖关系,则只能在读取字段时完成初始化。

例如,如果您运行程序

class Bar {
    static final long bar;

    static {
        System.out.println("Assigning bar");
        bar = Foo.foo;
    }
}
class Foo extends Bar {
    static final long foo;

    static {
        System.out.println("Assigning foo");
        foo = 1;
    }
}

public class Test {
    public static void main(String[] args) {
        new Foo();
        System.out.println(Bar.bar);
    }
}

你得到以下输出:

Assigning bar
Assigning foo
0
1

因为要创建Foo的新实例,所以会初始化Foo.class,首先会初始化其超类Bar.class,该超类读取Foo.class的字段,但是{{ 1}}已经被初始化了。 Java语言规范要求section 12.4.2, step 3,这种递归初始化立即完成,即调用者将看到该类处于部分初始化状态。也就是说,Foo.class在读取时未被分配,因此仍然包含默认值0.该值被分配给Foo.foo,完成Bar.bar的初始化。然后,通过运行初始化程序恢复Bar.class的初始化,初始化程序将Foo.class设置为1。

实际上,您可能希望查看类的依赖关系并构建程序,以便初始化程序之间不存在循环依赖关系。

答案 3 :(得分:0)

您缺少var的类型,请将该行更改为以下内容:

public final static String VAR;

答案 4 :(得分:0)

指定var type。

另外,通过编码约定类名应该用CamelCase和常量编写,UNDERSCORED_CAPS

public class Foo2 {
   public final static VAR = "newstring"; // why not?
...
}

另外,您可以通过某个变量来影响foo2类。检查你的进口。因为类静态字段引用不能产生NPE!