GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Exception Handling Xử lý ngoại lệ trong Java (Exception Handling)

Xử lý ngoại lệ trong Java (Exception Handling)

Đăng vào 06/11/2017 . Được đăng bởi GP Coder . 49440 Lượt xem . Toàn màn hình

Nội dung

  • 1 Ngoại lệ (Exception) là gì?
  • 2 Hệ thống cấp bậc của các lớp ngoại lệ trong Java
  • 3 Các kịch bản phổ biến nơi ngoại lệ có thể xảy ra
  • 4 Xử lý ngoại lệ (Exception Handling) trong java

Ngoại lệ (Exception) là gì?

Exception là một sự kiện xảy ra trong quá trình thực thi một chương trình Java, nó làm phá vỡ cái flow (luồng xử lý) bình thường của một chương trình, thậm chí chết chương trình.

Một ngoại lệ có thể xảy ra với nhiều lý do khác nhau, nó nằm ngoài dự tính của chương trình. Một vài ngoại lệ xảy ra bởi lỗi của người dùng, một số khác bởi lỗi của lập trình viên và số khác nữa đến từ lỗi của nguồn dữ liệu vật lý. Chẳng hạn như:

  • Người dùng nhập dữ liệu không hợp lệ.
  • Truy cập ngoài chỉ số mảng.
  • Một file cần được mở nhưng không thể tìm thấy.
  • Kết nối mạng bị ngắt trong quá trình thực hiện giao tiếp hoặc JVM hết bộ nhớ.
  • ….

Ví dụ chương trình chia 2 số. Nếu ta cho mẫu số = 0 thì phát sinh lỗi và đó được coi là 1 ngoại lệ.


public class ExceptionExample1 {

	public static void main(String[] args) {

		int zero = 0;

		int average = 10 / zero;

		System.out.println("Average = " + average);

	}

}

Khi thực thi chương trên, sẽ nhận được thông báo lỗi như sau:

Exception in thread "main" java.lang.ArithmeticException: / by zero

Hệ thống cấp bậc của các lớp ngoại lệ trong Java

Đây là mô hình sơ đồ phân cấp của Exception trong java.

  • Class ở mức cao nhất là Throwable
  • Hai class con trực tiếp là Error và Exception.

Trong nhánh Exception có một nhánh con RuntimeException là các ngoại lệ sẽ không được java kiểm tra trong thời điểm biên dịch.Ý nghĩa của được kiểm tra và không được kiểm tra tại thời điểm biên dịch sẽ được minh họa trong các ví dụ phần sau.

Exception

Trong Java có 2 loại exception: checked và unchecked. Tất cả các checked exception được kế thừa từ lớp Exception ngoại trừ lớp RuntimeException. RuntimeException là lớp cơ sở của tất cả các lớp unchecked exception. Đó cũng là dấu hiệu để nhận biết đâu là checked exception và đâu là unchecked exception.

Điểm khác biệt giữa các lớp checked và unchecked expcetion chính là thời điểm xác định được expcetion có thể xảy ra.

Checked exceptions

Là loại exception xảy ra trong lúc compile time, nó cũng có thể được gọi là compile time exceptions. Loại exception này không thể bỏ qua được trong quá trình compile, bắt buộc ta phải handle nó.

Các lớp extends từ lớp Throwable ngoại trừ RuntimeException và Error được gọi là checked exception.

Ví dụ: IOException, FileNotFoundException, NoSuchFieldException, ….

Ví dụ chương trình sau đọc file sử dụng java.io.FileReader lớp này ném ra ngoại lệ FileNotFoundException. Trình biên dịch thông báo lỗi như sau:

UnChecked exceptions

Là loại exception xảy ra tại thời điểm thực thi chương trình, nó cũng có thể gọi là runtime exceptions đó là programming bugs, lỗi logic của chương trình… Loại exception này được bỏ qua trong quá trình compile, không bắt buộc ta phải handle nó.

Các lớp extends từ RuntimeException được gọi là unchecked exception.

Ví dụ: NullPointerException, NumberFormatException, ArrayIndexOutOfBoundsException, DivideByZeroException, …

