简体   繁体   English

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

[英]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将创建一个要分配给instanceMyClass对象并初始化其字段, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM