Giới thiệu ngắn
Từ khóa var được đưa vào Java bắt đầu từ Java 10 như một phần của tính năng suy diễn kiểu cho biến cục bộ (Local-Variable Type Inference).
Thay vì khai báo kiểu tường minh bên trái, trình biên dịch sẽ suy ra kiểu dựa trên biểu thức khởi tạo ở bên phải.
Cú pháp cơ bản — ví dụ
Các ví dụ sau minh hoạ cách var hoạt động (kiểu được suy ra tại thời điểm biên dịch):
// Kiểu sẽ được suy ra tương đương:
String name = "Uma";
int age = 30;
ArrayList<String> list = new ArrayList<>();
// Với var (trình biên dịch suy ra kiểu)
var name = "Uma";
var age = 30;
var list = new ArrayList<String>();
Những điểm chính cần nhớ
- Suy diễn kiểu: Trình biên dịch suy ra kiểu từ biểu thức khởi tạo.
- Vẫn là ngôn ngữ tĩnh: Kiểu được xác định ở thời điểm biên dịch, không phải runtime.
- Chỉ dùng cho biến cục bộ: Không dùng cho trường lớp (fields), tham số phương thức hay kiểu trả về (tính đến Java 11).
- Phải có khởi tạo: Khi khai báo bằng
varcần gán ngay giá trị để suy kiểu. - Không được gán
null1 mình:var x = null;không hợp lệ vì trình biên dịch không biết suy kiểu gì.
Nơi được phép dùng
- Bên trong phương thức (local variables).
- Trong vòng lặp
fornâng cao (enhanced for). - Trong biểu thức try-with-resources.
Ví dụ vòng lặp:
var list = List.of("A","B","C");
for (var item : list) {
System.out.println(item);
}
Nơi không nên / không thể dùng
- Trường (class fields).
- Tham số phương thức (method parameters) — (trừ một số mở rộng sau Java 11 cho lambda).
- Kiểu trả về của phương thức.
Ví dụ đầy đủ
public class VarExample {
public static void main(String[] args) {
var message = "Hello, World!"; // suy ra là String
var number = 100; // suy ra là int
var list = List.of("One","Two");
for (var item : list) {
System.out.println(item.toUpperCase());
}
}
}
Lợi ích khi dùng var
- Giảm gõ tắt (boilerplate): không cần lặp lại các khai báo kiểu dài, đặc biệt với generic lồng nhau.
- Tăng đọc được ở một số ngữ cảnh: khi kiểu rõ ràng từ biểu thức khởi tạo, mã ngắn gọn hơn.
- Khuyến khích đặt tên biến có ý nghĩa: khi không viết kiểu tường minh, tên biến cần mô tả rõ vai trò.
- Hữu ích với kiểu generic phức tạp: giảm lặp lại thông tin kiểu ở hai phía.
- Vẫn giữ kiểu tĩnh: Java kiểm tra kiểu ở thời điểm biên dịch như bình thường.
- Dễ refactor: khi thay đổi kiểu trả về hoặc constructor, tên biến không cần sửa kiểu tường minh.
- Hỗ trợ trong for-each và lambda (từ Java 11): có thể dùng
vartrong tham số lambda để thêm chú thích kiểu (annotations) khi cần.
Cẩn trọng khi dùng
Mặc dù var tiện lợi, nhưng lạm dụng ở nơi không rõ ràng có thể làm giảm tính dễ hiểu:
- Nên tránh dùng khi kiểu không rõ ràng từ ngữ cảnh.
- Không dùng để che giấu kiểu phương thức trả về — điều này khiến code khó đọc.
- Trong giai đoạn debug hoặc khi onboarding, người mới có thể mất thời gian xác định kiểu biến.
Ví dụ so sánh:
// Kém rõ ràng
var a = someMethod(); // không biết trả về gì
// Rõ ràng hơn (tên biến có nghĩa)
var connection = getConnection(); // tên biến gợi ý về kiểu
Câu hỏi thường gặp: var có giúp tiết kiệm bộ nhớ hay tăng tốc không?
Không. var chỉ là tính năng ở thời điểm biên dịch để suy ra kiểu; nó không thay đổi hành vi khi chạy chương trình.
Sau khi biên dịch, mọi khai báo var được thay bằng kiểu cụ thể trong bytecode (ví dụ ArrayList<String> list), vì vậy hiệu năng, cách bố trí bộ nhớ, và hành vi JVM không thay đổi.
Tóm tắt ngắn gọn về quy trình:
- Trình biên dịch xác định kiểu dựa trên biểu thức khởi tạo.
- Sau khi biên dịch, bytecode chứa kiểu cụ thể — không tồn tại
vartrong .class.