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