對java.lang.ExceptionInInitializerError理解
阿新 • • 發佈:2019-01-09
最近碰到一個比較有趣的問題,以此記錄下^~^
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關鍵字有了更近一步的理解,靜態變數是所有類物件所共享的,因為它是隨著類的載入而載入,不是屬於物件所私有。
通過這個無意中的發現,現在不得不要反思自己,雖然畢業到工作有一年多了,心裡一直想著我要學習這個,學習那個,想要看下這個,那個的,但是卻連最基本,本質的東西都忘記的,最少我在剛看上面的程式碼的時候,並沒有覺得有問題,是後面通過運行了才發現問題的原因。這裡有一句話謹記:只有把根基打牢,才能走的更高^~^