Java var 關鍵字
Java 10 引入了 var 關鍵字,讓編譯器自動推斷區域變數的型別。
基本用法
// 傳統寫法
String name = "Alice";
int age = 25;
List<String> list = new ArrayList<>();
// 使用 var
var name = "Alice"; // 推斷為 String
var age = 25; // 推斷為 int
var list = new ArrayList<String>(); // 推斷為 ArrayList<String>
適用場合
宣告區域變數
var message = "Hello World";
var count = 100;
var price = 99.99;
var flag = true;
for 迴圈
var numbers = List.of(1, 2, 3, 4, 5);
for (var num : numbers) {
System.out.println(num);
}
for (var i = 0; i < 10; i++) {
System.out.println(i);
}
try-with-resources
try (var reader = new BufferedReader(new FileReader("file.txt"))) {
var line = reader.readLine();
System.out.println(line);
}
不適用場合
沒有初始值
// 錯誤:var 必須有初始值
// var name;
// name = "Alice";
// 正確
var name = "Alice";
null 初始值
// 錯誤:無法推斷型別
// var something = null;
// 正確
String something = null;
類別欄位
public class Person {
// 錯誤:var 不能用於欄位
// var name = "Alice";
// 正確
private String name = "Alice";
}
方法參數
// 錯誤:var 不能用於參數
// public void greet(var name) { }
// 正確
public void greet(String name) { }
Lambda 表達式
// 錯誤(Java 10)
// var greeting = (String name) -> "Hello, " + name;
// 正確:明確指定型別
Function<String, String> greeting = name -> "Hello, " + name;
// Java 11+ 可以在 Lambda 參數使用 var
Function<String, String> greeting2 = (var name) -> "Hello, " + name;
實際範例
簡化長型別名稱
// 傳統
Map<String, List<Employee>> departmentEmployees = new HashMap<>();
// 使用 var
var departmentEmployees = new HashMap<String, List<Employee>>();
Stream 操作
var names = List.of("Alice", "Bob", "Charlie");
var filtered = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
讀取檔案
try (var lines = Files.lines(Path.of("file.txt"))) {
lines.forEach(System.out::println);
}
最佳實踐
可讀性優先
// 好:型別明顯
var name = "Alice";
var numbers = new ArrayList<Integer>();
// 不好:型別不明顯
var result = process(); // result 是什麼型別?
var data = getData(); // data 是什麼?
避免過度使用
// 型別重要時明確寫出
List<String> names = getNames(); // 清楚表達意圖
// 型別明顯時可以用 var
var sb = new StringBuilder();
var map = new HashMap<String, Integer>();
保持一致性
在同一專案或團隊中,統一使用 var 的風格。
var vs 明確型別
| 情況 | 建議 |
|---|---|
| 右邊有 new | 可用 var |
| 方法回傳值型別不明顯 | 明確寫出型別 |
| 基本型別字面值 | 可用 var |
| 複雜的泛型 | 可用 var |
| API 設計考量 | 明確寫出型別 |
型別推斷範例
var str = "Hello"; // String
var num = 123; // int(不是 Integer)
var decimal = 3.14; // double(不是 float)
var list = List.of(1, 2, 3); // List<Integer>
var array = new int[10]; // int[]
var map = Map.of("a", 1); // Map<String, Integer>
var 推斷的是具體型別,不是介面。例如
var list = new ArrayList<>() 會推斷為 ArrayList,不是 List。