Trong hướng dẫn này, chúng ta sẽ tìm hiểu về câu lệnh khẳng định Java (assertions Java ) với sự trợ giúp của các ví dụ.

xác nhận(assertions) trong Java giúp phát hiện lỗi bằng cách kiểm tra mã mà chúng ta cho là đúng.

Một xác nhận(khẳng định) được thực hiện bằng cách sử dụng từ khóa assert.

Cú pháp của nó là:

assert condition;

Đây condition là một biểu thức boolean mà chúng ta giả sử là đúng khi chương trình thực thi.

1. Kích hoạt khẳng định

Theo mặc định, các xác nhận(assertions) bị tắt và bị bỏ qua trong thời gian chạy.

Để bật assert , chúng ta sử dụng:

java -ea:arguments

HOẶC LÀ

java -enableassertions:arguments

Khi các xác nhận(assert) được kích hoạt và điều kiện là true, chương trình sẽ thực thi bình thường.

Nhưng nếu điều kiện được đánh giá là false trong khi các xác nhận(assert) được bật, JVM sẽ ném một dấu AssertionError và chương trình dừng ngay lập tức.

Ví dụ 1: Xác nhận trong Java

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length == 2;
    System.out.println("There are " + weekends.length + "  weekends in a week");
  }
}

Đầu ra

There are 3 weekends in a week

Chúng ta nhận được kết quả ở trên vì chương trình này không có lỗi biên dịch và theo mặc định, các xác nhận(assert) bị vô hiệu hóa.

Sau khi bật xác nhận(assert), chúng ta nhận được kết quả sau:

Exception in thread "main" java.lang.AssertionError

2. Một dạng câu lệnh khẳng định khác

assert condition : expression;

Trong dạng câu lệnh khẳng định này, một biểu thức được chuyển tới hàm tạo của đối tượng AssertionError. Biểu thức này có một giá trị được hiển thị dưới dạng thông báo chi tiết của lỗi nếu điều kiện là false.

Thông báo chi tiết được sử dụng để nắm bắt và truyền thông tin về lỗi xác nhận để giúp gỡ lỗi vấn đề.

Ví dụ 2: Khẳng định Java với ví dụ về biểu thức

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length==2 : "There are only 2 weekends in a week";
    System.out.println("There are " + weekends.length + "  weekends in a week");
  }
}

Đầu ra

Exception in thread "main" java.lang.AssertionError: There are only 2 weekends in a week

Như chúng ta thấy từ ví dụ trên, biểu thức được chuyển cho hàm tạo của đối tượng AssertionError. Nếu giả định của chúng ta là false và xác nhận(Assertion) được kích hoạt, một ngoại lệ sẽ được đưa ra với một thông báo thích hợp.

Thông báo này giúp chẩn đoán và sửa lỗi khiến xác nhận(Assertion) không thành công.

3. Bật xác nhận(Assertion) cho các lớp và gói cụ thể

Nếu chúng ta không cung cấp bất kỳ đối số nào cho các công tắc dòng lệnh khẳng định,

java -ea

Điều này cho phép xác nhận(Assertion) trong tất cả các lớp ngoại trừ các lớp hệ thống.

Chúng ta cũng có thể kích hoạt xác nhận(Assertion) cho các lớp và gói cụ thể bằng cách sử dụng các đối số. Các đối số có thể được cung cấp cho các công tắc dòng lệnh này là:

Bật xác nhận(Assertion) trong tên lớp

Để kích hoạt xác nhận(Assertion) cho tất cả các lớp của chương trình Chính của chúng ta,

java -ea Main

Để bật một lớp,

java -ea:AnimalClass Main

Điều này cho phép xác nhận(Assertion) chỉ AnimalClass trong Main của chương trình.

Bật xác nhận(Assertion) trong tên gói

Để chỉ bật xác nhận(Assertion) cho gói com.animal và các gói con của nó,

java -ea:com.animal... Main

Bật xác nhận(Assertion) trong các gói không có tên

Để kích hoạt xác nhận(Assertion) trong các gói không có tên (khi chúng ta không sử dụng câu lệnh gói) trong thư mục làm việc hiện tại.

java -ea:... Main

Bật xác nhận(Assertion) trong các lớp hệ thống

Để kích hoạt xác nhận(Assertion) trong các lớp hệ thống, chúng ta sử dụng một công tắc dòng lệnh khác:

java -esa:arguments 

HOẶC LÀ

java -enablesystemassertions:arguments

Các đối số có thể được cung cấp cho các công tắc này là giống nhau.

4. Tắt xác nhận(Assertion)

Để tắt xác nhận(Assertion), chúng ta sử dụng:

java -da arguments 

HOẶC LÀ

java -disableassertions arguments

Để tắt xác nhận(Assertion) trong các lớp hệ thống, chúng ta sử dụng:

java -dsa:arguments

HOẶC LÀ

java -disablesystemassertions:arguments

Các đối số có thể được truyền trong khi tắt xác nhận(Assertion) cũng giống như khi bật chúng.

