一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 優雅地在Java 8中處理異常的方法詳解

優雅地在Java 8中處理異常的方法詳解

2021-07-01 13:59_pangzi Java教程

異常處理是我們在日常開發中經常會遇到的一種需求,下面這篇文章主要給大家介紹了關于如何優雅地在Java 8中處理異常的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋

前言

java 8 引入的流 (stream) api 和 lambda 表達式為我們打開了新世界的大門,自此之后我們也可以在 java 中進行函數式編程了。然而,在實際工作中,許多小伙伴并不知道如何正確的在 lambda 中處理異常,今天就來給大家講解一下。

優雅地在Java 8中處理異常的方法詳解

小編給大家推薦一個java技術交流群:937053620!群內提供設計模式、spring/mybatis源碼分析、高并發與分布式、微服務、性能優化,面試題整合文檔等免費資料!給大家提供一個交流學習的平臺!

我們都知道,java 異常分為檢查異常和非檢查異常。檢查異常就是編譯器要求開發者必須處理的異常,而非檢查異常則沒有這個要求。所以當我們需要調用某個拋出檢查異常的方法時,必須明確捕獲它:

?
1
2
3
4
5
6
7
8
9
mylist.stream()
 .map(item ->
  try{
  return dosomething(item);
  } catch(myexception e){
  throw new runtimeexception (e);
  }
 })
 .foreach(system.out::printion);

如上面代碼所示,我們捕獲了 myexception 這個檢查異常,然后將其轉化為 runtimeexception 非檢查異常,重新拋出。但是你自己心里面其實清楚的很,這不是最好的處理方式。

優化一: 提升可讀性

如下所示,我們將方法體單獨提取到 trysomething 方法中,這樣的話,我們就可以使用一行代碼完成 lambda 表達式,整個代碼可讀性也會提升不少:

?
1
2
3
4
5
6
7
8
9
10
11
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 類的一個簡單示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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 類是一個非常簡單的封裝類,用以封裝兩個值:

?
1
2
3
4
5
6
7
8
9
10
11
12
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,無論是想重試,還是做一些其他操作,都很方便了。

總結

我們經過上文一點一點地優化代碼,得到了一個比較滿意的在 java 8 中處理異常的通用方式。其實,大家還可以關注 github 上的有關函數式編程方面的庫,比如 javaslang ,它實現了多種多樣的函數式幫助方法和封裝類來幫助開發者寫好 lambda 表達式。但是,如果你只是為了處理異常,而引入這么大的一個第三方庫的話,就不太建議了哦~

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://studygolang.com/articles/17555

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 校园全肉高h湿一女多男 | 欧美整片完整片视频在线 | 男人j放进女人的p免费看视频 | 亚州春色| 精品视频在线免费 | 加勒比一本大道香蕉在线视频 | 魔法满屋免费观看完整版中文 | jk制服喷水| 欧美一区二区三区在线观看不卡 | 纲手被漫画aⅴ | 国产欧美又粗又猛又爽老 | 水多多凹凸福利视频导航 | 国内精品久久久久香蕉 | 国产精品乱码高清在线观看 | 免费网站看v片在线成人国产系列 | 69japanese日本100 6969精品视频在线观看 | 亚洲色图欧美偷拍 | 热热99 | 刺客女仆 | 2012中文字幕中字视频 | 亚洲精品色婷婷在线影院麻豆 | 国产精品视频在线观看 | 精品久久免费视频 | 2018天天拍拍拍免费视频 | 国产青色 | 毛片在线播放a | 国产免费资源高清小视频在线观看 | 青青热久麻豆精品视频在线观看 | www.国产在线观看 | 亚洲国产天堂久久综合网站 | 无码人妻视频又大又粗欧美 | 国产日韩欧美不卡www | 国产精品吹潮香蕉在线观看 | 午夜小福利 | 黑人群性xxx| 日本不卡免免费观看 | 2021小妲己永久回家地址 | 韩国禁片在线观看久 | 国产一级视频在线观看 | 亚洲网色| 国产精品露脸国语对白99 |