Bắt nhiều ngoại lệ trong Java

Feb 17 2023
Để xử lý nhiều ngoại lệ trong java, chúng ta có thể: Nhiều khối bắt Trong Java, một khối thử có thể có nhiều khối bắt. Tại sao chúng ta cần nhiều khối bắt trong Java? Nhiều khối bắt trong Java được sử dụng để xử lý các loại ngoại lệ khác nhau.

Để xử lý nhiều ngoại lệ trong java, chúng ta có thể:

  • Sử dụng nhiều khối bắt: Tại đây, bạn có thể xử lý nhiều ngoại lệ trong nhiều khối bắt cho một khối thử tương ứng. Luồng chương trình sẽ tự động đến từng khối bắt và sau đó, khối bắt tương ứng được tìm thấy theo ngoại lệ và sẽ được xử lý tương ứng.
  • Sử dụng nhiều câu lệnh bắt trong các đối số của một khối bắt: Tính năng này có từ Java 7. Tại đây, bạn có thể xử lý nhiều ngoại lệ trong một khối bắt duy nhất (được phân tách bằng dấu gạch ngang) cho một khối thử tương ứng. Luồng chương trình sẽ tự động đến khối catch và sau đó, ngoại lệ tương ứng bên trong các đối số của khối catch được tìm thấy cho khối try và sẽ được xử lý tương ứng.

Nhiều khối bắt

Trong Java, một khối thử có thể có nhiều khối bắt.

Tại sao chúng ta cần nhiều khối bắt trong Java?

Nhiều khối bắt trong Java được sử dụng để xử lý các loại ngoại lệ khác nhau. Khi các câu lệnh trong một khối thử tạo ra nhiều ngoại lệ, chúng tôi yêu cầu nhiều khối bắt để xử lý các loại ngoại lệ khác nhau. Cơ chế này được gọi là khối đa bắt trong java .

Một khối thử có thể được theo sau bởi một hoặc nhiều khối bắt. Mỗi khối bắt phải chứa một trình xử lý ngoại lệ khác. Bạn có thể bắt các ngoại lệ khác nhau trong các khối bắt khác nhau nếu nó chứa một trình xử lý ngoại lệ khác. Khi một ngoại lệ xảy ra trong khối thử, khối bắt tương ứng xử lý ngoại lệ cụ thể đó sẽ thực thi. Vì vậy, nếu bạn phải thực hiện các tác vụ khác nhau khi xảy ra các ngoại lệ khác nhau, bạn có thể sử dụng lệnh bắt nhiều lần trong Java.

cú pháp

Cú pháp sử dụng một lần thử với nhiều hơn một khối catch trong java như sau:

try 
{ 
  statements; 
} 
catch(ExceptionType1 e1) 
{ 
  statements; 
} 
catch(ExceptionType2 e2) 
{ 
  statements; 
}

Trong trường hợp, đối tượng ngoại lệ được ném không khớp với khối bắt đầu tiên, khối bắt thứ hai sẽ kiểm tra, v.v.

Tại một thời điểm chỉ có một ngoại lệ xảy ra và tại một thời điểm chỉ có một khối lệnh bắt được thực thi. Tất cả các khối bắt phải được sắp xếp theo cách mà ngoại lệ phải đến từ lớp con đầu tiên và sau đó là lớp cha, tức là bắt cho ArithmeticException phải đến trước bắt cho Ngoại lệ.

Lưu đồ khối đa bắt

ví dụ

ví dụ 1

class Main {
  public static void main(String[] args) {
    try {
      int array[] = new int[10];
      array[10] = 30 / 0;
    } catch (ArithmeticException e) {
      System.out.println(e.getMessage());
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println(e.getMessage());
    } 
  }
}

/ by zero

  • ArithmeticException vì chúng ta đang cố chia một số cho 0.
  • ArrayIndexOutOfBoundException vì chúng tôi đã khai báo một mảng số nguyên mới với giới hạn mảng từ 0 đến 9 và chúng tôi đang cố gán giá trị cho chỉ mục 10.

Tính kết hợp của toán tử gán = là từ phải sang trái, do đó, ArithmeticException được đưa ra đầu tiên với thông báo / bằng 0.

ví dụ 2

class Example2{
   public static void main(String args[]){
     try{
         int a[]=new int[7];
         a[4]=30/0;
         System.out.println("First print statement in try block");
     }
     catch(ArithmeticException e){
        System.out.println("Warning: ArithmeticException");
     }
     catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Warning: ArrayIndexOutOfBoundsException");
     }
     catch(Exception e){
        System.out.println("Warning: Some Other exception");
     }
   System.out.println("Out of try-catch block...");
  }
}

Warning: ArithmeticException
Out of try-catch block...

Bắt nhiều hơn một loại ngoại lệ với một trình xử lý ngoại lệ

Trong Java 7 trở lên, khối catch đã được cải thiện để xử lý nhiều ngoại lệ trong một khối catch . Nếu bạn đang bắt gặp nhiều ngoại lệ và chúng có mã tương tự nhau.

Một khối bắt duy nhất có khả năng xử lý (bắt) nhiều ngoại lệ bằng cách tách từng ngoại lệ bằng | (ký hiệu ống) trong khối bắt .

Tính năng này có thể giảm trùng lặp mã và tăng hiệu quả đồng thời giảm bớt sự cám dỗ để bắt một ngoại lệ quá rộng.. Mã byte được tạo trong khi biên dịch chương trình này sẽ nhỏ hơn chương trình có nhiều khối bắt vì không có dự phòng mã.

Xem xét ví dụ sau, chứa mã trùng lặp trong mỗi khối catch :

catch (IOException ex) {
     logger.log(ex);
     ex.printStackTrace();
catch (SQLException ex) {
     logger.log(ex);
     ex.printStackTrace();
}

Trong Java SE 7 trở lên, chúng ta có thể loại bỏ mã trùng lặp bằng cách sử dụng approch này

cú pháp

Trong catchmệnh đề, hãy chỉ định loại ngoại lệ mà khối có thể xử lý và phân tách từng loại ngoại lệ bằng một thanh dọc ( |):

try {
  // code
} catch (ExceptionType1 | Exceptiontype2 ex) { 
  // catch block
}

ví dụ

ví dụ 1

class Main {
  public static void main(String[] args) {
    try {
      int array[] = new int[10];
      array[10] = 30 / 0;
    } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
      System.out.println(e.getMessage());
    }
  }
}

/ by zero

Mã byte được tạo trong khi biên dịch chương trình này sẽ nhỏ hơn chương trình có nhiều khối bắt vì không có dự phòng mã.

Lưu ý : Nếu một khối catch xử lý nhiều hơn một loại ngoại lệ, thì tham số catch hoàn toàn là final . Trong ví dụ này, tham số catch ex là cuối cùng và do đó bạn không thể gán bất kỳ giá trị nào cho nó trong khối catch .

Sự chấp thuận này thường được sử dụng nếu bạn đang bắt gặp nhiều ngoại lệ và chúng có mã tương tự nhau. nhưng chúng ta cũng có thể sử dụng nó theo ý muốn.

ví dụ 2

class Main {
  public static void main(String[] args) {
    try {
      int array[] = new int[10];
      array[10] = 30 / 0;
    } catch (ArithmeticException|ArrayIndexOutOfBoundsException e) {
      if (e instanceof ArithmeticException)
          System.out.println("ArithmeticException");
      else
          System.out.println("ArrayIndexOutOfBoundsException");
    }
  }
}

Khi bắt nhiều ngoại lệ trong một khối bắt duy nhất , quy tắc được tổng quát hóa thành chuyên biệt.

Điều này có nghĩa là nếu có một hệ thống phân cấp các ngoại lệ trong khối bắt , chúng ta chỉ có thể bắt ngoại lệ cơ sở thay vì bắt nhiều ngoại lệ chuyên biệt.

Hãy lấy một ví dụ.

Ví dụ 1: Chỉ bắt lớp ngoại lệ cơ sở

class Main {
  public static void main(String[] args) {
    try {
      int array[] = new int[10];
      array[10] = 30 / 0;
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }
}

/ by zero

Nếu lớp ngoại lệ cơ sở đã được chỉ định trong khối bắt , không sử dụng các lớp ngoại lệ con trong cùng một khối bắt . Nếu không, chúng ta sẽ gặp lỗi biên dịch.

Hãy lấy một ví dụ.

Ví dụ 2: Bắt các lớp ngoại lệ cơ sở và con

class Main {
  public static void main(String[] args) {
    try {
      int array[] = new int[10];
      array[10] = 30 / 0;
    } catch (Exception | ArithmeticException | ArrayIndexOutOfBoundsException e) {
      System.out.println(e.getMessage());
    }
  }
}

Main.java:6: error: Alternatives in a multi-catch statement cannot be related by subclassing

Chương trình

Trong một số trường hợp, một đoạn mã có thể đưa ra nhiều ngoại lệ. Để xử lý loại tình huống này, bạn có thể chỉ định hai hoặc nhiều mệnh đề bắt, mỗi mệnh đề bắt một loại ngoại lệ khác nhau. Khi một ngoại lệ được ném ra, mỗi câu lệnh bắt được kiểm tra theo thứ tự và câu lệnh đầu tiên có loại khớp với câu lệnh của ngoại lệ sẽ được thực thi. Sau khi một câu lệnh catch được thực thi, các câu lệnh khác sẽ bị bỏ qua và quá trình thực thi tiếp tục sau khối try/catch. Ví dụ sau bẫy hai loại ngoại lệ khác nhau:

// Demonstrate multiple catch statements.
class MultiCatch {
public static void main(String args[]) {
try {
    int a = args.length;
    System.out.println("a = " + a);
    int b = 42 / a;
    int c[] = { 1 };
    c[42] = 99;
} catch(ArithmeticException e) {
    System.out.println("Divide by 0: " + e);
} catch(ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks.");
}
}

Đây là đầu ra được tạo bằng cách chạy theo cả hai cách:

C:\>java MultiCatch
a = 0
Divide by 0: java.lang.ArithmeticException: / by zero
After try/catch blocks.
C:\>java MultiCatch TestArg
a = 1
Array index oob: java.lang.ArrayIndexOutOfBoundsException:42
After try/catch blocks.

/* This program contains an error.
A subclass must come before its superclass in
a series of catch statements. If not,
unreachable code will be created and a
compile-time error will result.
*/
class SuperSubCatch {
public static void main(String args[]) {
    try {
        int a = 0;
        int b = 42 / a;
    } catch(Exception e) {
        System.out.println("Generic Exception catch.");
    }
    /* This catch is never reached because
    ArithmeticException is a subclass of Exception. */
    catch(ArithmeticException e) { // ERROR - unreachable
        System.out.println("This is never reached.");
    }
}
}

Tham gia nhóm Mouad Oumous Java WhatsApp THAM GIA

Tham gia kênh Telegram Mouad Oumous THAM GIA

Semaphore | Java Concurrent API Các gói Java Concurrent API — Phần 1 Java — 8 | Giao diện BiFunction, BiConsumer & BiPredicate với ví dụ