5. Ưu điểm của Assertion

  1. Nhanh chóng và hiệu quả để phát hiện và sửa lỗi.
  2. Kiểm tra xác nhận chỉ được thực hiện trong quá trình phát triển và thử nghiệm. Chúng tự động bị xóa trong code release trong thời gian chạy để không làm chậm quá trình thực thi chương trình.
  3. Nó giúp loại bỏ code viết sẵn và làm cho code dễ đọc hơn.
  4. Cơ cấu lại và tối ưu hóa mã với độ tin cậy cao hơn rằng nó hoạt động chính xác.

6. Khi nào sử dụng Assertions

6.1. Code không thể truy cập

Mã không thể truy cập là code không thực thi khi chúng ta cố gắng chạy chương trình. Sử dụng xác nhận(Assertion) để đảm bảo rằng các code không thể truy cập chắc chắn sẽ không thể truy cập được.

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

void unreachableCodeMethod() {
  System.out.println("Reachable code");
  return;
  // Unreachable code
  System.out.println("Unreachable code");
  assert false;
}

Hãy lấy một ví dụ khác về câu lệnh switch không có trường hợp mặc định.

switch (dayOfWeek) {
  case "Sunday":
    System.out.println("It’s Sunday!");
    break;
  case "Monday":
    System.out.println("It’s Monday!");
    break;
  case "Tuesday":
    System.out.println("It’s Tuesday!");
    break;
  case "Wednesday":
    System.out.println("It’s Wednesday!");
    break;
  case "Thursday":
    System.out.println("It’s Thursday!");
    break;
  case "Friday":
    System.out.println("It’s Friday!");
    break;
  case "Saturday":
    System.out.println("It’s Saturday!");
    break;
}

Câu lệnh switch trên chỉ ra rằng các ngày trong tuần chỉ có thể là một trong 7 giá trị trên. Không có trường hợp mặc định có nghĩa là lập trình viên tin rằng một trong những trường hợp này sẽ luôn được thực thi.

Tuy nhiên, có thể có một số trường hợp vẫn chưa được xem xét trong đó giả định thực sự là sai.

Giả định này nên được kiểm tra bằng cách sử dụng một xác nhận(Assertion) để đảm bảo rằng không đạt được trường hợp chuyển mạch mặc định.

default:
    assert false: dayofWeek + " is invalid day";

Nếu ngày trong tuần có giá trị khác với những ngày hợp lệ, một AssertionError được ném.

6.2. Lập hồ sơ các giả định

Để ghi lại các giả định cơ bản của họ, nhiều lập trình viên sử dụng các comment. Hãy lấy một ví dụ.

if (i % 2 == 0) {
    ...
} else { // We know (i % 2 == 1)
    ...
}

Sử dụng xác nhận(Assertion) để thay thế.

Các comment có thể lỗi thời và không đồng bộ khi chương trình phát triển. Tuy nhiên, chúng ta sẽ buộc phải cập nhật các câu lệnh assert; nếu không, chúng cũng có thể không đạt được các điều kiện hợp lệ.

if (i % 2 == 0) {
   ...
} else {
    assert i % 2 == 1 : i;
    ...
}

7. Khi nào không sử dụng Assertions

7.1. Kiểm tra đối số trong các phương thức công khai

Người dùng có thể cung cấp các đối số trong các phương thức công khai.

Vì vậy, nếu một khẳng định được sử dụng để kiểm tra các đối số này, các điều kiện có thể không thành công và dẫn đến kết quả là AssertionError.

Thay vì sử dụng các xác nhận(Assertion), hãy để nó dẫn đến các ngoại lệ thời gian chạy thích hợp và xử lý các ngoại lệ này.

7.2. Để đánh giá các biểu thức ảnh hưởng đến hoạt động của chương trình

Không gọi các phương thức hoặc đánh giá các ngoại lệ mà sau này có thể ảnh hưởng đến hoạt động của chương trình trong các điều kiện khẳng định.

Hãy để chúng tôi lấy một ví dụ về một danh sách các ngày trong tuần trong đó chứa tên của tất cả các ngày trong tuần.


ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

assert weekdays.removeAll(weekends);

Ở đây, chúng ta đang cố gắng xóa các phần tử Saturdayvà Sundaykhỏi ArrayList các ngày trong tuần.

Nếu xác nhận(Assertion) được bật, chương trình hoạt động tốt. Tuy nhiên, nếu xác nhận(Assertion) bị vô hiệu hóa, các phần tử từ danh sách sẽ không bị xóa. Điều này có thể dẫn đến lỗi chương trình.

Thay vào đó, hãy gán kết quả cho một biến và sau đó sử dụng biến đó để khẳng định.

ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

boolean weekendsRemoved = weekdays.removeAll(weekends);
assert weekendsRemoved;

Bằng cách này, chúng ta có thể đảm bảo rằng tất cả nhưng ngay cả cuối tuần bị loại bỏ khỏi các ngày trong tuần bất kể xác nhận(Assertion) được bật hay tắt. Nhờ vậy, nó không ảnh hưởng đến hoạt động của chương trình sau này.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Nguồn và Tài liệu tiếng anh tham khảo:

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!