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

歡迎訪問 生活随笔!

生活随笔

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

java

功能Java示例 第3部分–不要使用异常来控制流程

發布時間:2023/12/3 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 功能Java示例 第3部分–不要使用异常来控制流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是稱為“ Functional Java by Example”的系列文章的第3部分。

我在本系列的每個部分中發展的示例是某種“提要處理程序”,用于處理文檔。 在前面的部分中,我從一些原始代碼開始,并應用了一些重構來描述“什么”而不是“如何”。

為了幫助代碼向前發展,我們需要擺脫良好的java.lang.Exception 。 (免責聲明:我們實際上無法擺脫它)這就是其中的內容。

如果您是第一次來這里,最好從頭開始閱讀。 它有助于了解我們從何處開始以及如何在整個系列中繼續前進。

這些都是這些部分:

  • 第1部分–從命令式到聲明式
  • 第2部分–講故事
  • 第3部分–不要使用異常來控制流程
  • 第4部分–首選不變性
  • 第5部分–將I / O移到外部
  • 第6部分–用作參數
  • 第7部分–將失敗也視為數據
  • 第8部分–更多純函數

我將在每篇文章發表時更新鏈接。 如果您通過內容聯合組織來閱讀本文,請查看我博客上的原始文章。

每次代碼也被推送到這個GitHub項目 。

快速了解異常

自Java 1.0以來,我們的java.lang.Exception一直存在-基本上在好時機和其他時候成為我們的敵人。

關于它們的討論不多,但是如果您想閱讀一些資源,這是我的最愛:

  • Java異常 (JavaWorld)
  • Java例外– GeeksforGeeks (geeksforgeeks.org)
  • 9種處理Java中異常的最佳實踐 (stackify.com)
  • 異常處理的最佳實踐 (onjava.com)
  • Java異常面試問答 (journaldev.com)
  • 帶有示例的Java中的異常處理 (beginnersbook.com)
  • Java異常處理(Try-catch) (hackerrank.com)
  • 十大Java異常處理最佳實踐– HowToDoInJava (howtodoinjava.com)
  • Java中的異常處理和斷言– NTU (ntu.edu.sg)
  • 異常處理:最佳實踐指南 (dzone.com)
  • 在Java中處理異常的9種最佳實踐 (dzone.com)
  • 修復7個常見Java異常處理錯誤 (dzone.com)
  • Java慣例->已檢查異常與未檢查異常 (javapractices.com)
  • Java中異常的常見錯誤 MikaelSt?ldal的技術博客 (staldal.nu)
  • Java開發人員在使用異常時犯的11個錯誤 (medium.com/@rafacdelnero)
  • 檢查異常是好是壞? (JavaWorld)
  • 檢查異常:Java的最大錯誤 精簡Java (literatejava.com)
  • 未經檢查的異常-爭議 (docs.oracle.com)
  • 已檢查異常的麻煩 (artima.com)
  • Java例外:您(可能)做錯了 (dzone.com)
  • Java理論與實踐:異常辯論– IBM (ibm.com)
  • Java的檢查異常是一個錯誤(這是我想做的 (radio-weblogs.com)
  • Buggy Java代碼:Java開發人員犯的十大最常見錯誤 Toptal (toptal.com)

您已經在Java 8上了嗎? 生活變得好多了! 我… 呃…哦,等等。

  • Java輸入流的錯誤處理– Javamex (javamex.com)
  • 在Java流中處理檢查的異常 (oreilly.com)
  • JDK 8流中的異常處理 (azul.com)
  • 帶有異常的Java 8功能接口 (slieb.org)
  • 重新打包流中的異常– blog @ CodeFX (blog.codefx.org)
  • 如何在Java 8 Stream中處理異常? –堆棧溢出 (stackoverflow.com)
  • 檢查異常和流| Benji的博客 (benjiweber.co.uk)
  • 一個關于檢查異常和Java 8 Lambda表達式的 故事 (javadevguy.wordpress.com)– 很好的戰爭故事!
  • hgwood / java8-streams-and-exceptions (github.com)

好的,看來您不可能正確地做到這一點。

至少,閱讀上述名單后,我們現在完全取決于對速度的話題��

幸運的是,我不必再寫一篇博客文章,介紹上面的文章已經涵蓋了95%的內容,但是在這里,我將重點討論代碼中實際存在的一個Exception ��

副作用

既然您正在閱讀這篇文章,您可能會對為什么這一切都與函數式編程有關感興趣。

在以更“實用的方式”處理代碼的過程中,您可能會遇到“副作用”一詞,這是一件“壞事”。

在現實世界中, 副作用是您不希望發生的事情 ,您可能會說它等同于“例外”情況(您會例外說明),但是在函數式編程上下文中它具有更嚴格的含義。

維基百科有關副作用的文章說:

副作用(計算機科學)在計算機科學中,如果函數或表達式在返回范圍之外修改了某些狀態或與其調用函數或外界有可觀察的交互作用,則稱該函數或表達式具有副作用。 …在函數式編程中,很少使用副作用。

因此,在本系列的前兩篇文章之后,讓我們看看我們的FeedHandler代碼當前的樣子:

class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {changes.findAll { doc -> isImportant(doc) }.each { doc ->try {def resource = createResource(doc)updateToProcessed(doc, resource)} catch (e) {updateToFailed(doc, e)}}}private Resource createResource(doc) {webservice.create(doc)}private boolean isImportant(doc) {doc.type == 'important'}private void updateToProcessed(doc, resource) {doc.apiId = resource.iddoc.status = 'processed'documentDb.update(doc)}private void updateToFailed(doc, e) {doc.status = 'failed'doc.error = e.messagedocumentDb.update(doc)}}