Ví dụ một biến có giá trị null, thực hiện bất kỳ hoạt động nào bởi biến đó sẽ xảy ra ngoại lệ NullPointerException.

Error

Error là những vấn đề nghiêm trọng liên quan đến môi trường thực thi của ứng dụng hoặc hệ thống mà lập trình viên không thể kiểm soát. Nó thường làm chết chương trình.

Lớp Error định nghĩa các ngoại lệ mà không thể bắt (catch) từ chương trình.

Ví dụ: OutOfMemoryError, VirtualMachineError, and StackOverflowError, …

Ví dụ chương trình đệ quy vô tận:

Các kịch bản phổ biến nơi ngoại lệ có thể xảy ra

ArithmeticException

Nếu chúng ta chia bất kỳ số nào cho số 0, xảy ra ngoại lệ ArithmeticException.

Ví dụ:


int a = 10 / 0; // ArithmeticException

NullPointerException

Nếu một bất kỳ biến nào có giá trị null, thực hiện bất kỳ hoạt động nào bởi biến đó sẽ xảy ra ngoại lệ NullPointerException.

Ví dụ:


String obj = null;
System.out.println(obj .length()); // NullPointerException

NumberFormatException

Một biến String có giá trị là các ký tự, chuyển đổi biến này thành số sẽ xảy ra NumberFormatException.


String str = "abc"; 
int num = Integer.parseInt(str); // NumberFormatException 

ArrayIndexOutOfBoundsException

Nếu bạn chèn bất kỳ giá trị nào vào index sai, sẽ xảy ra ngoại lệ ArrayIndexOutOfBoundsException.


int arr[] = new int[5];
arr[5] = 50; // ArrayIndexOutOfBoundsException

ClassCastException

Nếu không thể chuyển kiểu object này sang kiểu object khác, sẽ xảy ra ngoại lệ ClassCastException.


Object dog = new Dog();
Rectangle rect = (Rectangle) dog;

Xử lý ngoại lệ (Exception Handling) trong java

Xử lý ngoại lệ là gì?

Xử lý ngoại lệ (Exception Handling) trong java là một cơ chế xử lý các lỗi runtime để có thể duy trì luồng bình thường của ứng dụng.

Quá trình xử lý exception được gọi là catch exception, nếu Runtime System không xử lý được ngoại lệ thì chương trình sẽ kết thúc.

JVM xử lý Exceptions thế nào

Khi một lỗi xảy ra trên một method, method đó sẽ tạo ra một object và đưa nó vào Runtime System. Object đó được gọi là Exception Object, nó chứa tất cả các thông tin về lỗi và trạng thái của chương trình khi xảy ra lỗi.

Sau đó, Runtime System sẽ xử lý sẽ tìm cách xử lý ngoại lệ phù hợp được sử dụng tại method ấy. Nếu không có thì JVM tiếp tục tìm xử lý ngoại lệ phù hợp ở các method trên (là method gọi lớp hiện tại). Nếu không có method nào có xử lý ngoại lệ phù hợp thì Thread mà đang thực hiện chuỗi method xảy ra ngoại lệ bị ngắt. Nếu thread ấy là thread main thì chết chương trình.

Cú pháp xử lý ngoại lệ trong Java

Khối lệnh try trong java được sử dụng để chứa một đoạn code có thế xảy ra một ngoại lệ. Nó phải được khai báo trong phương thức.

Sau một khối lệnh try bạn phải khai báo khối lệnh catch hoặc finally hoặc cả hai.

Cú pháp của khối lệnh try-catch


try {
	// code có thể ném ra ngoại lệ
} catch(Exception_class_Name ex) {
	// code xử lý ngoại lệ
}

Cú pháp của khối lệnh try-finally

try {
// code có thể ném ra ngoại lệ
} finally {
// code trong khối này luôn được thực thi
}

Cú pháp của khối lệnh try-catch-finally


