最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

優(yōu)雅地在Java 8中處理異常的方法詳解

 更新時(shí)間:2019年01月10日 09:08:59   作者:_pangzi  
異常處理是我們?cè)谌粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到的一種需求,下面這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地在Java 8中處理異常的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們來(lái)一起看看吧

前言

Java 8 引入的流 (Stream) API 和 lambda 表達(dá)式為我們打開(kāi)了新世界的大門(mén),自此之后我們也可以在 Java 中進(jìn)行函數(shù)式編程了。然而,在實(shí)際工作中,許多小伙伴并不知道如何正確的在 lambda 中處理異常,今天就來(lái)給大家講解一下。

小編給大家推薦一個(gè)Java技術(shù)交流群:937053620!群內(nèi)提供設(shè)計(jì)模式、spring/mybatis源碼分析、高并發(fā)與分布式、微服務(wù)、性能優(yōu)化,面試題整合文檔等免費(fèi)資料!給大家提供一個(gè)交流學(xué)習(xí)的平臺(tái)!

我們都知道,Java 異常分為檢查異常和非檢查異常。檢查異常就是編譯器要求開(kāi)發(fā)者必須處理的異常,而非檢查異常則沒(méi)有這個(gè)要求。所以當(dāng)我們需要調(diào)用某個(gè)拋出檢查異常的方法時(shí),必須明確捕獲它:

myList.stream()
 .map(item ->
  try{
  return doSomething(item);
  } catch(MyException e){
  throw new RuntimeException (e);
  }
 })
 .forEach(System.out::printion);

如上面代碼所示,我們捕獲了 MyException 這個(gè)檢查異常,然后將其轉(zhuǎn)化為 RuntimeException 非檢查異常,重新拋出。但是你自己心里面其實(shí)清楚的很,這不是最好的處理方式。

優(yōu)化一: 提升可讀性

如下所示,我們將方法體單獨(dú)提取到 trySomething 方法中,這樣的話(huà),我們就可以使用一行代碼完成 lambda 表達(dá)式,整個(gè)代碼可讀性也會(huì)提升不少:

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);
 }
}

優(yōu)化二: 復(fù)用代碼

現(xiàn)在你已經(jīng)解決了上述的問(wèn)題,然而當(dāng)我們?cè)倥龅叫枰幚懋惓5钠渌椒〞r(shí),難道我們都要用 try ... catch ... 包裹一層嗎?那樣的話(huà),你可以想象代碼中可能到處都是這種類(lèi)似的寫(xiě)法。為了避免陷入到這種重復(fù)的寫(xiě)法中,我們應(yīng)該將上述代碼片段抽象為一個(gè)小的工具類(lèi),專(zhuān)門(mén)用來(lái)干這件事情。你只需要定義一次,然后再需要的地方多次調(diào)用它就可以了。

為了實(shí)現(xiàn)這個(gè)目標(biāo),我們首先需要自己定義一個(gè)函數(shù)式接口,這個(gè)接口可能會(huì)拋出一個(gè)異常:

然后,我們來(lái)寫(xiě)一個(gè)靜態(tài)幫助函數(shù) wrap ,該方法接受一個(gè)函數(shù)式接口參數(shù),在方法體內(nèi)捕獲檢查異常,并拋出非檢查異常 RuntimeException:

借助于 wrap 靜態(tài)函數(shù),現(xiàn)在你可以在 lambda 表達(dá)式中這么寫(xiě)了

優(yōu)化三: 出現(xiàn)異常時(shí)繼續(xù)運(yùn)行

上述代碼的可讀性、抽象性已經(jīng)很好了,然而還存在一個(gè)比較大的問(wèn)題,那就是當(dāng)出現(xiàn)異常的時(shí)候,你的 stream 代碼會(huì)立即停止,不會(huì)接著處理下一個(gè)元素。大多數(shù)情況下,當(dāng)拋出異常的時(shí)候,我們可能還想讓 stream 繼續(xù)運(yùn)行下去。

我們與其拋出異常,將異常當(dāng)成一種特殊的情況處理,還不如直接將異常當(dāng)成是一個(gè) “正?!?的返回值。即這個(gè)函數(shù)要么返回一個(gè)正確的結(jié)果,要么返回一個(gè)異常,所以我們現(xiàn)在需要定義一個(gè)新的封裝類(lèi) Either,用來(lái)存儲(chǔ)這兩種結(jié)果。為了方便,我們將異常存儲(chǔ)到 left 這個(gè)字段中,將正常返回的值存儲(chǔ)到 right 這個(gè)字段中。下面就是 Either 類(lèi)的一個(gè)簡(jiǎn)單示例:

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 +")";
 } 
}

現(xiàn)在我們需要再定義一個(gè) lift 函數(shù),該函數(shù)內(nèi)部將 function 函數(shù)正常返回的值或者拋出的異常都使用 Either 類(lèi)進(jìn)行了一層封裝

現(xiàn)在我們的代碼變成這個(gè)樣子了,也不用擔(dān)心方法拋出異常會(huì)提前終止 Stream 了

優(yōu)化四: 保留原始值

現(xiàn)在思考一個(gè)問(wèn)題,如果在上述處理過(guò)程中,當(dāng)結(jié)果是異常信息的時(shí)候,我們想要重試,即重新調(diào)用這個(gè)方法怎么辦? 你會(huì)發(fā)現(xiàn)我們 Either 封裝類(lèi)沒(méi)有保存最原始的這個(gè)值,我們丟掉了原始值,因此我們可以進(jìn)一步優(yōu)化,將原始值 t 也封裝進(jìn) left 字段中,就像下面這樣:

