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

Java 初始化对象时,实例变量是否始终未初始化?,java,initialization,instance-variables,Java,Initialization,Instance Variables,以下代码生成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;

以下代码生成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
    }

}

如果我将
第3行
移动到
第5行
之后,它运行正常。这里的顺序有什么关系?类的实例化不应该每次都设置iVar值吗?

当在第3行创建对象时,该类尚未完成初始化,并且
have\u instance
变量有其默认值,
null
。此值被分配给对象的
inst\u Avail
成员变量,因此
main
方法中的
instance.isInstAvail()
返回的值将为
null

解决这个问题的一个简单方法是交换第3行和第4行,这样创建对象时,
have\u instance
已经有了一个值。或者您可以将
have_instance
声明为
boolean
,而不是
boolean
,这样它的值将为
false
,而不是
null
。这将使程序无法打印任何内容


或者你可以重新考虑你想做什么。在类完成初始化之前创建类的实例很少是一个好主意,尤其是当类不是“final”(即可能有子类)时。

另一个解决方案是将inst_用作静态变量,以便在加载类时实例化此变量:

 private static  Boolean inst_Avail=have_Instance;

您正在将
静态
变量值分配给
非静态
变量

i、 e

将其设置为静态或


如果直接通过设置字段值或使用静态初始化程序块初始化这些字段,则在构造函数中指定字段的顺序很重要。他们是按顺序执行的。所以您无法进行正向引用:

private int someInt = 10 + otherInt;
private int otherInt = 22;
这将不起作用,因为字段是按照其文本声明的顺序初始化的。如果您有两个静态初始值设定项,它们也将按顺序执行:

static { System.out.println("first"); }
static { System.out.println("second"); }
因此,在您的例子中,您在
have_instance
之前初始化
instance
,因此后者仍然是
null
(非原语的默认值)。JVM将创建一个
MyClass
对象以分配给
instance
并初始化其字段,即将
have\u instance
的值分配给
inst\u Avail
,该值也将设置为
null

一些读数:


这段代码真的很奇怪,我看不到这方面的用例,但这可以解决问题:

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
    }

}

嗯。。。您到底想做什么?当您交换第3行和第4行时,将在创建实例之前设置
have\u instance
变量,因此是的,这样做会使程序打印
实例。
为什么会有无止境的新实例循环?
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
    }

}