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. How does the order matter here? Shouldn't instantiation of a class set iVar values everytime?
如果我将第3行移到第5行之后,它运行正常。订单如何在这里重要?不应该每次实例化一个类设置iVar值吗?
5 个解决方案
#1
3
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
. 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
.
当在第3行创建对象时,该类尚未完成初始化,并且has_instance变量具有其默认值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. Or you could declare have_instance
as boolean
instead of Boolean
, so it will have the value false
and not null
. This would make the program print nothing though.
解决这个问题的一种简单方法是交换第3行和第4行,因此在创建对象时,has_instance已经有了一个值。或者您可以将have_instance声明为布尔值而不是布尔值,因此它将具有值false而不是null。这会使程序打印出来。
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" (i.e. may have subclasses).
或者也许你可以重新考虑你想要做的事情。在类完成初始化之前创建类的实例很少是个好主意,特别是如果类不是“最终”(即可能有子类)。
#2
2
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). The JVM will create a MyClass
object to be assigned to instance
and initialize its fields, i.e. assign the value of have_instance
to inst_Avail
which will be set to null
as well.
因此,在您的情况下,您在have_instance之前初始化实例,因此后者仍为null(非基元的默认值)。 JVM将创建一个要分配给实例并初始化其字段的MyClass对象,即将has_instance的值分配给inst_Avail,该值也将设置为null。
Some readings:
一些读物:
- Object initialization in Java
- Java中的对象初始化
#3
0
Another solution to this could be to make inst_Avail as static, so that at the time of loading the class, this variable is instantiated:
另一个解决方案是将inst_Avail设置为静态,以便在加载类时,实例化此变量:
private static Boolean inst_Avail=have_Instance;
#4
0
you are assigning static
variable value to non-static
variable
您将静态变量值分配给非静态变量
i.e.
即
Boolean inst_Avail=have_Instance;
either make it static
or
要么使它静止,要么
assign inst_Avail = true
in the constructor
在构造函数中指定inst_Avail = true
#5
0
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
}
}
#1
3
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
. 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
.
当在第3行创建对象时,该类尚未完成初始化,并且has_instance变量具有其默认值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. Or you could declare have_instance
as boolean
instead of Boolean
, so it will have the value false
and not null
. This would make the program print nothing though.
解决这个问题的一种简单方法是交换第3行和第4行,因此在创建对象时,has_instance已经有了一个值。或者您可以将have_instance声明为布尔值而不是布尔值,因此它将具有值false而不是null。这会使程序打印出来。
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" (i.e. may have subclasses).
或者也许你可以重新考虑你想要做的事情。在类完成初始化之前创建类的实例很少是个好主意,特别是如果类不是“最终”(即可能有子类)。
#2
2
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). The JVM will create a MyClass
object to be assigned to instance
and initialize its fields, i.e. assign the value of have_instance
to inst_Avail
which will be set to null
as well.
因此,在您的情况下,您在have_instance之前初始化实例,因此后者仍为null(非基元的默认值)。 JVM将创建一个要分配给实例并初始化其字段的MyClass对象,即将has_instance的值分配给inst_Avail,该值也将设置为null。
Some readings:
一些读物:
- Object initialization in Java
- Java中的对象初始化
#3
0
Another solution to this could be to make inst_Avail as static, so that at the time of loading the class, this variable is instantiated:
另一个解决方案是将inst_Avail设置为静态,以便在加载类时,实例化此变量:
private static Boolean inst_Avail=have_Instance;
#4
0
you are assigning static
variable value to non-static
variable
您将静态变量值分配给非静态变量
i.e.
即
Boolean inst_Avail=have_Instance;
either make it static
or
要么使它静止,要么
assign inst_Avail = true
in the constructor
在构造函数中指定inst_Avail = true
#5
0
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
}
}