2013-05-11 82 views
10

ClassNotFoundException是否爲檢查異常的原因是什麼?ClassNotFoundException的原因爲檢查異常

我一直在猜測和谷歌搜索試圖瞭解爲什麼認爲類沒有被發現爲檢查異常,因爲我所有的腦海告訴我,它應該是沒有檢查。

回答

6

異常通常在接收器可以/應該採取一些有意義的行動來在運行時糾正問題。

Unchecked Exceptions — The Controversy說:

這裏的底線準則:如果客戶可以合理預期從異常中恢復,使它成爲一個檢查異常。如果客戶端無法做任何事情來恢復異常,請將其設爲未檢查的異常。

ClassNotFoundException S中的最常見的來源是一樣

classLoader.loadClass(className); 

反射性負載根據在配置文件中,串行輸入,或遠程過程調用發現了一個名稱的類代碼。

這與ClassNotFoundError形成對比,它最常見於靜態編譯的程序,其他類在運行時無法被JVM的鏈接器找到。

從失敗反射用例(檢查)鏈接靜態編譯的代碼(運行時錯誤)有什麼區別?


語境

反思:來電者知道哪裏串從爲什麼負載試圖來了。

靜態:調用者只是試圖使用在編譯時可用的類。沒有上下文可用。

恢復

反思:呼叫者可以故障切換到不同的實現,或者嘗試一個默認的策略。

靜態:Java語言不明確支持替換不同的鏈接點。

改寫

反思:來電要經常錯誤轉換爲不同的種類,如
IOException失敗反序列化。

靜態: 如果你的程序的一部分丟失了,那麼你不能依賴你的程序的必要部分來解釋爲什麼一個部分丟失到其他部分。

4

如果代碼在無法解析應用程序類路徑上的類的類名稱上調用Class.forName()(簡而言之),則會引發A ClassNotFoundException。它可能是應用程序用戶提供的拼寫錯誤的類名,因此可能有理由將其報告給用戶,甚至可能會使用更正的類名重試。換句話說,這個可能是是一個可恢復的錯誤......在某些情況下......所以你可以爭辯說做出檢查的決定是合適的。

無論哪種方式:

  • 檢查之間對未選中任何選擇的「正確性」是見仁見智,而不是客觀事實,
  • 過去,Java的設計者已經在一些做出了錯誤的選擇案例和
  • 一旦做出選擇,就沒有回頭...沒有打破向後兼容性。

相比之下,如果您在類加載/初始化過程中遇到問題,您可能會得到一個NoClassDefFoundError。這絕對不可收回。發生這種情況時,您已經有一個或多個類存在於JVM中,但無法初始化或實例化。 (如果JVM無法找到您指定的入口點類,您也將看到NoClassDefFoundError,但是如果發生這種情況,您的應用程序甚至不會有機會嘗試恢復......)

+0

恕我直言,最大的錯誤是做'SQLException'檢查。 – Bohemian 2013-05-11 14:31:37

+0

@Bohemian - 看到我的第一個要點:-) – 2013-05-12 03:20:19

+0

我會出去走一走,說這是事實。當您查看使用JDBC的代碼時,它充斥着從未使用過的try-catch塊。永遠。當你有許多敷衍的代碼時,你知道你已經做了一個設計失誤。 – Bohemian 2013-05-12 03:57:45

1

未經檢查的異常用於您的程序無法從中恢復的錯誤。檢查異常適用於您可以從中恢復的無效條件。

據我所知,檢查異常的概念只存在於Java中。

現在的問題是程序能否從ClassNotFoundException中恢復?

這是由Class.forName方法拋出的大部分時間。這取決於你的程序,所以checked和unchecked的概念是有點隨意的,因爲API開發者應該知道我的程序是否可以從中恢復。當我在運行時需要該類並且無法處理時,對於我來說這將是一種無法檢查的情況,但是當我向用戶請求某些內容並基於此加載一個類時,輸入可能是錯誤的,我可以要求他提供其他內容。但是大多數時候我會說你無法從中恢復過來,最好是不加限制。

但是在我看來,api和第三方使用檢查的異常來提醒程序員這個問題可能發生並且需要考慮。並且由於基於純String的加載可能會失敗,並且與整個Java靜態類型化語言概念不兼容,所以這個異常會被標記爲checked,這樣就會提醒您破壞了您的靜態安全性。不過,這只是我的看法。

最終的決定是由異常開發商提出,他可能是錯的或右或也許想過一些其他的原因爲一