日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

JAVA 流不能很好地處理已檢查的異常。在本文中,深入探討如何管理此類問題。

 

Java 引入了檢查異常的概念。與早期的方法相比,強(qiáng)制開發(fā)人員管理異常的想法是革命性的。

如今,Java 仍然是唯一一種提供檢查異常的廣泛使用的語(yǔ)言。例如,Kotlin 中的每個(gè)異常都是未經(jīng)檢查的。

即使在 Java 中,新特性也與受檢異常不一致:Java 內(nèi)置函數(shù)式接口的簽名不使用異常。當(dāng)將遺留代碼集成到 lambda 中時(shí),會(huì)導(dǎo)致代碼繁瑣。這在 Streams 中很明顯。

在這篇文章中,我想深入探討如何處理此類問題。

 

代碼中的問題

 

下面是一個(gè)示例代碼來(lái)說(shuō)明這個(gè)問題:

Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList")
.map(it -> new ForNamer().Apply(it)) // 1
.forEach(System.out::println);

 

  1. 不編譯:需要捕獲已檢查ClassNotFoundException

 

我們必須添加一個(gè) try/catch 塊來(lái)修復(fù)編譯問題。

Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList")
.map(it -> {
try {
return Class.forName(it);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
})
.forEach(System.out::println);

添加塊破壞了易于閱讀的管道的目的。

 

將 Try/Catch 塊封裝到一個(gè)類中

 

為了恢復(fù)可讀性,我們需要重構(gòu)代碼以引入一個(gè)新類。IntelliJ IDEA 甚至提出了一條記錄:

var forNamer = new ForNamer(); // 1
Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList")
.map(forNamer::apply) // 2
.forEach(System.out::println);
record ForNamer() implements Function> {
@Override
public Class apply(String string) {
try {
return Class.forName(string);
} catch (ClassNotFoundException e) {
return null;
}
}
}

 

  1. 創(chuàng)建單個(gè)記錄對(duì)象。
  2. 重復(fù)使用它。
嘗試龍目島

 

Project Lombok 是一個(gè)編譯時(shí)注釋處理器,可生成額外的字節(jié)碼。一個(gè)人使用正確的注釋并獲得結(jié)果,而無(wú)需編寫樣板代碼。

 

Project Lombok 是一個(gè) Java 庫(kù),可自動(dòng)插入您的編輯器和構(gòu)建工具,為您的 Java 增添趣味。永遠(yuǎn)不要再編寫另一個(gè) getter 或 equals 方法,使用一個(gè)注釋,您的類就有一個(gè)功能齊全的構(gòu)建器、自動(dòng)化您的日志記錄變量等等。
-龍目島計(jì)劃

 

Lombok 提供了@SneakyThrow注解:它允許人們拋出已檢查的異常,而無(wú)需在自己的方法簽名中聲明它們。然而,它目前不適用于現(xiàn)有的 API。

如果您是 Lombok 用戶,請(qǐng)注意有一個(gè)已打開的 GitHub 問題,其狀態(tài)為停放。

 

Commons Lang 救援

 

Apache Commons Lang是一個(gè)古老的項(xiàng)目。它在當(dāng)時(shí)很普遍,因?yàn)樗峁┑膶?shí)用程序可能是 Java API 的一部分,但不是。這是一個(gè)比在每個(gè)項(xiàng)目中重新發(fā)明你的DateUtils和更好的選擇。StringUtils在研究這篇文章時(shí),我發(fā)現(xiàn)它仍然定期使用很棒的 API 進(jìn)行維護(hù)。其中之一是FailableAPI。

API 由兩部分組成:

 

  1. 一個(gè)包裝器Stream
  2. 簽名接受異常的管道方法

 

這是一個(gè)小摘錄:

代碼終于變成了我們一開始就期待的樣子:

Stream stream = Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList");
Failable.stream(stream)
.map(Class::forName) // 1
.forEach(System.out::println);

 

修復(fù)編譯時(shí)錯(cuò)誤是不夠的

 

前面的代碼在運(yùn)行時(shí)ClassNotFoundException拋出一個(gè)Wrapped in an 。我們滿足了編譯器,但我們無(wú)法指定預(yù)期的行為:UndeclaredThrowableException

 

  1. 拋出第一個(gè)異常
  2. 丟棄異常
  3. 聚合類和異常,以便我們可以在管道的最后階段對(duì)它們采取行動(dòng)
  4. 別的東西

 

為了實(shí)現(xiàn)這一點(diǎn),我們可以利用 Vavr 的力量。Vavr 是一個(gè)將函數(shù)式編程的強(qiáng)大功能帶入 Java 語(yǔ)言的庫(kù):

 

Vavr 核心是 Java 的函數(shù)庫(kù)。它有助于減少代碼量并增加健壯性。函數(shù)式編程的第一步是開始思考不可變的值。Vavr 提供了不可變的集合以及對(duì)這些值進(jìn)行操作所需的函數(shù)和控制結(jié)構(gòu)。結(jié)果很漂亮,而且很有效。
- Vavr

 

想象一下,我們想要一個(gè)收集異常和類的管道。以下是描述幾個(gè)構(gòu)建塊的 API 摘錄:

它轉(zhuǎn)換為以下代碼:

Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList")

.map(CheckedFunction1.liftTry(Class::forName)) // 1
.map(Try::toEither) // 2
.forEach(e -> {
if (e.isLeft()) { // 3
System.out.println("not found:" + e.getLeft().getMessage());
} else {
System.out.println("class:" + e.get().getName());

  1. 將調(diào)用包裝到 VavrTry中。
  2. 將 轉(zhuǎn)換Try為Either以保留異常。如果我們不感興趣,我們可以使用 anOptional來(lái)代替。
  3. 根據(jù)是否Either包含異常left或預(yù)期結(jié)果right 采取行動(dòng)。

 

到目前為止,我們還停留在 Java Streams 的世界中。它按預(yù)期工作,直到forEach看起來(lái)并不“好”。

Vavr 確實(shí)提供了自己的Stream類,它模仿 Java StreamAPI 并添加了額外的特性。讓我們用它來(lái)重寫管道:

var result = Stream.of("java.lang.String", "ch.frankel.blog.Dummy", "java.util.ArrayList")
.map(CheckedFunction1.liftTry(Class::forName))
.map(Try::toEither)
.partition(Either::isLeft) // 1
.map1(left -> left.map(Either::getLeft)) // 2
.map2(right -> right.map(Either::get)); // 3
result._1().forEach(it -> System.out.println("not found: " + it.getMessage())); // 4
result._2().forEach(it -> System.out.println("class: " + it.getName())); // 4

 

  1. Stream將of劃分Either為兩個(gè)的元組Stream。
  2. 將左側(cè)流從 a Streamof展平Either到 a Streamof Throwable。
  3. 將右流從 a Streamof展平Either到 a Streamof Class。
  4. 做我們想做的任何事。
結(jié)論

Java 的初始設(shè)計(jì)大量使用了檢查異常。編程語(yǔ)言的發(fā)展證明這不是一個(gè)好主意。

Java 流不能很好地處理已檢查的異常。將后者集成到前者所需的代碼看起來(lái)不太好。為了恢復(fù)我們期望的流的可讀性,我們可以依賴 Apache Commons Lang。

匯編只代表了問題的一小部分。我們通常希望對(duì)異常采取行動(dòng),而不是停止管道或忽略異常。在這種情況下,我們可以利用 Vavr 庫(kù),它提供了一種更實(shí)用的方法。

你可以在GitHub上找到這篇文章的源代碼。

分享到:
標(biāo)簽:Lambda
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定