1. 程式人生 > >對java.lang.ExceptionInInitializerError理解

對java.lang.ExceptionInInitializerError理解

最近碰到一個比較有趣的問題,以此記錄下^~^

public class A{
    private static A  a = new A();
    private static HashMap<Integer,String>() b = new HashMap<Integer,String>();

    private A(){
        b.put(123,"example");
    }
    public static A getInstance(){
        return a;
    }
}

執行上面的程式碼出現下面的錯誤,報的是ExceptionInInitializerError,通過檢視api文件給的解釋是靜態初始化程式中發生意外異常的訊號


再往下面看到了Caused by 資訊是因為呼叫put()出現了NullPointerException。

 java.lang.ExceptionInInitializerError                                                                    at com.activitydemo.MainActivity.onCreate(MainActivity.java:29)
                                                                      at
android.app.Activity.performCreate(Activity.java:6303) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376
) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483) at android.app.ActivityThread.access$900(ActivityThread.java:153) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5438) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.HashMap.put(java.lang.Object, java.lang.Object)' on a null object reference

現在就差不多可以看出來了啦 ,當呼叫getInstance() ,類A就開始載入,大家學習java的都知道靜態程式碼塊和靜態變數是隨著類的載入而載入的,靜態變數的載入順序是按照靜態變數宣告的位置開始的,那麼類A載入,就開始載入靜態變數a,接著呼叫a的構造,這裡直接呼叫b.put(123,”example”);,但是靜態變數b還沒有開始載入,所以就出現了上面的錯誤啦。
這裡修改只需要將上面靜態變數的位置交換下就好了,讓b先初始化,a再初始化呼叫構造時就不會出現問題啦!

private static HashMap <Integer,String> () b = new HashMap<Integer,String>();
private static A  a = new A();

記得在學校剛學習java static關鍵字時,那個時候記得最多的就是 static是靜態變數,後面的在沒有別的更多的理解了。
現在無意中遇到這個問題,讓我對static關鍵字有了更近一步的理解,靜態變數是所有類物件所共享的,因為它是隨著類的載入而載入,不是屬於物件所私有。

通過這個無意中的發現,現在不得不要反思自己,雖然畢業到工作有一年多了,心裡一直想著我要學習這個,學習那個,想要看下這個,那個的,但是卻連最基本,本質的東西都忘記的,最少我在剛看上面的程式碼的時候,並沒有覺得有問題,是後面通過運行了才發現問題的原因。這裡有一句話謹記:只有把根基打牢,才能走的更高^~^