2011-04-13 64 views
0


在下面的代碼爲什麼引用字符串的行爲不像其他對象引用?

public class Test { 

    public static void main(String[] args){ 
     int [] arr = new int[]{1,2}; 
     String b=new String("abc"); 
     f(b,arr); 
     System.out.println(b); 
     System.out.println(arr[0]); 

    } 

    public static void f(String b, int[] arr){ 

     b+="de"; 
     b=null; 
     arr[0] = 5; 
    } 
} 

爲什麼字符串的參考變量不表現得像陣列的參考變量?
我知道字符串是不可變的,因此對它們的操作會創建新的字符串,但是如何引用字符串以及引用b如何引用舊值,儘管它已更改爲引用f()方法中的其他內容。

+1

引用字符串就表現得像其他引用。嘗試將'f'的參數重命名爲'x'和'y'並在'f'內部執行'y = null;'而不是'arr [0] = 5;'並且您可能會理解它。 – 2011-04-13 17:20:17

+0

你的代碼中有兩個不同的'b'變量,而不僅僅是一個。 – MeBigFatGuy 2011-04-13 17:29:13

回答

7

Java中的對象引用是按值傳遞的。賦值只是改變了值,並不會改變原來的對象引用。

在您的例子arr[0]改變,但儘量arr=null,你會看到它有沒有效果的方法返回之後。

1

方法調用在Java中被值調用,關於這個問題還有很長時間的爭論,但是我認爲我們應該考慮Java的實現語言C/C++。對象引用只是指向對象的指針,而基元是值。每當調用某個方法時,實際參數都會被複制到形式參數中。因此,如果您將指針更改爲引用另一個對象,則原始指針不受此更改的影響,但如果您更改了對象本身,則主叫方也可以看到更改,因爲雙方都指的是同一對象。

,在你的例子中,你正在將被調用的方法中的字符串引用改爲null,但是你正在改變被數組引用引用的對象。這兩個操作是不一樣的,因此它們有不同的後果。例如,如果你改變代碼如下,他們會在語義上相同的操作..

arr = null; 
0

你cnanot改變參數的任何方法,但你可以做到以下幾點。

public static void main(String... args) throws IOException { 
    String[] strings = {"Hello "}; 
    addWorld(strings); 
    System.out.println("Using an array "+Arrays.toString(strings)); 

    StringBuilder text = new StringBuilder("Hello "); 
    addWorld(text); 
    System.out.println("Using a StringBuilder '" + text+"'"); 
} 

private static void addWorld(String[] strings) { 
    for(int i=0;i<strings.length;i++) 
     strings[i] += "World!"; 
    strings = null; // doesn't do anything. 
} 

private static void addWorld(StringBuilder text) { 
    text.append("World !!"); 
    text = null; // doesn't do anything. 
} 

打印

Using an array [Hello World!] 
Using a StringBuilder 'Hello World !!' 
相關問題