首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 參數傳遞機制深度解析:為何只有陣列被修改?

     編輯:程式設計綜合問答

現象重現

public class Aed {
    String str = "good";
    char[] ch = {'a','b','c'};
    int num = 10;

    public void change(String str, char[] ch, int num) {
        str = "test ok";    // 1. 重新指向新字串物件
        ch[0] = 'g';        // 2. 修改陣列內容
        num = 20;           // 3. 修改區域變數
    }

    public static void main(String[] args) {
        Aed a = new Aed();
        a.change(a.str, a.ch, a.num);
        System.out.print(a.str); // good
        System.out.print(a.ch);  // gbc
        System.out.print(a.num); // 10
    }
}

輸出:good gbc 10 —— 僅陣列 `ch` 的第一個元素變為 `'g'`。

核心真相:Java 唯一支援「傳值呼叫」

參數類型傳遞內容方法內操作對外部影響
基本型別 (int, char...)數值副本修改區域變數無影響
參考型別 (String, 陣列, 物件)引用副本 (記憶體位址)重新指向新物件 (`=`)無影響
參考型別引用副本透過引用修改物件內部狀態 (如 `ch[0]=...`)有影響

逐行解析

  1. str = "test ok":`str` 參數原本指向 `"good"`,賦值後指向新字串 `"test ok"`,外部 `a.str` 仍指向 `"good"`。
  2. ch[0] = 'g':`ch` 參數與外部 `a.ch` 指向同一個陣列物件,透過索引修改內容,外部可見。
  3. num = 20:基本型別傳值,修改區域副本,外部 `a.num` 不變。

常見誤區澄清

「Java 物件是傳址呼叫」—— 錯誤。Java 傳遞的是引用的副本(值),無法在方法內讓外部引用指向新物件。C++ 的引用參數 (`Type&`) 才是真正的傳址。

最佳實踐建議

  • 若需修改呼叫端的引用指向,請回傳新物件並重新賦值:`a.str = a.change(...)`。
  • 若需修改物件內部狀態,直接呼叫方法操作即可(如 `list.add()`、`arr[0]=...`)。
  • 不可變物件 (`String`, `Integer`, `BigDecimal` 等) 無法被修改內部狀態,任何「修改」實為產生新物件。

延伸:如何在方法中修改基本型別?

包裝在可變容器中:

// 方案 1: 陣列包裝
void modify(int[] wrapper) { wrapper[0] = 20; }
int[] num = {10}; modify(num); // num[0] 變 20

// 方案 2: 自訂可變持有類
class MutableInt { int value; }
void modify(MutableInt mi) { mi.value = 20; }
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved