Java參數(shù)傳遞-引用傳遞vs.值傳遞

Java中的變量類型基本分為兩種:基本類型和引用類型。

  • 基本類型為全小寫字母,如:int, long, short, char等;
  • 引用類型為首字母大,如:String, Integer, User 等。

其中引用類型中又有一些是“不可變引用類型”,如:String, Integer等。
對于基本類型作為方法的參數(shù)傳遞的是值本身,沒什么問題。
對于引用類型作為方法的參數(shù)傳遞的是地址,看下面的例子。
Demo1

String s = "abc";
changeValue(s);
System.out.println(s); //abc

public static void changeValue(String str){
    str+="cde";
}

在調(diào)用changeValue方法的時候,會將變量s指向的字符串“abc”的地址3a傳給局部變量str,這時str也指向字符串“abc”。而在Java中String是不可改變的,若改變String類型變量的值,只能是在字符串常量池中新創(chuàng)建一個字符串“abccde”。而這時,str通過地址3b指向了字符串常量“abccde”。而s依舊通過地址3a指向字符串常量“abc”。因此調(diào)用端輸出s的值為“abc”(未改變)。

Demo2

StringBuffer sb = new StringBuffer("abc");
changeValue(sb);
System.out.println(sb); //abccde

public static void changeValue(StringBuffer str){
    str.append("cde");
}

在調(diào)用changeValue的時候,同樣會吧sb指向的對象的堆內(nèi)存地址3a傳給局部變量str,這時str也指向該塊地址。然后調(diào)用str的append方法時,在該堆內(nèi)存區(qū)域中追加了字符串“cde”,3a處的對象本身改變了。因此在調(diào)用端輸出sb的時候,表示輸出3a處的對象,因此,輸出的是改變后的值。

Demo3

StringBuffer sb1 = new StringBuffer("111");
StringBuffer sb2 = new StringBuffer("222");
swap(sb1, sb2);
System.out.println("sb1="+sb1);
System.out.println("sb2="+sb2);

public static void swap(StringBuffer s1, StringBuffer s2){
    StringBuffer sb = s1;
    s1=s2;
    s2=sb;
}

在調(diào)用swap方法的時候,會將sb1指向的對象的內(nèi)存地址3a,sb2指向的內(nèi)存地址3b分別傳給局部變量s1,s2。接下來,通過中間局部變量sb將s1和s2的值交換了,交換后s1指向內(nèi)存地址3b,s2指向內(nèi)存地址3a。而從始至終sb1和sb2所指向的內(nèi)存地址并未改變,sb1—>3a,sb2—>3b。所以,在調(diào)用端輸出的時候,sb1輸出“111”,sb2輸出“222”。

結(jié)論

有人說Java中參數(shù)的傳遞都是值傳遞,不存在引用傳遞。也有人不這么認為。然而,只要理解了參數(shù)傳遞的本質(zhì)就行了。

首先,基本類型的參數(shù),傳遞的肯定是值本身,因為基本類型的變量存在JVM的棧內(nèi)存中。不存在堆內(nèi)存地址的概念;

其次,引用類型的參數(shù)(不管是可變引用類型還是不可變引用類型)傳遞的都是該變量所指向的堆內(nèi)存的地址。而在調(diào)用方法的時候,會將這個地址的值賦給方法的局部變量,使得這個局部變量也指向相應的堆內(nèi)存。

只不過,如果是不可變引用類型的參數(shù),當對局部變量賦新值時,本質(zhì)上是開辟了新的內(nèi)存區(qū)域放入新值,使局部變量指向新的內(nèi)存區(qū)域,因此不會改變調(diào)用端變量的值。

而如果是可變引用類型的參數(shù),當改變對象的內(nèi)容時,改變是這個對象所在內(nèi)存中的值,因此,在調(diào)用端讀取的時候是改變后的值。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,783評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,633評論 18 399
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,593評論 30 472
  • 一到過年各種拜年信息就層出不窮。以前是短信拜年,現(xiàn)在發(fā)展到了微信拜年。一提到拜年信息,很多人都表示收到過群發(fā)信息,...
    佳期diane閱讀 2,465評論 2 3
  • 2017年11月08日 九月二十 星期三 晴 一場大風吹走了霧霾,今天天空晴朗。下午大家一起來到果園,跟姜老師學習...
    土蜂閱讀 1,460評論 0 0

友情鏈接更多精彩內(nèi)容