java傳值還是傳引用

最近一直在看primer c++,函數一章對c++函數之間傳遞參數有詳細的講解,傳值、傳指針和傳引用的應用與區別都講得很清楚,
以前一直用java,由於java沒有指針,當時也沒有引用這個概念,所以沒有對java參數的傳遞有過多的思考,現在搞清楚了c++
傳遞參數的機制,自然就會跟java進行對比,究竟java傳的是什麼東西?
Java代碼
public static void test(Pass passA); {   
passA = null;  
}
看看, 對passA有什麼影響?
毫無作用。函數調用出來後,passA還是原來的值,不會變成Null.

但是,你的代碼對 passA進行了操作  passA.a ,改變了passA的成員變量。
這個成員變量是一個真實指向String 的 地址,當然能夠被改變。
這就是操作 (.)  和 賦值 (=) 的區別。
這是對 成員變量 a 的 賦值。真正改變了成員變量 a 的值。

注意,這裏傳遞的參數是 passA, 而不是 a.
所以,passA 被複制了一份。passA 的這個副本的 a 變量還 指向 原來的 passA 的 a 變量。
Java中的“引用”是指非原生類型的變量的值保存的是對一個堆上對象的引用。
Java任何時候都是傳值的,只不過該值的語義有所不同罷了

1、對象是按引用傳遞的
2、Java 應用程序有且僅有的一種參數傳遞機制,即按值傳遞
3、按值傳遞意味着當將一個參數傳遞給一個函數時,函數接收的是原始值的一個副本
4、按引用傳遞意味着當將一個參數傳遞給一個函數時,函數接收的是原始值的內存地址,而不是值的副本
寫的沒錯,但是文字太多,第二條就已經把人弄糊塗了,得仔細看完4條才清楚。而且對String類型的疑惑沒有解決。

三句話總結一下:

1.對象就是傳引用

2.原始類型就是傳值

3.String類型因爲沒有提供自身修改的函數,每次操作都是新生成一個String對象,所以要特殊對待。可以認爲是傳值。
在網上查了一下,還是外國人解釋得比較清楚:
Does Java pass by reference or pass by value?
Why can't you swap in Java?
By Tony Sintes, JavaWorld.com, 05/26/00
Q:If Java uses the pass-by reference, why won't a swap function work?
A:Your question demonstrates a common error made by Java language newcomers. Indeed, even seasoned veterans find it difficult to keep the terms straight.

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:

Java代碼
public void badSwap(int var1, int var2)  
 
 int temp = var1;  
 var1 = var2;  
 var2 = temp;  

 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 from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:

Java代碼
 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);    
}  
 
                    

 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:

Java代碼
 X: 0 Y: 0 
X: 0 Y: 0 
X: 100 Y: 100 
X: 0 Y: 0 

 X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0 The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references. When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章