天天看點

Java參數傳遞的問題

有一道題

下列java程式的輸出結果為__。

public class Example{
    String str=new String("hello");
    char[]ch={'a','b'};
    public static void main(String args[]){
        Example ex=new Example();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str+" and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[]){
        str="test ok";
        ch[]='c';
    }
}
           

A.hello and ab

B.hello and cb

C.hello and a

D.test ok and ab

E.test ok and cb

F.test ok and c

正确答案是B。

JAVA兩種資料類型:基本類型和引用類型。 基本類型作為參數傳遞時是按值傳遞,方法中使用的是參數的值拷貝,原參數不會得到改變。傳遞引用類型時的情況頗有争議,目前主要有兩種說法:1.Java中隻有一種傳遞的方式即按值傳遞,引用類型作為參數傳遞時傳遞的實際是該對象引用的值。2.Java中原始類型按值傳遞,對象按引用傳遞。在我看來,這兩種說法意思是一樣的,隻是不同的人表述習慣不同。事情其實很簡單,“Java manipulates objects ‘by reference,’ but it passes object references to methods ‘by value.”

Java按引用傳遞時,方法會得到原始對象的引用複制即記憶體位址,通過這個複制得到的引用是可以改變原對象的狀态的。如題中的char ch[]就是引用傳遞,在change方法中對ch[0]指派,就改變了原ch數組的内容。而String str也是引用傳遞,原字元串str卻沒有改變的原因是String類型的特殊性,String類型是不可更改的,任何試圖改變String的行為其實都是建立了一個新的String對象,讓原來的引用指向這個新的String對象。是以change方法中 str=”test ok”;其實是生成了一個新的String對象”test ok”,并讓str指向了它,而str隻是一個局部變量,change方法結束後就被自動回收了,與Example類中的全局變量str完全沒産生關系,自然也不會将其改變。如果想改變全局變量str,隻需要在change方法中指定this.str就可以了。

Java參數傳遞的問題

另外還需要注意,如果隻是在方法中更改引用指向的對象,而不通過引用對原對象作實質性改變的話,是不會對原對象産生影響的。因為方法傳遞進來的引用隻是原引用的一個拷貝,是局部變量,随着方法結束也就失去作用了,是不會對原對象産生影響的。比如下面:

Java參數傳遞的問題

很多認為Java隻存在值傳遞的人都會舉類似的例子,但其實我覺得這個隻是展現 了局部變量的特點而已。