Pair 類(lèi)是一個(gè)非常簡(jiǎn)單的封裝類(lèi),用以封裝兩個(gè)值:

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);
 }
}

這樣,當(dāng)我們遇見(jiàn)異常的時(shí)候,我們可以從 Pair 中取出最原始的值 t,無(wú)論是想重試,還是做一些其他操作,都很方便了。

總結(jié)

我們經(jīng)過(guò)上文一點(diǎn)一點(diǎn)地優(yōu)化代碼,得到了一個(gè)比較滿(mǎn)意的在 Java 8 中處理異常的通用方式。其實(shí),大家還可以關(guān)注 Github 上的有關(guān)函數(shù)式編程方面的庫(kù),比如 Javaslang ,它實(shí)現(xiàn)了多種多樣的函數(shù)式幫助方法和封裝類(lèi)來(lái)幫助開(kāi)發(fā)者寫(xiě)好 lambda 表達(dá)式。但是,如果你只是為了處理異常,而引入這么大的一個(gè)第三方庫(kù)的話(huà),就不太建議了哦~

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • java如何通過(guò)IP解析地理位置

    java如何通過(guò)IP解析地理位置

    這篇文章主要介紹了java如何通過(guò)IP解析地理位置的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java基礎(chǔ)教程之類(lèi)型轉(zhuǎn)換與多態(tài)

    Java基礎(chǔ)教程之類(lèi)型轉(zhuǎn)換與多態(tài)

    這篇文章主要介紹了Java基礎(chǔ)教程之類(lèi)型轉(zhuǎn)換與多態(tài),本文講解了 基本類(lèi)型轉(zhuǎn)換、 upcast與多態(tài)、 Object類(lèi)等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • Mybatis查詢(xún)返回Map<String,Object>類(lèi)型的實(shí)現(xiàn)

    Mybatis查詢(xún)返回Map<String,Object>類(lèi)型的實(shí)現(xiàn)

    本文主要介紹了Mybatis查詢(xún)返回Map<String,Object>類(lèi)型的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印

    Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印

    這篇文章主要介紹了Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • java——多線程基礎(chǔ)

    java——多線程基礎(chǔ)

    Java多線程實(shí)現(xiàn)方式有兩種,第一種是繼承Thread類(lèi),第二種是實(shí)現(xiàn)Runnable接口,兩種有很多差異,下面跟著本文一起學(xué)習(xí)吧,希望能給你帶來(lái)幫助
    2021-07-07
  • java開(kāi)發(fā)CPU流水線與指令亂序執(zhí)行詳解

    java開(kāi)發(fā)CPU流水線與指令亂序執(zhí)行詳解

    這篇文章主要為大家介紹了java開(kāi)發(fā)CPU流水線與指令亂序執(zhí)行詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java線程中的關(guān)鍵字和方法示例詳解

    Java線程中的關(guān)鍵字和方法示例詳解

    這篇文章主要介紹了Java有關(guān)線程中的關(guān)鍵字和方法,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Java ThreadLocal的使用場(chǎng)景總結(jié)

    Java ThreadLocal的使用場(chǎng)景總結(jié)

    ThreadLocal原本設(shè)計(jì)是為了解決并發(fā)時(shí),線程共享變量的問(wèn)題,但由于過(guò)度設(shè)計(jì),從而導(dǎo)致它的理解難度大和使用成本高等問(wèn)題。即便如此,ThreadLocal依舊有適合自己的使用場(chǎng)景,比如本文要介紹了這兩種使用場(chǎng)景,除了ThreadLocal之外,還真沒(méi)有合適的替代方案。
    2021-05-05
  • java簡(jiǎn)單手寫(xiě)版本實(shí)現(xiàn)時(shí)間輪算法

    java簡(jiǎn)單手寫(xiě)版本實(shí)現(xiàn)時(shí)間輪算法

    這篇文章主要為大家詳細(xì)介紹了java簡(jiǎn)單手寫(xiě)版本實(shí)現(xiàn)時(shí)間輪算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • postman中參數(shù)和x-www-form-urlencoded傳值的區(qū)別及說(shuō)明

    postman中參數(shù)和x-www-form-urlencoded傳值的區(qū)別及說(shuō)明

    在Postman中,參數(shù)傳遞有多種方式,其中params和x-www-form-urlencoded最為常用,Params主要用于URL中傳遞查詢(xún)參數(shù),適合GET請(qǐng)求和非敏感數(shù)據(jù),其特點(diǎn)是將參數(shù)作為查詢(xún)字符串附加在URL末尾,適用于過(guò)濾和排序等操作
    2024-09-09

最新評(píng)論

陕西省| 博爱县| 阳城县| 阆中市| 孟连| 鄂托克前旗| 渝北区| 浪卡子县| 巴楚县| 万荣县| 辛集市| 金阳县| 陆良县| 丰顺县| 滨州市| 固安县| 宁南县| 沂源县| 大名县| 象州县| 安阳县| 宜宾市| 准格尔旗| 崇明县| 无极县| 华阴市| 盱眙县| 夏邑县| 电白县| 会理县| 双峰县| 紫金县| 徐闻县| 和平县| 吉水县| 黑河市| 龙江县| 漯河市| 乌鲁木齐市| 边坝县| 黎川县|