try {
	// code có thể ném ra ngoại lệ
} catch(Exception_class_Name_1 ex) {
	// code xử lý ngoại lệ 1
} catch(Exception_class_Name_2 ex) {
	// code xử lý ngoại lệ 2
} catch(Exception_class_Name_n ex) {
	// code xử lý ngoại lệ n
} finally {
	// code trong khối này luôn được thực thi
}

Các phương thức của lớp Exception

STTPhương thức và Miêu tả
1public String getMessage()
Trả về một message cụ thể về exception đã xảy ra. Message này được khởi tạo bởi phương thức contructor của Throwable
2public Throwable getCause()
Trả về nguyên nhân xảy ra exception biểu diễn bởi đối tượng Throwable
3public String toString()
Trả về tên của lớp và kết hợp với kết quả từ phương thức getMessage()
4public void printStackTrace()
In ra kết quả của phương thức toString cùng với stack trace đến System.err
5public StackTraceElement [] getStackTrace()
Trả về một mảng chứa mỗi phần tử trên stack trace. Phần tử tại chỉ mục 0 biểu diễn phần trên cùng của Call Stack, và phần tử cuối cùng trong mảng biểu diễn phương thức tại dưới cùng của Call Stack
6public Throwable fillInStackTrace()
Fills the stack trace of this Throwable object with the current stack trace, adding to any previous information in the stack trace.

Các ví dụ minh họa việc xử lý ngoại lệ

Ví dụ xử lý ngoại lệ thực hiện phép chia cho số 0

Khi chưa xử lý ngoại lệ


public class ExceptionExample1 {

	public static void main(String[] args) {
		int zero = 0;
		int average = 10 / zero;
		System.out.println("Average = " + average);
		System.out.println("Finished!");
	}

}

Thực thi chương trình trên:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.gpcoder.exception.ExceptionExample1.main(ExceptionExample1.java:7)

Xử lý ngoại lệ ArithmeticException cho chương trình trên

public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int zero = 0;
			int average = 10 / zero;
			System.out.println("Average = " + average);
		} catch (ArithmeticException ex) {
			System.out.println(ex);
		}
		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArithmeticException: / by zero
Finished!

Ví dụ về khối lệnh try lồng nhau


public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			try {
				int zero = 0;
				int average = 10 / zero;
				System.out.println("Average = " + average);
			} catch (ArithmeticException ex) {
				System.out.println(ex);
			}

			System.out.println("Continue...");
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);

		} catch (ArrayIndexOutOfBoundsException ex) {
			System.out.println(ex);
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArithmeticException: / by zero
Continue...
java.lang.ArrayIndexOutOfBoundsException: 5
Finished!

Ví dụ sau sử dụng nhiều khối lệnh catch

public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);
			
			int zero = 0;
			int average = 10 / zero;
			System.out.println("Average = " + average);
			
			String obj = null;
			System.out.println(obj.length());
		} catch (NullPointerException ex) {
			System.out.println(ex);
		} catch (ArithmeticException ex) {
			System.out.println(ex);
		} catch (ArrayIndexOutOfBoundsException ex) {
			System.out.println(ex);
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArrayIndexOutOfBoundsException: 5
Finished!

Ví dụ sử dụng khối lệnh finally nơi ngoại lệ không xảy ra

public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int res = 10/2;
			System.out.println("10/2 = " + res);
		} finally {
			System.out.println("Khối lệnh finally luôn được thực thi");
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

10/2 = 5
Khối lệnh finally luôn được thực thi
Finished!

Ví dụ sử dụng khối lệnh finally nơi ngoại lệ xảy ra nhưng không xử lý

public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);
		} catch (NullPointerException ex) {
			System.out.println(ex);
		} finally {
			System.out.println("Khối lệnh finally luôn được thực thi");
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

Khối lệnh finally luôn được thực thiException in thread "main" 
java.lang.ArrayIndexOutOfBoundsException: 5
	at com.gpcoder.exception.ExceptionExample1.main(ExceptionExample1.java:8)

Ví dụ sử dụng khối lệnh finally nơi ngoại lệ xảy ra và được xử lý

public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);
		} catch (NullPointerException ex) {
			System.out.println(ex);
		} catch (ArrayIndexOutOfBoundsException ex) {
			System.out.println(ex);
		} finally {
			System.out.println("Khối lệnh finally luôn được thực thi");
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArrayIndexOutOfBoundsException: 5
Khối lệnh finally luôn được thực thi
Finished!

Một số lưu ý

  • Tại một thời điểm chỉ xảy ra một ngoại lệ và tại một thời điểm chỉ có một khối catch được thực thi. Khi exception đã bị bắt ở một catch thì các catch tiếp theo sẽ không được bắt.
  • Tất cả các khối catch phải được sắp xếp từ cụ thể nhất đến chung nhất (từ exception con đến exception cha), tức là phải khai báo khối lệnh catch để xử lý lỗi NullPointerException, ArithmeticException, … trước khi khai báo catch để xử lý lỗi Exception.
  • Khối lệnh finally luôn được thực thi dù chương trình có xảy ra ngoại lệ hay không (ngay cả sử dụng lệnh return).
  • Đối với mỗi khối try, có thể không có hoặc nhiều khối catch, nhưng chỉ có một khối finally.
  • Khối finally sẽ không được thực thi nếu chương trình bị thoát bằng cách gọi System.exit() hoặc xảy ra một lỗi (Error) không thể tránh khiến chương trình bị chết.

Ví dụ sử dụng System.exit() để không thực thi khối lệnh finally


public class ExceptionExample1 {

	public static void main(String[] args) {
		try {
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);
		} catch (ArrayIndexOutOfBoundsException ex) {
			System.out.println(ex);
			System.exit(0); // Khối finally sẽ không được thực thi
		} finally {
			System.out.println("Khối lệnh finally luôn được thực thi");
		}

		System.out.println("Finished!");
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArrayIndexOutOfBoundsException: 5

Ví dụ khối finally vẫn được thực thi dù gọi lệnh return


public class ExceptionExample1 {
	
	public static int getValueAtIndex5() {
		try {
			int arr[] = new int[5];
			arr[5] = 4;
			System.out.println("arr[5] = " + arr[5]);
			return 1;
		} catch (ArrayIndexOutOfBoundsException ex) {
			System.out.println(ex);
			return 0; // Return kết quả nhưng vẫn thực thi khối finally
		} finally {
			System.out.println("Khối lệnh finally luôn được thực thi");
		}
	}

	public static void main(String[] args) {
		System.out.println("getValueAtIndex5() = " + getValueAtIndex5());
	}

}

Kết quả thực thi chương trình trên:

java.lang.ArrayIndexOutOfBoundsException: 5
Khối lệnh finally luôn được thực thi
getValueAtIndex5() = 0

Tài liệu tham khảo:

  • https://www.tutorialspoint.com/java/java_exceptions.htm
  • https://www.javatpoint.com/exception-handling-in-java
  • https://docs.oracle.com/javase/tutorial/essential/exceptions/

Trên đây là những hướng dẫn cơ bản về xử lý ngoại lệ (exception handling). Hy vọng giúp ích cho các bạn, hẹn gặp lại các bạn ở những bài viết tiếp theo.

4.6
21
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Exception Handling Được gắn thẻ: Basic Java, Exception

Abstract class và Interface trong Java
Từ khóa throw và throws trong Java

Có thể bạn muốn xem:

  • Một số tính năng mới về xử lý ngoại lệ trong Java 7 (09/12/2017)
  • Xử lý ngoại lệ đối với trường hợp ghi đè phương thức trong java (07/11/2017)
  • Từ khóa throw và throws trong Java (07/11/2017)
  • Custom Exception trong Java (07/11/2017)
  • Tránh lỗi NullPointerException trong Java như thế nào? (06/08/2018)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97436 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97121 lượt xem)
  • Giới thiệu Design Patterns (86805 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85607 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83150 lượt xem)

Nội dung bài viết

  • 1 Ngoại lệ (Exception) là gì?
  • 2 Hệ thống cấp bậc của các lớp ngoại lệ trong Java
  • 3 Các kịch bản phổ biến nơi ngoại lệ có thể xảy ra
  • 4 Xử lý ngoại lệ (Exception Handling) trong java

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link