2

我想问一下为什么下面的代码会导致错误:

class A
{
    A()
    {
       statObj.x = 5; 
    }

    int x;
    static A statObj = new A();
}

我得到 ExceptionInInitializerError。我不明白为什么。在这种情况下,静态变量statObj将被初始化为第一个。所以,如果我是对的,静态对象statObj = new A()将被创建为第一个。

这个内部静态对象的创建和初始化顺序是什么?在调用内部静态对象构造函数之前,statObj.x 不是默认初始化为 0 值statObj.A()吗?如果是这样,为什么 statObj.x 的行为就像它没有被初始化(我认为它是默认初始化为 0 值)?

还有一个为什么这个问题只发生在构造函数中而不发生在方法中?以下代码工作正常:

        class A
        {
            A()
            {  
            }

            void met1()
            {
                statObj.x = 5; 
            }

            int x;
            static A statObj = new A();
        }


        public MainClass
        {
            public static void main(String[] arg)
            {
                A a = new A();
                a.statObj.met1();
            }
        }
4

4 回答 4

9

考虑会发生什么。以下静态初始化程序:

static A statObj = new A();

调用A(),然后尝试访问statObj

A() {
  statObj.x = 5; 
}

但是,此时statObj尚未初始化,因此null. ANullPointerException被抛出,然后被翻译成一个ExceptionInInitializerError(因为NPE已经发生在静态初始化程序中)。

第二个例子没有这个问题,因为当你尝试访问statObj时,它已经完全初始化了。

于 2012-12-12T11:36:11.130 回答
0

问题是您使用包含此静态的构造函数初始化了一个静态。

要正确完成,构造函数应该具有该静态值。但是要拥有静态值构造函数,必须首先完成。

于 2012-12-12T11:38:30.247 回答
0

您收到 NullPointerException,因为您试图在创建该对象之前访问存储在静态字段中的实例。发生这种情况是因为它仅在其构造函数完成后才被创建。但是您是从构造函数中调用它的。

第二个代码工作正常,因为构造函数(什么都不做)有机会完成。

再次:

 static A statObj = new A();

statObjnew A()在构造函数 ( ) 完成之前将为 null 。

如果创建新对象,创建顺序如下: - 找到 A.class 文件, - 静态变量的初始化, - 非静态变量的默认初始化, - 为对象分配内存 - 非静态变量的显式初始化, - 构造函数执行

好吧,这里的问题是,在“静态变量的初始化”期间,您正在调用尝试使用相同静态变量的构造函数,如果您愿意的话,会在您的序列中向前跳跃一点。

那么当我们创建 statObj 时,statObj.x 不应该在调用 statObj 构造函数之前默认初始化(按 0)吗?

是的,但这不是这里的问题。这里的问题是,statObj在其构造函数完成之前,它本身为 null。

statObj.x = 5;

如果你这样做了this.x,它会起作用的。但statObj当时仍然为空。

于 2012-12-12T11:35:56.460 回答
0

您正试图在创建对象 (statObj.x) 之前对其进行访问。试试这个:

class A
{
    A()
    { 
    }

    int x;
    static A statObj = new A();

    static {
        statObj.x = 5;
    }
}
于 2012-12-12T11:37:03.067 回答