程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 【Simple Java】字符串是通過“引用”傳遞的,simplejava

【Simple Java】字符串是通過“引用”傳遞的,simplejava

編輯:JAVA綜合教程

【Simple Java】字符串是通過“引用”傳遞的,simplejava


這是Java中一個很經典的問題,在stack-overflow上有很多類似的問題,然而很多回答都是錯的或者回答不完整;如果你不深入思考的話,會認為這個問題很簡單,但是當你深入下去,會發現這個問題很容易讓人產生困惑。

一段有趣且讓人困惑的代碼

package simplejava;

public class Q14 {

    public static void change(String x) {
        x = "cd";
    }

    public static void main(String[] args) {
        String x = new String("ab");
        change(x);
        System.out.println(x);
    }

}

結果打印:

ab

C++版本如下:

void change(string &x) {
    x = "cd";
}
int main(){
    string x = "ab";
    change(x);
    cout << x << endl;
}

打印結果:

cd

常見有誤的理解

x變量存儲了堆中“ab”對象的引用,當x作為一個參數傳入到change()方法內部時,仍然指向堆中的“ab”對象,如下所示:

因為Java是按值傳遞的,x的值是“ab”對象的引用,當方法change()被調用時,創建了一個新的對象“cd”,然後x指向“cd”對象,如下圖所示:

這看起來像是一個完美的解釋,他們很清楚Java總是按值傳遞的。但是,問題到底出在哪裡呢?

這段代碼到底究竟在做什麼

上面的解釋有若干處錯誤,為了更加容易的理解該問題,我們還是先理清下整個過程。

當字符串對象“ab”被創建的時候,Java分配了對應大小的內存空間,然後對象被賦值給變量x,事實上是x變量存儲的是對象的引用,這個引用是“ab”對象在內存中的地址;

x變量包含了對象的引用,x並不是“ab”對象,而是一個存儲了“ab”對象引用(內存地址)的變量。

Java是按值傳遞的,當x被傳入change()方法的時候,事實上傳入的是一個x變量的拷貝。然後在方法change()內部創建了另一個對象“cd”,它有一個不同的引用。真正改變的是這個x變量的拷貝,其值變成了“cd”對象的引用,而不是原始的x變量被改變;

注:感覺說得有點混亂,我的理解,先說這個參數x,其相當於一個局部變量,當使用該參數的時候,將會分配一個新的存儲位置,將實參拷貝到該位置,並將該拷貝值傳遞給該方法;

在change()方法內部,執行x = "cd"的時候,這裡的x實際上是main方法的x變量的一個拷貝,一開始其存放的是“ab對象”的引用,執行完這段代碼後,其值變成“cd”對象的引用,而main方法的x變量並沒有改變,存放的仍然是“ab”對象的引用。

另一錯誤解釋

這個問題的原因跟字符串的不變形沒任何關系,即使將String替換成StringBuilder對象,結果仍然不變,關鍵點是變量存儲的是對象的引用,而不是對象本身;

解決這個問題的方法

如果真的想改變這個對象的值,

首先這個對象是要可改變的,例如StringBuilder。

其次,我們要保證沒有新對象被創建賦值給參數變量,因為Java只能按值傳遞。

如下代碼:

public static void main(String[] args) {
    StringBuilder x = new StringBuilder("ab");
    change(x);
    System.out.println(x);
}
public static void change(StringBuilder x) {
    x.delete(0, 2).append("cd");
}

 

譯文鏈接:http://www.programcreek.com/2013/09/string-is-passed-by-reference-in-java/

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved