1. Từ khóa throws trong Java

Từ khóa Throws trong Java cũng dùng để khai báo một ngoại lệ. Nó giúp cung cấp thông tin cho ta rằng có thể xảy ra một ngoại lệ. Chúng ta sử dụng từ khóa Throws trong khai báo phương thức để khai báo kiểu loại ngoại lệ mà có thể xảy ra bên trong. Nếu một phương thức không xử lý một ngoại lệ đã kiểm tra thì phương thức đó phải khai báo ngoại lệ bằng từ khóa Throws. Từ khóa Throws được khai báo ở cuối dấu ngoặc ( ) trước khi bắt đầu một phương thức.
Trong một chương trình nếu có khả năng phát sinh một ngoại lệ thì trình biên dịch luôn cảnh báo chúng ta về điều đó và bắt buộc chúng ta phải xử lý ngoại lệ đã kiểm tra đó. Nếu không chúng ta sẽ gặp lỗi thời trong thời gian biên dịch nói rằng ngoại lệ chưa xử lý. Exception Handling chủ yếu được sử dụng để xử lý ngoại lệ checked. Nếu xảy ra bất kỳ ngoại lệ unchecked (ngoại lệ không được kiểm tra) như NullPointerException, đó là lỗi của chính ta không thực hiện kiểm tra trước khi code được sử dụng.

Cú pháp của Throws trong Java:

return_type method_name() throws exception_class_name {  
    / /method code
}

Ví dụ:

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
       FileOutputStream fileOutputStream = null;
       fileOutputStream = new FileOutputStream("D://output.txt");
       fileOutputStream.write(65);
    }
}

Ở ví dụ trên phương thức main đã khai báo bỏ qua ngoại lệ IOException nên chương trình trên vẫn chạy bình thường. Vậy ngoại lệ nào nên được khai báo? Ta chỉ nên khai báo ngoại lệ checked (ngoại lệ đã được kiểm tra). Vì ngoại lệ unchecked đã nằm trong sự kiểm soát của ta. Tiếp theo nữa với error ta sẽ không thể kiểm soát được nó. Ví dụ ta sẽ không thể làm được bất kì điều gì khi các lỗi VirtualMachineError hoặc StackOverflowError xảy ra.

Ta cũng có thể khai báo bỏ qua nhiều ngoại lệ bằng cách khai báo các ngoại lệ sau từ khóa throws cách nhau bởi dấu phẩy.

public void withdraw(int n) throws RemoteException, 
      InsufficientFundsException {
      //code
   }

2. Ví dụ về throws trong Java

Ví dụ về ngoại lệ checked có thể được truyền ra bằng từ khóa Throws.

import java.io.*;

class Main {
    public static void ghi_file() throws IOException {
        File f = new File("abc.txt");
        FileInputStream stream=new FileInputStream(f);
    }
    public static void main(String[] args) {
        try{
            ghi_file();
        }
        catch(IOException a){
            System.out.println(a);
        }
    }
}

Kết quả

java.io.FileNotFoundException: abc.txt (No such file or directory)

Khi chúng ta chạy chương trình, vì file abc.txt không tồn tại, FileInputStream sẽ truyền một ngoại lệ FileNotFoundException. Nếu một phương thức không xử lý các ngoại lệ, thì ngoại lệ có thể xảy ra bên trong nó phải được chỉ định trong mệnh đề Throws để các phương thức trong ngăn xếp đằng sau có thể xử lý hoặc xác định nó bằng cách sử dụng từ khóa Throws. Phương thức ghi_file() chỉ định rằng một IOException có thể được truyền. Phương thức main() thực hiện lời gọi phương thức này và xử lý ngoại lệ nếu nó được truyền.

Và nếu ta đang gọi một phương thức khai báo Throws một ngoại lệ ta phải bắt hoặc Throws ngoại lệ đó. Có 2 cách là:

  • Ta đã bắt ngoại lệ, tức là xử lý ngoại lệ bằng cách sử dụng try catch . Code sẽ thực thi tốt dù ngoại lệ có xảy ra hay không
  • Ta khai báo ném ngoại lệ, tức là sử dụng từ khóa Throws với phương thức. Code sẽ thực thi tốt nếu ngoại lệ không xảy ra. Nếu ngoại lệ xảy ra một ngoại lệ sẽ được ném ra tại runtime vì throws nên không xử lý ngoại đó.

Xử lý ngoại lệ với try catch

import java.io.IOException;
 
class M {
    void method() throws IOException {
        throw new IOException("Gặp lỗi");
    }
}
 
public class Main {
    public static void main(String args[]) {
        try {
            M m = new M();
            m.method();
        } catch (Exception e) {
            System.out.println("Ngoại lệ được xử lý");
        }
 
        System.out.println("laptrinhtudau.com");
    }
}

Kết quả

Ngoại lệ được xử lý
laptrinhtudau.com

Khai báo Throws ngoại lệ

import java.io.IOException;
 
class M {
    void method() throws IOException {
        System.out.println("Bạn đã đúng");
    }
}
 
public class Main {
    public static void main(String args[]) throws IOException {
        M m = new M();
        m.method();
        System.out.println("laptrinhtudau.com");
    }
}

Kết quả

Bạn đã đúng
laptrinhtudau.com

Đây là trường hợp tốt nhất khi không có ngoại lệ xảy ra. Nếu có ngoại lệ xảy ra thì một ngoại lệ khác được ném ra

import java.io.IOException;
 
class M {
    void method() throws IOException {
        throw new IOException("Gặp lỗi");
    }
}
 
public class Main {
    public static void main(String args[]) throws IOException {
        M m = new M();
        m.method();
        System.out.println("laptrinhtudau.com");
    }
}

Kết quả

Exception in thread "main" java.io.IOException: Gặp lỗi
    at M.method(Main.java:5)
    at Main.main(Main.java:12)

3. Sự khác nhau giữa throw và throws trong Java

Dù chỉ khác nhau một chữ s ở cuối nhưng 2 từ khóa này có công dụng cũng như cách sử dụng khác nhau trong Java. Các bạn có thể tham khảo bảng so sánh Throw và Throws sau:

Throw Throws
Từ khóa Throw trong Java được sử dụng để ném ra một ngoại lệ rõ ràng. Từ khóa Throws trong java được sử dụng để khai báo một ngoại lệ.
Ngoại lệ checked không được truyền ra nếu chỉ sử dụng từ khóa Throw. Ngoại lệ checked được truyền ra ngay cả khi chỉ sử dụng từ khóa Throws.
Sau Throw là một instance Sau Throws là một hoặc nhiều class.
Throw được sử dụng trong phương thức có thể quăng ra Exception ở bất kỳ dòng nào trong phương thức (sau đó dùng try catch để bắt hoặc Throws cho thằng khác sử lý) Throws được khai báo ngay sau dấu đóng ngoặc đơn của phương thức. Khi một phương thức có Throw bên trong mà không bắt lại (try catch) thì phải ném đi (throws) cho thằng khác xử lý.
Không thể Throw nhiều Exceptions. Có thể khai báo nhiều Exceptions, Ví dụ: public void method() throws IOException, SQLException { }