Java中的ExceptionInInitializerError異常及解決方法


  當在靜態初始化塊中出現了異常的時候,JVM會拋出 java.lang.ExceptionInInitializerError異常。如果你了解Java中的靜態變量,你會知道它們是在類加載的時候進行初始化的。如果在這個靜態變量初始化的過程中出現了異常,那么就會拋出 java.lang.ExceptionInInitializerError異常。任何異常都可能會引發這種情況,比如說,java.lang.ArrayIndexOutOfBound或者java.lang.NullPointerException。Java開發人員通常會被這個錯誤弄暈,他覺得自己並沒有定義任何的靜態初始化塊,為什么還會拋出ExceptionInInitializerError異常;事實上,Java默認會將靜態變量的初始化放在一個默認的靜態初始化塊中,然后按它們在源文件中聲明的順序來進行初始化。比如說變量ABC聲明在第一行,在第二行中使用到了,而在第三行的時候才初始化,那么第二行的代碼會拋出一個NullPointerException異常,這個異常會被封裝到一個ExceptionInInitializerError異常中,如果這段代碼在主線程中執行了,你會看到控制台或者日志文件中出現這樣的錯誤信息: "Exception in thread "main" java.lang.ExceptionInInitializerError"。在一個擁有大量日志文件的大型系統中,這樣的錯誤很容易被忽略,而程序員會得到一個java.lang.NoClassDefFoundError異常。不幸的是只有當別人使用到了這個類的時候才會出現這個錯誤,因為ExceptionInInitializerError導致了這個類無法加載。由於類加載失敗了,因此JVM會拋出NoClassDefFoundError。有的時候這會誤導Java開發人員,他們會檢查類路徑,PATH,以及java.library.path看是不是缺少了這個類,卻又發現不了任何問題,這讓他們很困惑。如果你在分析NoClassDefFoundError的原因,你最好看下你的日志文件中有沒有ExceptionInInitializerError,然后再考慮要不要檢查classpath
Exception in thread "main" java.lang.ExceptionInInitializerError的原因 
正如別的錯誤或者異常一樣,當你看見這行信息,你知道這是出現ExceptionInInitializerError異常了,這個異常是由於類加載過程中靜態塊初始化過程失敗所導致的。由於它出現在負責啟動程序的主線程中,因此你最好從主類中開始分析,這里說的主類是指你在命令行參數中指定的那個,或者說是你聲明了public static void main(String args[])方法的那個類。如果你仔細地看一下完整的堆棧跟蹤信息,你其實什么也不用做,因為JVM已經把類名給打印出來了,這就是引發ExceptionInInitializerError的類。ExceptionInInitializerError是LinkageError的子類,這意味着這個異常會導致你的類無法加載到JVM的內存中。現在我們來看一下這個示例程序,它在執行的時候會拋出下面的異常: 
 
如何解決Exception in thread "main" java.lang.ExceptionInInitializerError 
需要記住以下幾點: 
  1. "Exception in thread "main" java.lang.ExceptionInInitializerError"意味着異常出現在主線程,並且是LinkageError的一個子類java.lang.ExceptionInInitializerError,這是JVM類加載失敗時才拋出的,原因是靜態初始化代碼中出現了諸如IndexOutOfBoundsException或者NullPointerException這樣的RuntimeException。 
  2. 記住JVM會將所有的靜態變量的初始化按它們在源文件中的出現順序放到一個靜態初始化塊中。因此,不要覺得沒有看到靜態初始塊就認為不會出現這個異常。事實上,你得確保靜態變量的正確順序,比如說,如果 一個變量初始化的時候用到了另一個變量,你得確保這個變量在前面已經初始化過了。 
  3. 如果別的代碼想要使用這個類,則會拋出ExceptionInInitializerError異常,而它又會導致ClassNotFoundException或者NoClassDefFoundError。為什么?因為這個類加載失敗了,並沒有加載到JVM的內存中。因此如果你在解決類不存在之類的異常時,先看看你的日志文件中有沒有這個異常。 
  4. 記住靜態初始化代碼塊會拋出RuntimeException而不是已檢查異常,而后者需要有對應的catch塊來進行處理。 
  需要謹記的是這個異常的一個副作用是NoClassDefFoundError,而Java程序拋出這個異常的位置可能會離java.lang.ExceptionInInitializerError很遠,這取決於你的客戶端代碼何時引用到這個類。因此,在查看類路徑解決NoClassDefFoundError異常之前,最好先看看日志有沒有出現ExceptionInInitializerError。
經檢查和如下錯誤有關:
java.lang.IllegalArgumentException: Malformed \uxxxx encoding. 

  Java讀取配置文件中路徑信息時,若路徑部分使用“\”而不是“/”,系統默認解析\u的形式,因此,配置文件中若有路徑信息,應該使用“\\”或“/”


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM