日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 8 lambda_异常作弊– Java 8 Lambdas

發布時間:2023/12/3 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 8 lambda_异常作弊– Java 8 Lambdas 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java 8 lambda

異常作弊– Java 8 Lambdas

撇開關于Checked vs Runtime異常的宗教辯論,有時由于庫的構造不佳,處理Checked示例會使您發瘋。

考慮一下您可能要編寫的以下代碼片段:

public void createTempFileForKey(String key) {Map<String, File> tempFiles = new ConcurrentHashMap<>();//does not compile because it throws an IOException!!tempFiles.computeIfAbsent(key, k -> File.createTempFile(key, ".tmp")); }

為了使其編譯,您需要捕獲使您留下此代碼的異常:

public void createTempFileForKey(String key) {Map<String, File> tempFiles = new ConcurrentHashMap<>();tempFiles.computeIfAbsent(key, k -> {try {return File.createTempFile(key, ".tmp");}catch(IOException e) {e.printStackTrace();return null;}}); }

盡管可以編譯,但是IOException已經有效地被吞沒了。 應該通知此方法的用戶已引發異常。

為了解決這個問題,您可以將IOException包裝在通用RuntimeException中,如下所示:

public void createTempFileForKey(String key) throws RuntimeException {Map<String, File> tempFiles = new ConcurrentHashMap<>();tempFiles.computeIfAbsent(key, k -> {try {return File.createTempFile(key, ".tmp");}catch(IOException e) {throw new RuntimeException(e);}}); }

這段代碼確實拋出了一個Exception,但是沒有拋出打算由該代碼拋出的實際IOException。 那些只支持RuntimeExceptions的人可能會對此代碼感到滿意,尤其是如果可以改進解決方案以創建自定義的IORuntimeException時。 盡管如此,大多數人還是以這種方式編寫代碼,他們希望他們的方法能夠從File.createTempFile方法中拋出經過檢查的IOException 。

這樣做的自然方法有些復雜,看起來像這樣:

public void createTempFileForKey(String key) throws IOException{Map<String, File> tempFiles = new ConcurrentHashMap<>();try {tempFiles.computeIfAbsent(key, k -> {try {return File.createTempFile(key, ".tmp");} catch (IOException e) {throw new RuntimeException(e);}});}catch(RuntimeException e){if(e.getCause() instanceof IOException){throw (IOException)e.getCause();}} }

從lambda內部,您必須捕獲IOException,將其包裝在RuntimeException中并拋出該RuntimeException。 Lambda必須捕獲RuntimeException的包裝并重新拋出IOException。 確實非常丑陋!

在理想的世界中,我們需要做的就是從lambda中拋出已檢查的異常,而不必更改computeIfAbsent的聲明。 換句話說,拋出檢查異常,就好像它是運行時異常一樣。 但是不幸的是Java不允許我們這樣做…

除非我們作弊,否則那不是! 這里有兩種方法可以精確地執行我們想要的操作,即拋出檢查異常,就好像它是運行時異常一樣。

方法1 –使用泛型:

public static void main(String[] args){doThrow(new IOException());}static void doThrow(Exception e) {CheckedException.<RuntimeException> doThrow0(e);}static <E extends Exception>void doThrow0(Exception e) throws E {throw (E) e;}

請注意,我們已經創建并拋出IOException,而沒有在main方法中聲明它。

方法2 –使用不安全:

public static void main(String[] args){getUnsafe().throwException(new IOException());}private static Unsafe getUnsafe(){try {Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);return (Unsafe) theUnsafe.get(null);} catch (Exception e) {throw new AssertionError(e);}}

再次,我們設法拋出IOException而不在方法中聲明它。

無論您喜歡哪種方法,我們現在都可以通過這種方式自由編寫原始代碼:

public void createTempFileForKey(String key) throws IOException{Map<String, File> tempFiles = new ConcurrentHashMap<>();tempFiles.computeIfAbsent(key, k -> {try {return File.createTempFile(key, ".tmp");} catch (IOException e) {throw doThrow(e);}});}private RuntimeException doThrow(Exception e){getUnsafe().throwException(e);return new RuntimeException();}private static Unsafe getUnsafe(){try {Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);return (Unsafe) theUnsafe.get(null);} catch (Exception e) {throw new AssertionError(e);}}

doThrow()方法顯然將封裝在某些實用程序類中,從而使您的代碼在createTempFileForKey()非常干凈。

翻譯自: https://www.javacodegeeks.com/2015/05/cheating-with-exceptions-java-8-lambdas.html

java 8 lambda

總結

以上是生活随笔為你收集整理的java 8 lambda_异常作弊– Java 8 Lambdas的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。