大膽拋出已檢查的異常,之前沒有人拋出它們!java
@SneakyThrows能夠用來偷偷拋出已檢查的異常而不在方法的throws子句中實際聲明這一點。固然,應該謹慎使用這種有爭議的能力。由lombok生成的代碼不會忽略,包裝,替換或以其餘方式修改拋出的已檢查異常; 它只是僞造了編譯器。在JVM(類文件)級別,不管方法的throws子句如何,均可以拋出全部異常,不管是否檢查,這就是爲何這樣作的緣由。函數
當您想要選擇退出已檢查的異常機制時,常見的用例圍繞兩種狀況:
一個沒必要要的嚴格的接口,例如Runnable- 不管是否傳播出你的run()方法,檢查與否,它都將被傳遞給Thread未處理的異常處理程序。捕獲已檢查的異常並將其包裝在某種狀況RuntimeException下只會模糊問題的真正緣由。
一個'不可能'的例外。例如,new String(someByteArray, "UTF-8");聲明它能夠拋出UnsupportedEncodingException可是根據JVM規範,UTF-8 必須始終可用。一個UnsupportedEncodingException在這裏大約是有可能的ClassNotFoundError,當你使用一個String對象,而你沒有遇上那些要麼!
請注意,直接捕獲偷偷摸摸的已檢查類型是不可能的,由於javac不容許您爲try體中沒有方法調用聲明爲拋出的異常類型編寫catch塊。此問題與上面列出的任何一個用例都無關,因此請注意這個問題,不要在@SneakyThrows沒有通過深思熟慮的狀況下使用該機制!spa
您能夠將任意數量的例外傳遞給@SneakyThrows註釋。若是你沒有經過任何例外,你能夠偷偷地拋出任何例外。code
import lombok.SneakyThrows; public class SneakyThrowsExample implements Runnable { @SneakyThrows(UnsupportedEncodingException.class) public String utf8ToString(byte[] bytes) { return new String(bytes, "UTF-8"); } @SneakyThrows public void run() { throw new Throwable(); } }
import lombok.Lombok; public class SneakyThrowsExample implements Runnable { public String utf8ToString(byte[] bytes) { try { return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw Lombok.sneakyThrow(e); } } public void run() { try { throw new Throwable(); } catch (Throwable t) { throw Lombok.sneakyThrow(t); } } }
lombok.sneakyThrows.flagUsage = [warning | error] (default: not set)
對象
由於@SneakyThrows是一個實現細節而不是方法簽名的一部分,因此當你不調用任何拋出此異常的方法時,若是你試圖將一個被檢查的異常聲明爲偷偷拋出則是一個錯誤。(throws對於容納子類的語句,這樣作是徹底合法的)。一樣,@SneakyThrows不繼承。blog
對於人羣中的不一樣說法者:開箱即用,Eclipse將爲未捕獲的異常提供「快速修復」,這些異常包含在catch塊中的try / catch塊中的違規語句e.printStackTrace()。與僅僅偷偷地拋出異常相比,這是很是無效的,Roel和Reinier認爲被檢查的異常系統遠非完美,所以有理由選擇退出機制。繼承
若是你加上@SneakyThrows一個構造函數,那麼對兄弟或超級構造函數的任何調用都將被排除在@SneakyThrows處理以外。這是咱們沒法解決的java限制:對兄弟/超級構造函數的調用必須是構造函數中的第一個語句; 它們不能放在try / catch塊中。接口
@SneakyThrows 在一個空方法,或一個空的構造函數或只有一個兄弟/超級構造函數的調用致使沒有try / catch塊和警告。ip