CodeGym/Blog Java/Ngẫu nhiên/Ngoại lệ trong Java

Ngoại lệ trong Java

Xuất bản trong nhóm
Xin chào! Trong bài học hôm nay, chúng ta sẽ nói về Java Exceptions. Cuộc sống hàng ngày đầy rẫy những tình huống mà chúng ta không lường trước được. Ví dụ, bạn thức dậy đi làm vào buổi sáng và tìm bộ sạc điện thoại nhưng không thấy đâu cả. Bạn vào phòng tắm để tắm và phát hiện ra rằng các đường ống đã bị đóng băng. Bạn vào trong xe của bạn, nhưng nó sẽ không bắt đầu. Một con người có thể đối phó với những tình huống không lường trước như vậy khá dễ dàng. Trong bài viết này, chúng ta sẽ cố gắng tìm hiểu xem các chương trình Java xử lý chúng như thế nào.

Ngoại lệ Java là gì?

Trong thế giới lập trình, các lỗi và tình huống không lường trước được khi thực hiện chương trình được gọi là ngoại lệ. Trong một chương trình, các ngoại lệ có thể xảy ra do hành động của người dùng không hợp lệ, không đủ dung lượng ổ đĩa hoặc mất kết nối mạng với máy chủ. Các ngoại lệ cũng có thể do lỗi lập trình hoặc sử dụng API không chính xác. Không giống như con người trong thế giới thực, một chương trình phải biết chính xác cách xử lý những tình huống này. Đối với điều này, Java có một cơ chế được gọi là xử lý ngoại lệ.

Một vài từ về từ khóa

Xử lý ngoại lệ trong Java dựa trên việc sử dụng các từ khóa sau trong chương trình:
  • try - xác định một khối mã nơi có thể xảy ra ngoại lệ;
  • bắt - xác định một khối mã xử lý các ngoại lệ;
  • cuối cùng - xác định một khối mã tùy chọn, nếu có, sẽ được thực thi bất kể kết quả của khối thử.
Những từ khóa này được sử dụng để tạo các cấu trúc đặc biệt trong mã: try{}catch , try{}catch{}finally , try{}finally{} .
  • ném - được sử dụng để đưa ra một ngoại lệ;
  • ném - được sử dụng trong chữ ký phương thức để cảnh báo rằng phương thức có thể đưa ra một ngoại lệ.
Một ví dụ về việc sử dụng từ khóa trong chương trình Java:
// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

Tại sao chúng ta cần ngoại lệ?

Hãy xem xét một ví dụ từ thế giới thực. Hãy tưởng tượng rằng một phần của đường cao tốc có một cây cầu nhỏ với trọng lượng hạn chế. Nếu một chiếc ô tô nặng hơn giới hạn của cây cầu chạy qua nó, nó có thể bị sập. Nói một cách nhẹ nhàng, tình huống đối với người lái xe sẽ trở nên đặc biệt. Để tránh điều này, bộ giao thông vận tải đã lắp đặt các biển cảnh báo trên đường trước khi xảy ra sự cố. Nhìn thấy biển cảnh báo, người lái xe so sánh trọng lượng xe của mình với trọng lượng tối đa của cây cầu. Nếu xe quá nặng, tài xế đi đường vòng. Đầu tiên, bộ giao thông vận tải cho phép các tài xế xe tải thay đổi lộ trình nếu cần thiết, thứ hai, cảnh báo các tài xế về những nguy hiểm trên đường chính và thứ ba, cảnh báo các tài xế rằng không được sử dụng cây cầu trong một số điều kiện nhất định. Ngoại lệ trong Java - 2Khả năng ngăn chặn và giải quyết các tình huống ngoại lệ trong chương trình, cho phép chương trình tiếp tục chạy, là một lý do để sử dụng ngoại lệ trong Java. Cơ chế ngoại lệ cũng cho phép bạn bảo vệ mã (API) của mình khỏi việc sử dụng không đúng cách bằng cách xác thực (kiểm tra) bất kỳ thông tin đầu vào nào. Bây giờ hãy tưởng tượng rằng bạn là bộ phận giao thông vận tải trong một giây. Trước tiên, bạn cần biết những nơi mà người lái xe có thể gặp rắc rối. Thứ hai, bạn cần tạo và cài đặt các dấu hiệu cảnh báo. Và cuối cùng, bạn cần cung cấp các đường vòng nếu có vấn đề phát sinh trên tuyến đường chính. Trong Java, cơ chế ngoại lệ hoạt động theo cách tương tự. Trong quá trình phát triển, chúng tôi sử dụng khối thử để xây dựng "các rào cản ngoại lệ" xung quanh các phần mã nguy hiểm, chúng tôi cung cấp "các tuyến dự phòng" bằng cách sử dụng lệnh bắt {}và chúng tôi viết mã sẽ chạy bất kể nội dung gì trong khối finally{} . Nếu chúng tôi không thể cung cấp "lộ trình dự phòng" hoặc chúng tôi muốn cho người dùng quyền lựa chọn, thì ít nhất chúng tôi phải cảnh báo họ về mối nguy hiểm. Tại sao? Chỉ cần tưởng tượng sự phẫn nộ của một người lái xe, người mà không nhìn thấy một dấu hiệu cảnh báo nào, đã đến một cây cầu nhỏ mà anh ta không thể đi qua! Trong lập trình, khi viết các lớp và phương thức của mình, không phải lúc nào chúng ta cũng có thể thấy trước cách các nhà phát triển khác có thể sử dụng chúng. Do đó, chúng tôi không thể thấy trước cách chính xác 100% để giải quyết một tình huống ngoại lệ. Điều đó nói rằng, đó là hình thức tốt để cảnh báo những người khác về khả năng xảy ra các tình huống đặc biệt. Cơ chế ngoại lệ của Java cho phép chúng tôi thực hiện điều này với các cú némtừ khóa - về cơ bản là một tuyên bố rằng hành vi chung của phương thức của chúng tôi bao gồm đưa ra một ngoại lệ. Do đó, bất kỳ ai sử dụng phương pháp này đều biết mình nên viết mã để xử lý các ngoại lệ.

Cảnh báo người khác về "rắc rối"

Nếu bạn không có kế hoạch xử lý các ngoại lệ trong phương pháp của mình, nhưng muốn cảnh báo những người khác rằng các ngoại lệ có thể xảy ra, hãy sử dụng từ khóa ném . Từ khóa này trong chữ ký phương thức có nghĩa là, trong một số điều kiện nhất định, phương thức có thể đưa ra một ngoại lệ. Cảnh báo này là một phần của giao diện phương pháp và cho phép người dùng thực hiện logic xử lý ngoại lệ của riêng họ. Sau khi ném, chúng tôi chỉ định các loại ngoại lệ được ném. Chúng thường xuất phát từ lớp Ngoại lệ của Java . Vì Java là ngôn ngữ hướng đối tượng nên tất cả các ngoại lệ đều là đối tượng trong Java. Ngoại lệ trong Java - 3

phân cấp ngoại lệ

Khi xảy ra lỗi trong khi chương trình đang chạy, JVM sẽ tạo một đối tượng thuộc loại thích hợp từ hệ thống phân cấp ngoại lệ Java — một tập hợp các ngoại lệ có thể xuất phát từ một tổ tiên chung — lớp Có thể ném được . Chúng ta có thể chia các tình huống thời gian chạy đặc biệt thành hai nhóm:
  1. Các tình huống mà chương trình không thể phục hồi và tiếp tục hoạt động bình thường.
  2. Các tình huống có thể phục hồi.
Nhóm đầu tiên bao gồm các tình huống liên quan đến một ngoại lệ xuất phát từ lớp Lỗi . Đây là những lỗi xảy ra do sự cố JVM, tràn bộ nhớ hoặc lỗi hệ thống. Chúng thường chỉ ra các sự cố nghiêm trọng mà phần mềm không thể khắc phục được. Trong Java, khả năng xảy ra các ngoại lệ như vậy không được trình biên dịch kiểm tra, vì vậy chúng được gọi là các ngoại lệ không được kiểm tra. Nhóm này cũng bao gồm RuntimeExceptions, là những ngoại lệ xuất phát từ Exceptionlớp và được tạo bởi JVM trong thời gian chạy. Chúng thường do lỗi lập trình gây ra. Các ngoại lệ này cũng không được kiểm tra (unchecked) lúc biên dịch, do đó bạn không bắt buộc phải viết mã để xử lý chúng. Nhóm thứ hai bao gồm các tình huống ngoại lệ có thể thấy trước khi bạn viết chương trình (và do đó bạn nên viết mã để xử lý chúng). Những ngoại lệ như vậy được gọi là ngoại lệ được kiểm tra. Khi nói đến các trường hợp ngoại lệ, hầu hết công việc của nhà phát triển Java là xử lý các tình huống như vậy.

Tạo một ngoại lệ

Khi một chương trình chạy, các ngoại lệ được tạo bởi JVM hoặc thủ công bằng cách sử dụng câu lệnh ném . Khi điều này xảy ra, một đối tượng ngoại lệ được tạo trong bộ nhớ, luồng chính của chương trình bị gián đoạn và trình xử lý ngoại lệ của JVM cố gắng xử lý ngoại lệ.

xử lý ngoại lệ

Trong Java, chúng tôi tạo các khối mã mà chúng tôi dự đoán nhu cầu xử lý ngoại lệ bằng cách sử dụng các cấu trúc try{}catch , try{}catch{}finallytry{}finally{} . Ngoại lệ trong Java - 4Khi một ngoại lệ được ném vào một khối thử , JVM sẽ tìm kiếm một trình xử lý ngoại lệ thích hợp trong khối bắt tiếp theo . Nếu một khối bắt có trình xử lý ngoại lệ được yêu cầu, thì quyền kiểm soát sẽ chuyển đến khối đó. Nếu không, thì JVM sẽ tìm kiếm sâu hơn trong chuỗi các khối catch cho đến khi tìm thấy trình xử lý thích hợp. Sau khi thực hiện khối bắt , quyền điều khiển được chuyển sang khối cuối cùng tùy chọn . Nếu đánh bắt phù hợpkhông tìm thấy khối, thì JVM sẽ dừng chương trình và hiển thị dấu vết ngăn xếp (ngăn lệnh gọi phương thức hiện tại), sau lần đầu tiên thực hiện khối cuối cùng nếu nó tồn tại. Ví dụ về xử lý ngoại lệ:
public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
Đây là kết quả của phương pháp chính :
Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
Cuối cùng thường được sử dụng để đóng bất kỳ luồng nào và giải phóng mọi tài nguyên được mở/phân bổ trong một khối thử . Tuy nhiên, khi viết một chương trình, không phải lúc nào bạn cũng có thể theo dõi việc đóng tất cả các tài nguyên. Để làm cho cuộc sống của chúng ta dễ dàng hơn, các nhà phát triển Java cung cấp cấu trúc dùng thử tài nguyên , cấu trúc này sẽ tự động đóng bất kỳ tài nguyên nào được mở trong một khối thử . Ví dụ đầu tiên của chúng ta có thể được viết lại bằng try-with-resources :
public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
Nhờ các khả năng của Java được giới thiệu trong phiên bản 7, chúng tôi cũng có thể kết hợp việc bắt các ngoại lệ không đồng nhất thành một khối, làm cho mã trở nên gọn gàng và dễ đọc hơn. Ví dụ:
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Điểm mấu chốt

Việc sử dụng ngoại lệ trong Java cho phép bạn làm cho chương trình của mình mạnh mẽ hơn bằng cách tạo "các tuyến dự phòng", sử dụng các khối catch để tách mã chính khỏi mã xử lý ngoại lệ và sử dụng lệnh ném để chuyển trách nhiệm xử lý ngoại lệ cho bất kỳ ai sử dụng phương thức của bạn .
Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào