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

var và suy luận kiểu (Type Inference)

Từ Java 10, bạn có thể khai báo biến cục bộ bằng var thay vì ghi rõ kiểu dữ liệu - trình biên dịch sẽ tự suy luận kiểu dựa trên giá trị khởi tạo:

var age = 25; // suy luận là int
var name = "Bumbii"; // suy luận là String
var price = 19.99; // suy luận là double
var list = new ArrayList<String>(); // suy luận là ArrayList<String>

2. var vẫn là kiểu tĩnh - không phải kiểu động!

Phần tiêu đề “2. var vẫn là kiểu tĩnh - không phải kiểu động!”

⚠️ Đây là điểm dễ hiểu nhầm nhất: var không biến Java thành ngôn ngữ kiểu động (dynamically typed) như Python hay JavaScript. Kiểu dữ liệu được xác định tại thời điểm biên dịch dựa trên giá trị khởi tạo, và sau đó không thể thay đổi - giống hệt như khai báo kiểu tường minh:

var count = 10; // suy luận là int
count = 20; // OK, vẫn là int
// count = "abc"; // LỖI BIÊN DỊCH! count đã được suy luận là int, không thể gán String

var chỉ là cú pháp rút gọn giúp bạn không phải gõ lại kiểu dữ liệu - trình biên dịch vẫn kiểm tra kiểu chặt chẽ như bình thường.

var phải được khởi tạo ngay khi khai báo - trình biên dịch cần giá trị để suy luận kiểu:

// var x; // LỖI BIÊN DỊCH! Không có giá trị khởi tạo để suy luận kiểu
var x = 0; // OK

var chỉ dùng được cho biến cục bộ (local variable trong thân phương thức) - không dùng được cho:

  • Thuộc tính của lớp (field)
  • Tham số phương thức
  • Kiểu trả về của phương thức
public class Demo {
// var count = 0; // LỖI! Không dùng var cho field của lớp
// void greet(var name) {} // LỖI! Không dùng var cho tham số
void run() {
var total = 0; // OK - chỉ hợp lệ trong thân phương thức
}
}

var giúp code gọn hơn khi kiểu dữ liệu đã rõ ràng từ vế phải:

// Kiểu dài dòng, lặp lại - var giúp gọn hơn mà không mất thông tin
var students = new ArrayList<Map<String, Integer>>();
// Thay vì:
ArrayList<Map<String, Integer>> students2 = new ArrayList<Map<String, Integer>>();

Nên tránh dùng var khi nó làm giảm khả năng đọc code - ví dụ khi kiểu không rõ ràng từ tên biến hoặc giá trị khởi tạo:

var result = compute(); // Không rõ compute() trả về kiểu gì nếu chỉ đọc dòng này - nên ghi rõ kiểu ở đây
  • var (Java 10+) để trình biên dịch tự suy luận kiểu biến cục bộ từ giá trị khởi tạo
  • Vẫn là kiểu tĩnh - kiểu được cố định tại thời điểm biên dịch, không đổi được sau đó
  • Chỉ dùng cho biến cục bộ, phải khởi tạo ngay khi khai báo
  • Dùng khi kiểu đã rõ ràng để code gọn hơn; tránh dùng khi làm giảm khả năng đọc