Bỏ qua để đến nội dung

Hằng số (final)

Từ khóa final đứng trước khai báo biến khiến biến đó chỉ được gán giá trị một lần - sau đó không thể gán lại:

final double PI = 3.14159;
System.out.println(PI);
// PI = 3.14; // LỖI BIÊN DỊCH! Không thể gán lại biến final

Hằng số thường được đặt tên theo kiểu UPPER_SNAKE_CASE (chữ hoa, cách nhau bằng dấu gạch dưới) để dễ phân biệt với biến thông thường:

final int MAX_USERS = 100;
final String APP_NAME = "Bumbii Academy";
final double TAX_RATE = 0.1;

Khi hằng số thuộc về cả lớp (dùng chung cho mọi đối tượng, không phụ thuộc từng instance), kết hợp với static:

public class Config {
public static final int MAX_USERS = 100;
public static final String APP_NAME = "Bumbii Academy";
}
// Dùng ở nơi khác, không cần tạo đối tượng Config
System.out.println(Config.MAX_USERS);

Đây là cách phổ biến nhất để định nghĩa các hằng số dùng chung trong một chương trình Java.

4. final không đồng nghĩa với “bất biến sâu”

Phần tiêu đề “4. final không đồng nghĩa với “bất biến sâu””

final chỉ ngăn gán lại tham chiếu/giá trị của biến - nếu biến là một đối tượng (như List), nội dung bên trong đối tượng đó vẫn có thể thay đổi được:

import java.util.ArrayList;
import java.util.List;
final List<String> names = new ArrayList<>();
names.add("An"); // OK! Vẫn thêm được phần tử - nội dung list thay đổi
names.add("Binh"); // OK!
// names = new ArrayList<>(); // LỖI BIÊN DỊCH! Không thể gán lại biến final

⚠️ Đây là điểm khác với khái niệm “hằng số bất biến hoàn toàn”: final bảo vệ tham chiếu, không bảo vệ trạng thái bên trong đối tượng. Muốn một List thực sự không thể sửa, cần bọc bằng Collections.unmodifiableList(...) hoặc List.of(...).

final cũng dùng được cho tham số hàm (không được gán lại giá trị bên trong hàm) và cho phương thức/lớp (ngăn override/kế thừa - sẽ học ở phần Hướng đối tượng):

void printMessage(final String message) {
// message = "khác"; // LỖI BIÊN DỊCH! Không thể gán lại tham số final
System.out.println(message);
}
  • final khiến một biến chỉ được gán giá trị một lần - hằng số
  • Quy ước đặt tên: UPPER_SNAKE_CASE
  • Kết hợp static final để tạo hằng số dùng chung ở cấp lớp
  • final chỉ khóa tham chiếu, không khóa nội dung bên trong đối tượng mà tham chiếu đó trỏ tới