0

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

任何帮助表示赞赏。

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 行出现空指针错误。

4

5 回答 5

3

您尚未指定vartry的类型public final static String VAR;

然后为什么不只是

public class foo2 extends bar {
  public final static String var = "newstring";
于 2013-11-20T17:47:05.277 回答
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,但Foo.class已经被初始化。Java 语言规范在第 12.4.2 节第 3 步中规定,这种递归初始化立即完成,即调用者将看到类处于部分初始化状态。也就是说,Foo.foo在读取时未分配,因此仍包含默认值 0。该值被分配给Bar.bar,完成 的初始化Bar.class。然后,Foo.class通过运行初始化程序来恢复初始化,初始化程序设置Foo.foo为 1。

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

于 2013-11-20T18:28:20.467 回答
2

var没有类型。Java 中的常量也按照惯例是大写的。做了:

public class Foo2 {
  public final static String VAR;

  static {
    VAR = "newstring";
  }
  ...
}
于 2013-11-20T17:46:53.967 回答
0

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

public final static String VAR;
于 2013-11-20T17:49:36.143 回答
0

指定 var 类型。

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

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

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

于 2013-11-20T17:49:51.410 回答