您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么在Java8中處理異常”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
我們都知道,Java 異常分為檢查異常和非檢查異常。檢查異常就是編譯器要求開發者必須處理的異常,而非檢查異常則沒有這個要求。所以當我們需要調用某個拋出檢查異常的方法時,必須明確捕獲它:
myList.stream() .map(item -> try{ return doSomething(item); } catch(MyException e){ throw new RuntimeException (e); } }) .forEach(System.out::printion);
如上面代碼所示,我們捕獲了 MyException 這個檢查異常,然后將其轉化為 RuntimeException 非檢查異常,重新拋出。但是你自己心里面其實清楚的很,這不是最好的處理方式。
如下所示,我們將方法體單獨提取到 trySomething 方法中,這樣的話,我們就可以使用一行代碼完成 lambda 表達式,整個代碼可讀性也會提升不少:
myList.stream() .map(this::trySomething) .forEach(System.out::printion); private Item trySomething(Item item) { try{ return doSomething(item); } catch(MyException e){ throw new RuntimeException (e); } }
現在你已經解決了上述的問題,然而當我們再碰到需要處理異常的其它方法時,難道我們都要用 try ... catch ... 包裹一層嗎?那樣的話,你可以想象代碼中可能到處都是這種類似的寫法。為了避免陷入到這種重復的寫法中,我們應該將上述代碼片段抽象為一個小的工具類,專門用來干這件事情。你只需要定義一次,然后再需要的地方多次調用它就可以了。
為了實現這個目標,我們首先需要自己定義一個函數式接口,這個接口可能會拋出一個異常:
然后,我們來寫一個靜態幫助函數 wrap ,該方法接受一個函數式接口參數,在方法體內捕獲檢查異常,并拋出非檢查異常 RuntimeException:
借助于 wrap 靜態函數,現在你可以在 lambda 表達式中這么寫了
上述代碼的可讀性、抽象性已經很好了,然而還存在一個比較大的問題,那就是當出現異常的時候,你的 stream 代碼會立即停止,不會接著處理下一個元素。大多數情況下,當拋出異常的時候,我們可能還想讓 stream 繼續運行下去。
我們與其拋出異常,將異常當成一種特殊的情況處理,還不如直接將異常當成是一個 “正常” 的返回值。即這個函數要么返回一個正確的結果,要么返回一個異常,所以我們現在需要定義一個新的封裝類 Either,用來存儲這兩種結果。為了方便,我們將異常存儲到 left 這個字段中,將正常返回的值存儲到 right 這個字段中。下面就是 Either 類的一個簡單示例:
public class Eithercl<L,R>{ private final L Left: private final R right; private Either(L left, R right){ this left=left; this right =right; } public static <L, R> Either,<L,R> Left( L value) { return new Either(value, null): } public static <L, R> Either<L, R> Right( R value) { return new Either(null, value) } public Optional<L> getleft() { return Optional. ofnullable(left) } public Optional<R> getright() { return Optional.ofnullable(right); } public boolean isleft() { return left I- null; } public boolean isright(){ return right != null; } public < T> optional<T> mapleft(Function<? super L, T> mapper){ if (isleft()) { return Optional of(mapper. apply(left)); } return Optional empty(); } public <T> Optional<T> mapright(Function<? super R, T> mapper) { if (isright()) { return Optional of(mapper. apply(right)); } return Optionalempty(); } public String tostring(){ if (isleft()){ return"Left(”+left+")"; } return "Right("+ right +")"; } }
現在我們需要再定義一個 lift 函數,該函數內部將 function 函數正常返回的值或者拋出的異常都使用 Either 類進行了一層封裝
現在我們的代碼變成這個樣子了,也不用擔心方法拋出異常會提前終止 Stream 了
現在思考一個問題,如果在上述處理過程中,當結果是異常信息的時候,我們想要重試,即重新調用這個方法怎么辦? 你會發現我們 Either 封裝類沒有保存最原始的這個值,我們丟掉了原始值,因此我們可以進一步優化,將原始值 t 也封裝進 left 字段中,就像下面這樣:
Pair 類是一個非常簡單的封裝類,用以封裝兩個值:
public class Pair<F, S> { public final F fst; public final S snd; private Pair(F fst, S snd){ this fst fst; this snd= snd; } public static <F, S> Pair<F, S> of(F fst, S snd){ return new Pair<>(fst, snd); } }
這樣,當我們遇見異常的時候,我們可以從 Pair 中取出最原始的值 t,無論是想重試,還是做一些其他操作,都很方便了。
“怎么在Java8中處理異常”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。