在一個地方,我們嘗試捕獲異常,在那兒,我們循環瀏覽重要的文檔,并嘗試為其創建“資源”(無論是什么)。

try {def resource = createResource(doc)updateToProcessed(doc, resource) } catch (e) {updateToFailed(doc, e) }

在上面的代碼中catch (e)是catch (Exception e) Groovy縮寫。

是的,這就是我們正在捕獲的通用java.lang.Exception 。 可以是任何例外,包括NPE。

如果createResource方法沒有引發異常,則將文檔(“ doc”)更新為“已處理”,否則將其更新為“失敗”。 順便說一句,即使updateToProcessed也會引發異常,但是對于當前的討論,我實際上只對成功創建資源感興趣。

因此,上面的代碼可以工作 (我已經通過單元測試來證明它:-)),但是我對try-catch語句不滿意。 我只對成功創建資源感興趣,而且很傻,我只能提出createResource要么返回成功的資源, 要么拋出異常。

拋出異常以表示出了點問題,躲開閃避,讓調用者捕獲該異常以進行處理,這是為什么發明了異常的原因呢? 而且比返回null更好嗎?

它一直在發生。 采取一些我們喜歡的框架,例如JPA規范中的 EntityManager#find :

啊! 返回null 。

返回值:
找到的實體實例;如果該實體不存在,則返回null

錯誤的例子。

函數式編程鼓勵使用無副作用的方法(或:函數),以使代碼更易于理解且更易于推理。 如果某個方法僅接受某些輸入并每次都返回相同的輸出(這使其成為一個純函數),則各種優化都可以在后臺進行,例如通過編譯器或緩存,并行化等。

我們可以再次用純函數(計算出的值)替換純函數,這稱為參考透明度 。

在上一篇文章中,我們已經將一些邏輯提取到了自己的方法中,例如下面的isImportant 。 給定相同的文檔(具有相同的 type屬性)作為輸入,我們每次都會獲得相同的 (布爾值)輸出。

boolean isImportant(doc) {doc.type == 'important' }

這里沒有可觀察到的副作用,沒有全局變量被突變,沒有日志文件被更新–它只是塞進,塞出 。

因此,我要說的是,通過我們的傳統異常與外界交互的函數很少在函數式編程中使用。

我想做得更好 。 更好 。

可選救援

正如石磊韋伯表示它:

關于如何在Java中有效使用異常有不同的觀點。 有些人喜歡檢查異常,有些人則認為這是一次失敗的實驗,他們更喜歡獨占使用未檢查異常。 其他人則完全避開異常,而贊成傳遞和返回諸如Optional或Maybe之類的類型。

好的,讓我們嘗試一下Java 8的Optional以便發出是否可以創建資源的信號。

讓我們更改我們的webservice接口和createResource方法,以在Optional包裝并返回我們的資源:

//private Resource createResource(doc) { private Optional<Resource> createResource(doc) {webservice.create(doc) }

讓我們更改原始的try-catch :

try {def resource = createResource(doc)updateToProcessed(doc, resource) } catch (e) {updateToFailed(doc, e) }

map (處理資源)和orElseGet (處理空的可選):

createResource(doc).map { resource ->updateToProcessed(doc, resource)}.orElseGet { /* e -> */updateToFailed(doc, e)}

很棒的createResource方法:返回正確結果,或者為空結果。

等一下! 唯一的例外e我們需要傳遞到updateToFailed是走了 :我們有一個空的Optional替代。 我們不能存儲的原因失敗的原因 -這是我們做的必要性。

可能是Optional只是表示“缺席”,并且是我們此處目的不正確的工具。

出色的完成

如果沒有try-catch和map-orElseGet ,我確實喜歡代碼開始更多地反映操作“流程”的方式。 不幸的是,使用Optional更適合“得到一些東西”或“什么也沒有得到”(這也建議使用map和orElseGet類的名稱),并且沒有給我們提供記錄失敗原因的機會。

還有什么方法能夠獲得成功的結果或失敗的原因,而仍然接近我們的閱讀方式呢?

Future 。 更好的是: CompletableFuture 。

CompletableFuture (CF)知道如何返回值,這類似于Optional 。 通常,CF用于將來獲取值集 ,但這不是我們想要將其用于…的原因。

從Javadoc :

……支持……在完成時觸發的行動的未來。

跳動,它可以表示“異?!蓖瓿?-給我機會對此采取行動。

