Java中方法調用參數傳遞的方式是傳值,儘管傳的是引用的值而不是對象的值。(Does Java pass by reference or pass by value?)

來源:互聯網
上載者:User
文章目錄
  • About the author

原文地址:http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

在Java中,所有的物件變數都是引用,Java通過引用來管理對象。然而在給方法傳參時,Java並沒有使用傳引用的方式,而是採用了傳值的方式。例如下面的badSwap()方法:

public void badSwap(int var1, int var2){  int temp = var1;  var1 = var2;  var2 = temp;}

當badSwap方法時,原有的var1和var2的值並不會發生變化。即使我們用其它Object類型來替代int,也不會有變化,因為Java在傳遞引用時也是採用傳值的方式。(譯者註:這裡是關鍵,全文的核心是:1. Java中物件變數是引用 2. Java中方法是傳值的 3. 傳方法中參數時,傳遞的是引用的值)

如果譯者的注釋沒看明白,沒關係,看看下面的代碼:

public void tricky(Point arg1, Point arg2){  arg1.x = 100;  arg1.y = 100;  Point temp = arg1;  arg1 = arg2;  arg2 = temp;}public static void main(String [] args){  Point pnt1 = new Point(0,0);  Point pnt2 = new Point(0,0);  System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);   System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  System.out.println(" ");  tricky(pnt1,pnt2);  System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);   System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  }

執行main()的輸出如下:

X: 0 Y: 0X: 0 Y: 0X: 100 Y: 100X: 0 Y: 0

這個方法成功地改變了pnt1的值,但pnt1和pnt2的交換卻失敗了!這是Java參數傳遞機制裡最讓人迷惑的地方。在main()中,pnt1和pnt2是Point對象的引用,當將pnt1和pnt2傳遞給tricky()時,Java使用的正是傳值的方式,將這兩個引用的傳給了arg1和arg2。也就是說arg1和arg2正是pnt1和pnt2的複製,他們所指向的對象是相同的。詳情可見下面的圖示:

圖 1. 在作為參數傳遞後,對象至少有兩個引用指向自己

Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references
are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call,
we need to swap the original references, not the copies.

在main()中,引用被複製並以傳值的方式進行傳遞,對象本身並不會被傳遞。因此,tricky()方法中pnt1所指向的對象發生了變化。因為傳遞的是引用的複製,因此引用的交換既不能引起對象的交換,更不會使原始引用發生變化。2所示,tricky()交換了arg1與arg2,但不會影響pnt1和pnt2。因此若想交換原始引用pnt1和pnt2,那麼不能通過調用方法的方式來實現。

圖 2. 只有作為參數的引用發生了交換,但原始引用並沒有變化

總結:

1. Java中物件變數是引用 

2. Java中方法是傳值的 

3. 傳方法中參數時,傳遞的是引用的值

原文如下:

Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.

Take the badSwap() method for example:

public void badSwap(int var1, int var2){  int temp = var1;  var1 = var2;  var2 = temp;}

When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type fromint toObject, since Java passes object references by value
as well. Now, here is where it gets tricky:

public void tricky(Point arg1, Point arg2){  arg1.x = 100;  arg1.y = 100;  Point temp = arg1;  arg1 = arg2;  arg2 = temp;}public static void main(String [] args){  Point pnt1 = new Point(0,0);  Point pnt2 = new Point(0,0);  System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);   System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  System.out.println(" ");  tricky(pnt1,pnt2);  System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);   System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  }

If we execute this main() method, we see the following output:

X: 0 Y: 0X: 0 Y: 0X: 100 Y: 100X: 0 Y: 0

The method successfully alters the value of pnt1, even though it is passed by value; however, a swap ofpnt1 andpnt2 fails! This is the major source of confusion. In themain() method,pnt1 andpnt2
are nothing more than object references. When you passpnt1 andpnt2 to thetricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actuallycopies
of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.

Figure 1. After being passed to a method, an object will have at least two references

Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail. As Figure 2 illustrates, the
method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies.

Figure 2. Only the method references are swapped, not the original ones

About the author

Tony Sintes is a principal consultant at BroadVision. Tony, a Sun-certified Java 1.1 programmer and Java 2 developer, has worked with Java since 1997.O'Reilly'sJava in a Nutshell by David Flanagan (seeResources)
puts it best: "Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'" As a result, you cannot write a standard swap method to swap objects.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.