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

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

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

將討論一個非常重要的主題-JAVA 中的異常處理。盡管有時可能會對此主題進行過多的討論,但并非每篇文章都包含有用且相關的信息。

Java 中最常見的異常處理機制通常與 try-catch 塊關聯 。我們使用它來捕獲異常,然后提供在發生異常的情況下可以執行的邏輯。

的確,你不需要將所有異常都放在這些塊中。另一方面,如果你正在研究應用程序的軟件設計,則可能不需要內置的異常處理機制。在這種情況下,你可以嘗試使用替代方法-Vavr Try 結構。

在本文中,我們將探討 Java 異常處理的不同方法,并討論如何使用 Vavr Try 替代內置方法。讓我們開始吧!

處理 Java 中的異常

作為介紹,讓我們回顧一下 Java 如何允許我們處理異常。如果你不記得它,則 Java 中的異常會指出意外或意外事件,該異常在程序執行期間(即在運行時)發生,這會破壞程序指令的正常流程。Java為我們提供了上述 try-catch 捕獲異常的機制。讓我們簡要檢查一下它是如何工作的。

如果不處理異常會發生什么?

首先,讓我們看一個非常常見的例子。這是一個包含 JDBC 代碼的代碼段:

Connection connection = dataSource.getConnection();
String updateNameSql = "UPDATE employees SET name=? WHERE emp_id=?";
PreparedStatement preparedStatement = connection.prepareStatement(updateNameSql);

坦白地說,你的 IDE 甚至不允許你編寫這段代碼,而是要求用 try-catch 塊將其包圍,像這樣:

try {
 Connection connection = dataSource.getConnection();
 String updateNameSql = "UPDATE employees SET name=? WHERE emp_id=?";
 PreparedStatement preparedStatement = connection.prepareStatement(updateNameSql);
} catch (SQLException ex){
}

注:我們可以將其重構為 try-with-resources,但是稍后再討論。

那么,為什么我們要這樣編寫代碼?因為 SQLException 是一個檢查異常。

如果這些異??梢杂煞椒ɑ驑嬙旌瘮档膱绦袙伋霾鞑サ椒椒ɑ驑嬙旌瘮颠吔缰?,則必須在方法或構造函數的 throws 子句中聲明這些異常。SQLException 如果發生數據庫訪問錯誤,則在示例中使用的方法將拋出 。因此,我們用一個 try-catch 塊將其包圍。

Java 在編譯過程中驗證了這些異常,這就是它們與運行時異常不同的原因。

但是你不必處理所有異常情況

但是,并非每個異常都應被一個 try-catch 塊包圍。

情況 1:運行時異常

Java 異常是 Throwable 的子類,但是其中一些是 RuntimeException 類的子類??聪旅娴膱D,它給出了 Java 異常的層次結構:

Java異常處理只有Try-Catch嗎?

 

請注意,運行時異常是特定的組。根據 Java 規范,從這些異常中還是有可能恢復的。作為示例,讓我們回想一下 ArrayIndexOutOfBoundsException??纯聪旅娴氖纠a片段:

int numbers[] = [1,43,51,0,9];
System.out.println(numbers[6]);

在這里,我們有一個具有5個值(0-4位)的整數數組。當我們嘗試檢索絕對超出范圍的值(索引= 6)時,Java 將拋出 ArrayIndexOutOfBoundsException。

這表明我們嘗試調用的索引為負數,大于或等于數組的大小。如我所說,這些異??梢孕迯?,因此在編譯過程中不會對其進行檢查。這意味著你仍然可以編寫如下代碼:

int numbers[] = [1,43,51,0,9];
int index = 6;
try{
 System.out.println(numbers[index]);
} catch (ArrayIndexOutOfBoundsException ex){
 System.out.println("Incorrect index!");
}

但是你不必這樣做。

情況 2:錯誤

Error 是另一個棘手的概念。再看一下上面的圖-存在錯誤,但是通常不會處理。為什么?通常,這是由于 Java 程序無法執行任何操作來從錯誤中恢復,例如:錯誤表明嚴重的問題,而合理的應用程序甚至不應嘗試捕獲。

讓我們考慮一下內存錯誤– java.lang.VirtualmachineError。此錯誤表明 JVM 已損壞或已經用盡了繼續運行所必需的資源。換句話說,如果應用程序的內存不足,則它根本無法分配額外的內存資源。

當然,如果由于持有大量應釋放的內存而導致失敗,則異常處理程序可以嘗試釋放它(不是直接釋放它本身,而是可以調用JVM來釋放它)。并且,盡管這樣的處理程序在這種情況下可能有用,但是這樣的嘗試可能不會成功。

Try-Catch 塊的變體

上述編寫 try-catch 語句的方法并不是 Java 中唯一可用的方法。還有其他方法:try-with-resources,try-catch-finally 和多個 catch 塊。讓我們快速瀏覽這些不同的方法。

方法 1:Try-With-Resources

try-with-resources 塊在 Java 7 中引入的,并允許開發者在程序運行到此結束后必須關閉聲明的資源。我們可以在實現該 AutoCloseable 接口(即特定標記接口)的任何類中包含資源。我們可以像這樣重構所提到的 JDBC 代碼:

try (Connection connection = dataSource.getConnection){
 String updateNameSql = "UPDATE employees SET name=? WHERE emp_id=?";
 PreparedStatement preparedStatement = connection.prepareStatement(updateNameSql);
} catch (SQLException ex){
//..
}

Java 確保我們 Connection 在執行代碼后將其關閉。在進行此構建之前,我們必須顯式地關閉 finally 塊中的資源。

方法 2:Try + Finally

finally 塊在任何情況下都將執行。例如在成功情況下或在異常情況下。在其中,你需要放置將在之后執行的代碼:

FileReader reader = null;
try {
 reader = new FileReader("/text.txt");
 int i=0;
 while(i != -1){
 i = reader.read();
 System.out.println((char) i);
 }
} catch(IOException ex1){
//...
} finally{
 if(reader != null){
 try {
 reader.close();
 } catch (IOException ex2) {
 //...
 }
 }
}

請注意,此方法有一個缺點:如果在 finally 塊內引發異常 ,則會使其中斷。因此,我們必須正常處理異常。將 try-with-resources 與可關閉的資源一起使用,避免在 finally 塊內關閉資源 。

方法 3:多 Catch 塊

最后,Java 允許我們使用一個 try-catch 塊多次捕獲異常。當方法拋出幾種類型的異常并且您想區分每種情況的邏輯時,這很有用。舉個例子,讓這個虛構的類使用拋出多個異常的方法:

class Repository{
 void insert(Car car) throws DatabaseAccessException, InvalidInputException {
 //...
 }
}
//...
try {
 repository.insert(car);
} catch (DatabaseAccessException dae){
 System.out.println("Database is down!");
} catch (InvalidInputException iie){
 System.out.println("Invalid format of car!");
}

在這里需要記住什么?通常,我們假設在此代碼中,這些異常處于同一級別。但是你必須從最具體到最一般的順序排序 catch 塊。例如,捕獲 ArithmeticException 異常必須在 捕獲 Exception 異常之前。

到這里,我們已經回顧了如何使用內置方法處理 Java 中的異常?,F在,讓我們看一下如何使用 Vavr 庫執行此操作。

Vavr Try

我們回顧了捕獲 Java 異常的標準方法。另一種方法是使用 Vavr Try 類,Vavr 是 Java 8+ 中一個函數式庫,提供了一些不可變數據類型及函數式控制結構。首先,添加 Vavr 庫依賴項:

<dependency>
 <groupId>io.vavr</groupId>
 <artifactId>vavr</artifactId>
 <version>0.10.2</version>
</dependency>

Try 容器

Vavr 包含的 Try 類是 monadic 容器類型,它表示可能導致異常或返回成功計算出的值的計算。此結果可以采用 Success 或 Failure??聪旅孢@段代碼:

class CarsRepository{
 Car insert(Car car) throws DatabaseAccessException {
 //...
 }
 Car find (String id) throws DatabaseAccessException {
 //..
 }
 void update (Car car) throws DatabaseAccessException {
 //..
 }
 void remove (String id) throws DatabaseAccessException {
 //..
 }
}

在調用此代碼時,我們將使用這些 try-catch 塊來處理 DatabaseAccessException。但是另一個解決方案是使用 Vavr 對其進行重構。查看以下代碼片段:

class CarsVavrRepository{
 Try<Car> insert(Car car) {
 System.out.println("Insert a car...");
 return Try.success(car);
 }
 Try<Car> find (String id) {
 System.out.println("Finding a car...");
 System.out.println("..something wrong with database!");
 return Try.failure(new DatabaseAccessException());
 }
 Try<Car> update (Car car) {
 System.out.println("Updating a car...");
 return Try.success(car);
 }
 Try<Void> remove (String id) {
 System.out.println("Removing a car...");
 System.out.println("..something wrong with database!");
 return Try.failure(new DatabaseAccessException());
 }
}

現在,我們可以使用 Vavr 處理數據庫問題。

處理成功

當我們收到成功計算的結果時,我們會收到 Success:

@Test
void successTest(){
 CarsVavrRepository repository = new CarsVavrRepository();
 Car skoda = new Car("skoda", "9T4 4242", "black");
 Car result = repository.insert(skoda).getOrElse(new Car("volkswagen", "3E2 1222", "red"));
 Assertions.assertEquals(skoda.getColor(), result.getColor());
 Assertions.assertEquals(skoda.getId(), result.getId());
}

請注意,Vavr.Try 相較于 Vavr.Option,為我們提供了一種方便的 getOrElse 方法,在發生故障的情況下我們可以使用默認值,我們可以將這種邏輯與有問題的方法結合使用,例如與 find 一起使用。

處理失敗

在另一種情況下,我們將處理 Failure:

@Test
void failureTest(){
 CarsVavrRepository repository = new CarsVavrRepository();
 // desired car
 Car bmw = new Car("bmw", "4A1 2019", "white");
 // failure car
 Car failureCar = new Car("seat", "1A1 3112", "yellow");
 Car result = repository.find("4A1 2019").getOrElse(failureCar);
 Assertions.assertEquals(bmw.getColor(), result.getColor());
 Assertions.assertEquals(bmw.getId(), result.getId());
}

運行此代碼。由于斷言錯誤,該測試將失?。?/p>

org.opentest4j.AssertionFailedError: 
Expected :white
Actual :yellow

這意味著因為我們在 find 方法中對失敗進行了硬編碼 ,所以我們收到了默認值。除了返回默認值之外,我們還可以在發生錯誤的情況下執行其他操作并生成結果。你可以使用鏈接函數 Option 來使您的代碼更具功能性:

repository.insert(bmw).andThen(car -> {
 System.out.println("Car is found "+car.getId());
}).andFinally(()->{
 System.out.println("Finishing");
});

或者,你可以使用收到的異常執行代碼,如下所示:

repository.find("1A9 4312").orElseRun(error->{
 //...
});

一般來說,Vavr Try 是一個功能豐富的解決方案,可用于以更實用的方式轉換代碼庫。毫無疑問,它與其他 Vavr 類(如 Option 或 Collections)結合后,才可以釋放出真正的力量。但是, 如果您想編寫更多的功能樣式的代碼,即使沒有它們,Vavr Try 對于 Java 的 try-catch 塊來說也是一個的正確的替代選擇。

總結

Java 中的異常處理機制通常與 try-catch 塊關聯, 以便捕獲異常并提供發生異常時將要執行的邏輯。同樣,我們確實不需要將所有異常都放入這些塊中。在本文中,我們探討了如何使用 Vavr 庫執行此操作。

分享到:
標簽:Java
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定