[英]When Initializing object, instance variable not initialized always?
The following code produces NullPointerException - 以下代码生成NullPointerException -
public class MyClass {
static MyClass instance= new MyClass(); // line 3
static Boolean have_Instance = true;
Boolean inst_Avail=have_Instance; // line 5
Boolean isInstAvail(){
return inst_Avail;
}
public static void main(String[] args) {
System.out.println(instance.isInstAvail() ? "Instance is there.":""); // gives java.lang.NullPointerException
}
}
If I move line 3
to after line 5
, it runs fine. 如果我将
line 3
line 5
移到line 3
line 5
line 3
之后,它运行正常。 How does the order matter here? 订单如何在这里重要? Shouldn't instantiation of a class set iVar values everytime?
不应该每次实例化一个类设置iVar值吗?
When an object is created on line 3 the class has not finished initializing yet, and the have_instance
variable has its default value, null
. 当在第3行创建对象时,该类尚未完成初始化,并且
have_instance
变量具有其默认值null
。 This value is assigned to the inst_Avail
member variable of the object, so the value returned by instance.isInstAvail()
in the main
method will be null
. 此值分配给对象的
inst_Avail
成员变量,因此main
方法中instance.isInstAvail()
返回的值将为null
。
An easy way to fix this is swapping lines 3 and 4, so have_instance
already has a value when the object is created. 解决这个问题的一种简单方法是交换第3行和第4行,因此在创建对象时,
have_instance
已经有了一个值。 Or you could declare have_instance
as boolean
instead of Boolean
, so it will have the value false
and not null
. 或者您可以将
have_instance
声明为boolean
而不是Boolean
,因此它将具有值false
而不是null
。 This would make the program print nothing though. 这会使程序打印出来。
Or maybe you could rethink what you're trying to do. 或者也许你可以重新考虑你想要做的事情。 It's rarely a good idea to create instances of a class before the class has finished initializing, especially if the class is not "final" (ie may have subclasses).
在类初始化之前创建类的实例很少是个好主意,特别是如果类不是“最终”(即可能有子类)。
The order of fields matter if you initialize these fields either directly by setting their values or using a static initializer block. 如果通过设置其值或使用静态初始化程序块直接初始化这些字段,则字段顺序很重要。 They are executed in order.
它们按顺序执行。 So you couldn't do a forward reference:
所以你不能做一个前向参考:
private int someInt = 10 + otherInt;
private int otherInt = 22;
This won't work, because the fields are initialized in order of their textual declaration. 这不起作用,因为字段按其文本声明的顺序初始化。 If you have two static initializers, they will be executed in order as well:
如果你有两个静态初始值设定项,它们也将按顺序执行:
static { System.out.println("first"); }
static { System.out.println("second"); }
So in your case, you initialize instance
before have_instance
, so the latter is still null
(default value for non-primitives). 因此,在您的情况下,您在
have_instance
之前初始化instance
,因此后者仍为null
(非基元的默认值)。 The JVM will create a MyClass
object to be assigned to instance
and initialize its fields, ie assign the value of have_instance
to inst_Avail
which will be set to null
as well. JVM将创建一个要分配给
instance
的MyClass
对象并初始化其字段, have_instance
inst_Avail
的值分配给inst_Avail
,该值也将设置为null
。
Some readings: 一些读物:
This code is really weird and I dont see use-cases for this, but this would do the fix: 这段代码非常奇怪,我没有看到用例,但是这样可以解决这个问题:
public class MyClass {
static MyClass instance; // line 3
static Boolean have_Instance = true;
Boolean inst_Avail=have_Instance; // line 5
Boolean isInstAvail(){
return inst_Avail;
}
public static void main(String[] args) {
instance = new MyClass();
System.out.println(instance.isInstAvail() ? "Instance is there.":""); // gives java.lang.NullPointerException
}
}
另一个解决方案可能是将inst_Avail设置为静态,以便在加载类时,实例化此变量:
private static Boolean inst_Avail=have_Instance;
you are assigning static
variable value to non-static
variable 您将
static
变量值分配给non-static
变量
ie 即
Boolean inst_Avail=have_Instance;
either make it static
or 要么让它
static
要么
assign inst_Avail = true
in the constructor
在
constructor
指定inst_Avail = true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.