讓我們更改map和orElseGet :

createResource(doc).map { resource ->updateToProcessed(doc, resource)}.orElseGet { /* e -> */updateToFailed(doc, e)}

thenAccept (處理成功)并exceptionally (處理失敗):

createResource(doc).thenAccept { resource ->updateToProcessed(doc, resource)}.exceptionally { e ->updateToFailed(doc, e)}

CompletableFuture#exceptionally方法接受一個帶有我們實際失敗原因的異常e的函數。

您可能會想: tomayto,tomahto。 首先,我們進行了try-catch ,現在我們進行了thenAccept-exceptionally ,那么有什么大不同?

好吧,我們顯然不能擺脫特殊情況,但我們現在正在像Functionalville的居民那樣思考:我們的方法開始成為函數 ,告訴我們有什么東西有事。

考慮到這是我們在第4部分中需要進行的少量重構,而在第5部分中,甚至更多地限制了代碼中的副作用。

現在就這樣

作為參考,這是重構代碼的完整版本。

class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {changes.findAll { doc -> isImportant(doc) }.each { doc ->createResource(doc).thenAccept { resource ->updateToProcessed(doc, resource)}.exceptionally { e ->updateToFailed(doc, e)}}}private CompletableFuture<Resource> createResource(doc) {webservice.create(doc)}private boolean isImportant(doc) {doc.type == 'important'}private void updateToProcessed(doc, resource) {doc.apiId = resource.iddoc.status = 'processed'documentDb.update(doc)}private void updateToFailed(doc, e) {doc.status = 'failed'doc.error = e.messagedocumentDb.update(doc)}}

-

翻譯自: https://www.javacodegeeks.com/2018/01/functional-java-example-part-3-dont-use-exceptions-control-flow.html

總結

以上是生活随笔為你收集整理的功能Java示例 第3部分–不要使用异常来控制流程的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 午夜视频在线瓜伦 | av在线观看地址 | 一区二区在线视频 | 激情文学久久 | 国产v亚洲v天堂无码 | 九九热视频精品 | 亚洲三级视频 | 久久大胆视频 | 免费看黄色一级大片 | 日韩av不卡在线播放 | 在线观看污| 热99精品视频 | 黄片毛片在线 | 国产欧美日韩激情 | 日日摸日日添日日碰9学生露脸 | 国产在线视频一区二区三区 | 在线观看国产一区二区 | 亚洲欧美强伦一区二区 | 性欧美在线观看 | 久久在线观看 | 久久国产精品久久精品国产 | 国产无遮挡又黄又爽又色视频 | 播色屋| 欧美成年人在线观看 | 性高湖久久久久久久久免费 | n0659极腔濑亚美莉在线播放播放 | 女性向小h片资源在线观看 日本天天操 | 久久久久欧美 | 综合视频在线观看 | 日本丰满大乳奶做爰 | 午夜鲁鲁| av成人在线播放 | 国产叼嘿视频在线观看 | 婷婷超碰| 色就是色网站 | 欧美三级视频网站 | 国产aaa视频 | 日韩av在线导航 | 国产黄色片免费观看 | 欧美性一区二区 | 久久国语对白 | 大桥未久视频在线观看 | 91狠狠干 | 日韩三级一区二区三区 | 国产人人看 | 亚洲一区二区三区观看 | 三上悠亚在线一区 | 精品无码免费视频 | 日本乱偷中文字幕 | 欧美精品videos另类日本 | 国产日本在线观看 | 成人国产av一区二区三区 | 91丨国产丨捆绑调教 | 精品一区二区三区不卡 | 亚洲精品白浆高清久久久久久 | 国产丝袜视频在线 | 婷婷狠狠操 | 黑人高潮一区二区三区在线看 | 欧美在线观看一区二区三区 | 国产aa毛片| 亚洲人成无码www久久久 | 成人深夜影院 | 51精产品一区一区三区 | 日韩夜夜高潮夜夜爽无码 | 日本黄色大片视频 | 中文字幕在线不卡 | 中文字幕免费高清视频 | 黄污视频网站 | 黄毛片在线观看 | 黄色三级免费网站 | 男人的天堂久久 | 精品福利在线视频 | 久久久久99精品成人片试看 | 无码粉嫩虎白一线天在线观看 | 国产在线精品一区二区三区 | 亚洲五码在线 | 丁香午夜| 神宫寺奈绪一区二区三区 | 精品一区二区三区四区 | 亚洲精品久久夜色撩人男男小说 | 岳狂躁岳丰满少妇大叫 | 国产黄色av网站 | 蜜臀久久99精品久久久久久宅男 | 中文乱码人妻一区二区三区视频 | 91在线资源 | 中出一区 | 2023天天操 | 五月婷婷丁香在线 | 玖玖视频| 欧美三级网站在线观看 | 日韩亚洲欧美在线 | 不卡视频国产 | 新97超碰 | 日韩r级电影在线观看 | 免费成人深夜夜国外 | 国产成人在线看 | 免费看黄在线观看 | 亚洲骚片| 久久综合资源 |