初始化对象时,实例变量始终未初始化?

时间:2022-04-15 01:41:10

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:

一些读物:

#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:

一些读物:

#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
    }

}