Java 静态初始化
我编译代码时遇到了问题。当我编译代码时,foo2.var在类foo中返回null,我似乎不知道为什么。我在foo2类中进行静态初始化的方式是否有错误,导致foo2.var在foo类中为null 感谢您的帮助Java 静态初始化,java,instance-variables,static-initialization,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 exten
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行上出现空指针错误。
var
没有类型。Java中的常量按惯例也是大写的。让它:
public class Foo2 {
public final static String VAR;
static {
VAR = "newstring";
}
...
}
您尚未为
var
trypublic final static String var指定类型代码>
那为什么不
public class foo2 extends bar {
public final static String var = "newstring";
您缺少var
的类型,请将该行更改为以下内容:
public final static String VAR;
指定变量类型
此外,通过编码约定,类名应使用CamelCase和常量(带下划线的大写字母)编写
public class Foo2 {
public final static VAR = "newstring"; // why not?
...
}
此外,您还可以通过一些变量来隐藏foo2类。检查您的导入。因为类静态字段引用无法生成NPE 访问静态字段(其值不是编译时常量表达式)将触发声明该字段的类的初始化,在此期间执行静态初始值设定项。但是,只有在初始化器之间没有循环依赖关系的情况下,才能保证在读取字段时完成初始化
例如,如果您运行该程序
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语言规范要求这样的递归初始化立即完成,即调用方将看到类处于部分初始化状态。也就是说,Foo.Foo
在读取时是未赋值的,因此仍然包含默认值0。该值被分配给Bar.Bar
,完成Bar.class
的初始化。然后,通过运行将Foo.Foo
设置为1的初始值设定项,继续初始化Foo.class
实际上,您可能希望检查类的依赖关系并构造程序,以便初始值设定项之间没有循环依赖关系。什么类型的“var”?在运行foo
之前是否编译了foo2
?检查导入。如果foo2是在此上下文中导入的类,则它无法生成NPE!也许你用了什么东西来隐藏它,可能是null。@RohitJain我不确定,当编译器到达foo2.var行时,它返回null,我的理解是,当调用foo2 var实例变量时,它会自动在foo2 classI中运行静态初始化,我猜答案是“newstring”在foo2.var被分配给blah之后被分配给var。这些事情的顺序是在jls中指定的。糟糕,它在编译中确实有一个类型,只是忘了在示例中编写它。这会改变什么吗?常量不必是大写的,但这是标准约定。当然,您可以假定该类型是在那里给定的,否则编译器错误会有所不同。@RohitJain:是的,但问题中显示的代码没有其他错误。意思是也许我们应该问更多的细节糟糕的是,它在编译中确实有一个类型,只是忘了在示例中编写它。这会改变什么吗?你当然可以假设那里给出了类型,否则编译器的错误会不同。所以在你的例子中,您将如何更改它,以便在bar尝试访问它之前先为foo分配一个值?循环依赖性正是问题所在,我找到了一种方法,通过切换连接到我的示例的类/实例变量的设计来解决这个问题。谢谢