許多書籍對物件與引用關係語焉不詳甚至錯誤。必須清楚理解:
A a = new A();
產生一個 A 型別物件,a 是指向堆疊中真正物件的引用,a 本身與基本型別一樣存放在堆疊。底層來看,a 類似指標。
若認為 a 就是物件,初學階段似乎無礙(操作 a 即操作物件),但當引用指向改變時,此說法即失效。看範例:
class A { private int i=0; public void setI(int x){i=x;} public int getI(){return i;} }
public class MyRef1 {
public static void main(String[] args) {
A a=new A(); A b=new A();
a.setI(10); b.setI(15);
System.out.println("a的i=" + a.getI()); // 10
System.out.println("b的i=" + b.getI()); // 15
a = b; // a 指向 b 所指物件
a.setI(20);
System.out.println("a的i=" + a.getI()); // 20
System.out.println("b的i=" + b.getI()); // 20 而非 15!
}
}
第四行輸出 20 證明 a、b 指向同一物件。final A a = new A(); 僅防止 a 重新指向,不防止物件狀態改變:
final A a = new A(); System.out.println(a.getI()); // 0 a.setI(8); // 合法 System.out.println(a.getI()); // 8
結論:Java 透過 reference 操控 object,是深入學習基礎。
先看基本型別:
static int x=10, y=20;
public static void fangfa(int i) { i++; x=i; }
main: fangfa(y); // 輸出 x=21, y=20 → y 未改變,為值傳遞。
但物件引用傳遞時:
public static void setA1(A newA, int t) { newA.setI(t); }
main: A a=new A(); setA1(a, 30); // a.i 變為 30
似乎是引用傳遞?實則不然:a 是引用,傳遞的是引用的副本(值傳遞)。副本與原引用指向同一物件,操作副本即操作原物件。Java 只有值傳遞,無引用傳遞。