Chương 9: Ngoại lệ Mục tiêu bài học
9.4.2 Cho và không cho phép assertion
Các tùy chọn dòng lệnh của lệnh Java cho phép hoặc không cho phép assertion ở mức lớp. Dòng lệnh chuyển đổi –enableassertion hay viết tắt là –ea, cho
phép assertion. Ngầm định, assertion bị vô hiệu lúc thực thi. Hai tùy chọn dòng lệnh cho phép nhà phát triển lựa chọn cho phép hoặc không cho phép assertion. Để cho phép assertion sử dụng –enableassertion hay –ea. Để không cho phép assertion sử dụng –disableassertion hay –da. Chi tiết về các tùy chọn như sau:
-ea
Cho phép hoặc không cho phép assertion trong tất cả các lớp ngoại trừ các lớp hệ thống.
-ea:<tên_package >
Cho phép hoặc không cho phép assertion trong package có tên và các package con.
-ea:…
Cho phép hoặc không cho phép assertion trong package không chỉ tên trong thư mục làm việc hiện tại.
-ea:<tên_lớp>
Cho phép hoặc không cho phép assertion trong lớp có tên.
Kết quả sau khi thực thi lớp Excep bằng lệnh Java Excep, với môi trường thực thi ngầm định không cho phép assertion:
Excep.m1 ( 1 ) : OK Excep.m1 ( -1) : OK
Với các assertion bị vô hiệu, không lời gọi phương thức m1(int) nào gây ra kiểm tra assertion. Như mô tả ở trước, để cho phép assertion cần sử dụng các tùy chọn dòng lệnh. Bất cứ lệnh nào sau đây, thể hiện trong đoạn mã 9, cho phép kiểm tra assertion trong lớp Excep
Java –ea Excep
Java –ea:Excep Excep Java –ea:... Excep
Kết quả sau khi thực hiện các lệnh:
Excep.m1( 1 ) : OK
Excep.m1( -1 ) : Exception in thread “main”
Java.lang.AssertionError
at Excep.m1(Excep.Java:6) at Excep.main(Excep.Java:17)
Gọi phương thức m1(int) với tham số 1 không gây ra assertion. Tuy nhiên, -1 vi phạm giả định rằng tham số phải làm một số nguyên dương. Hệ thống thực thi Java thông báo giả định thất bại thông qua thể hiện của lớp,
Chương 9 Ngoại lệ
111/114 Để nắm rõ hàm dựng AssertionError nào được dùng, xem xét cách thức các assertion được xử lý khi cho phép
Ước lượng expression1
Nếu true
o Không có hành động nào
Nếu false
o Và nếu expression2 tồn tại
Ước lượng expression2 và sử dụng kết quả dưới dạng tham số đơn của hàm dựng AssertionError.
o Ngược lại
Sử dụng hàm dựng ngầm định AssertionError.
Vì lệnh assert trong lớp Excep sử dụng dạng biểu thức đơn, sự vi phạm đã xảy ra khi truyền -1 vào phương thức m1(int) thúc đẩy hàm dựng AssertionError
được sử dụng. Hàm dựng ngầm định thực tế sử dụng hàm dựng ngầm định của
java.lang.Throwable để in thông điệp ngoại lệ bao gồm mô tả lần vết dạng văn
bản.
Kết quả lỗi assertion khi thực hiện lớp Excep thiếu. Như đã thấy AssertionError xảy ra trong phương thức m1 tại dòng 6, nhưng kết quả không mô tả sai điều gì. May mắn là dạng lệnh assert có hai biểu thức cung cấp khả năng này. Như giải thích ở trên, trong dạng hai biểu thức, khi biểu thức expression1 được ước lượng là false, assertion sẽ truyền kết quả của biểu thức expression2 vào cho tham số của hàm dựng AssertionError. Biểu thức expression2 thực tế mang thông điệp dạng chuỗi. Nghĩa là các hàm dựng một tham số của lớp AssertionError phải chuyển kết quả của biểu thức expression2 sang chuỗi (String).
Lớp Bar, được mô tả trong đoạn mã 10, sử dụng dạng hai biểu thức cho một assertion đơn trong phương thức m1(int).
Đoạn mã 10:
public class Bar {
public void m1(int value){
assert 0 <= value: "Value must be non-negative : value= " + value;
System.out.println("OK"); }
Bar bar = new Bar(); System.out.println("bar.m1( 1 ): "); bar.m1(1); System.out.println("bar.m1( -1 ): "); bar.m1(-1); } }
Kết quả thực hiện Bar có cho phép assertion như sau: bar.m1( 1 ): OK
bar.m1( -1 ): Exception in thread “main” Java.lang.AssertionError: Value must be non-negative: value= -1
at Bar.m1(Bar.Java:6) at Bar.main(Bar.Java:17)
Kết quả cho thấy sự chuyển đổi kết quả của biểu thức expression thành chuỗi (String) và nối vào cuối thông điệp ngoại lệ, trước thông tin theo vết. Thông điệp chi tiết tất nhiên là cải thiện công dụng của thông điệp ngoại lệ. Vì tạo các thông điệp lỗi hợp lý không khó, các nhà phát triển ủng hộ dạng hai biểu thức của lệnh assert.
Lớp Java.lang.Throwable cho phép định dạng rõ ràng thông tin lần vết. Lớp FooBar, liệt kê trong đoạn mã 11, sử dụng các khả năng mới này để định dạng thông điệp ngoại lệ được tạo ra bởi lỗi assertion.
Đoạn mã 11:
public class Bar {
public void m1(int value){
assert 0 <= value: "Value must be non-negative : value= " + value;
System.out.println("OK"); }
public static void printAssertionError(AssertionError ae){ StackTraceElement[] stackTraceElements=ae.getStackTrace(); StackTraceElement stackTraceElement=stackTraceElements[0]; System.err.println("AssertionError"); System.err.println("Class="+stackTraceElement.getClassName()); System.err.println("method="+stackTraceElement.getMethodName()); System.err.println("message="+stackTraceElement.getMessage()); }
Chương 9 Ngoại lệ
113/114 try{
Bar bar = new Bar();
System.out.println("bar.m1( 1 ): "); bar.m1(1); System.out.println("bar.m1( -1 ): "); bar.m1(-1); }catch(AssertionError ae){ printAssertionError(ae); } } }
Kết quả thực thi FooBar có cho phép assertion hiển thị thông báo
AssertionError rõ ràng:
fooBar.m1( 1 ): OK
fooBar.m1( 1 ): AssertionError class = FooBar
method= m1
message= Value must be non-negative: value= -1