Java到底是傳值還是傳引用?相信很少有人能完全回答正確。通常的說法是:對于基本數據類型(整型、浮點型、字符型、布爾型等),傳值;對于引用類型(對象、數組),傳引用。基本類型傳值,所有人都不會對此有疑義;問題出在引用類型上。
為引入正題,不妨先看看下面的例子,你能正確給出程序的運行結果嘛?
/**?*/
/**
?*?@(#)Swap.java
?*
?*
?*?
@author
?
?*?
@version
?1.00?2007/1/5
?
*/
public
?
class
?Swap?
{

 ????
public
?Swap()?
{
????}
????
 ????
public
?
static
?
void
?main(String[]?args)?
{
????????Changer?c?
=
?
new
?Changer();
????????
????????String?stra?
=
?
"
Mighty
"
;
????????String?strb?
=
?
"
Mouse
"
;
???????????c.swap(stra,?strb);
????????System.out.println(stra?
+
?
"
?
"
?
+
?strb);
????????
????????String[]?strArr?
=
?
new
?String[
2
]?;
????????strArr[
0
]?
=
?stra;
????????strArr[
1
]?
=
?strb;
????????c.swap(strArr);
????????System.out.println(strArr[
0
]?
+
??
"
?
"
?
+
?strArr[
1
]);
????????
????????
????}
????
 ????
static
?
class
?Changer?
{??????
 ????????
public
?
<
T
>
?
void
?swap(T?a,?T?b)?
{
????????????T?temp?
=
?a;
????????????a?
=
?b;
????????????b?
=
?temp;
????????}
????????
 ????????
public
?
<
T
>
?
void
?swap(T[]?t)?
{
 ????????????
if
?(t.length?
<
?
2
)?
{
????????????????System.out.println(
"
error!
"
);
????????????????
return
;
????????????}
????????????
????????????T?temp?
=
?t[
0
];
????????????t[
0
]?
=
?t[
1
];
????????????t[
1
]?
=
?temp;
????????}
????}
????
}
上面程序的正確運行結果為: Mighty Mouse Mouse Mighty 你答對了嘛?
下面我們來分析一下:為什么會出現上面的運行結果?
為分析這個問題,我們必須對程序中的數據在內存中的布局有一定了解。上面main程序中和String相關的變量共有3個,其布局可以用下圖所示:

當調用swap(stra, strb)函數時,傳遞的是引用類型stra、strb的拷貝值,因此函數中任何對參數的改變都不會影響到stra和strb的值;而調用swap(strArr)時,傳遞的是strArr的拷貝值,程序中對參數的任何改變仍然不會影響到strArr的值,然而swap(T[] t)中改變的并不是strArr的值,而是strArr[0]和strArr[1]的值,也就是引用類型strArr所指向的對象的值,因而strArr[0]和strArr[1]的值發生了變化。
從上面的分析,我們可以得出結論:對于引用類型,其實參數傳遞時仍然是按值傳遞的;當然,按引用傳遞也不是完全沒有道理,只是參考對象不是引用類型本身,而是引用類型所指向的對象。
|