Java 方法參數

方法參數是呼叫方法時傳入的值。

基本參數

public static void greet(String name, int age) {
    System.out.println("Hello " + name + ", age " + age);
}

// 呼叫
greet("Alice", 25);

Java 是傳值 (Pass by Value)

Java 永遠是傳值,不是傳參考。

基本型別

修改參數不會影響原始值:

public static void modify(int x) {
    x = 100;  // 修改的是副本
}

public static void main(String[] args) {
    int num = 10;
    modify(num);
    System.out.println(num);  // 10(沒有改變)
}

參考型別

傳遞的是參考的副本,可以修改物件內容,但不能修改參考本身:

public static void modifyArray(int[] arr) {
    arr[0] = 100;  // 可以修改內容
}

public static void reassignArray(int[] arr) {
    arr = new int[]{9, 9, 9};  // 這只是改變本地參考
}

public static void main(String[] args) {
    int[] numbers = {1, 2, 3};
    
    modifyArray(numbers);
    System.out.println(Arrays.toString(numbers));  // [100, 2, 3]
    
    reassignArray(numbers);
    System.out.println(Arrays.toString(numbers));  // [100, 2, 3](沒改變)
}

可變參數 (Varargs)

使用 ... 接受任意數量的參數:

public static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

// 呼叫
sum();              // 0
sum(1);             // 1
sum(1, 2);          // 3
sum(1, 2, 3, 4, 5); // 15

可變參數規則

  • 只能有一個可變參數
  • 必須是最後一個參數
// 正確
public static void method(String name, int... numbers) { }

// 錯誤
// public static void method(int... numbers, String name) { }
// public static void method(int... a, int... b) { }

參數預設值

Java 不支援參數預設值,但可以用方法多載模擬:

public static void greet(String name) {
    greet(name, "Hello");  // 呼叫另一個版本
}

public static void greet(String name, String greeting) {
    System.out.println(greeting + ", " + name + "!");
}

// 呼叫
greet("Alice");           // Hello, Alice!
greet("Bob", "Hi");       // Hi, Bob!

final 參數

final 參數不能在方法內重新賦值:

public static void process(final int value) {
    // value = 100;  // 編譯錯誤
    System.out.println(value);
}

物件參數

public static void printPerson(Person p) {
    System.out.println(p.getName() + ", " + p.getAge());
}

public static void updatePerson(Person p, String newName) {
    p.setName(newName);  // 會修改原物件
}

public static void main(String[] args) {
    Person person = new Person("Alice", 25);
    
    printPerson(person);  // Alice, 25
    updatePerson(person, "Bob");
    printPerson(person);  // Bob, 25
}

陣列參數

public static void printArray(int[] arr) {
    System.out.println(Arrays.toString(arr));
}

public static int[] doubleValues(int[] arr) {
    int[] result = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        result[i] = arr[i] * 2;
    }
    return result;
}

參數驗證

在方法開頭驗證參數:

public static double divide(double a, double b) {
    if (b == 0) {
        throw new IllegalArgumentException("除數不能為 0");
    }
    return a / b;
}

public static void setAge(int age) {
    if (age < 0 || age > 150) {
        throw new IllegalArgumentException("年齡必須在 0-150 之間");
    }
    // ...
}

public static void setName(String name) {
    if (name == null || name.isEmpty()) {
        throw new IllegalArgumentException("名稱不能為空");
    }
    // ...
}

回傳多個值

Java 方法只能回傳一個值,但可以用其他方式:

使用陣列

public static int[] minMax(int[] arr) {
    int min = arr[0], max = arr[0];
    for (int n : arr) {
        if (n < min) min = n;
        if (n > max) max = n;
    }
    return new int[]{min, max};
}

使用物件

public class Result {
    public int min;
    public int max;
    
    public Result(int min, int max) {
        this.min = min;
        this.max = max;
    }
}

public static Result findMinMax(int[] arr) {
    // ...
    return new Result(min, max);
}

使用 Map (Java 9+)

public static Map<String, Integer> getStats(int[] arr) {
    return Map.of(
        "min", Arrays.stream(arr).min().orElse(0),
        "max", Arrays.stream(arr).max().orElse(0),
        "sum", Arrays.stream(arr).sum()
    );
}