String是值傳遞還是引用傳遞

String是值傳遞還是引用傳遞

今天上班時奴拦,同事發(fā)現(xiàn)了一個比較有意思的問題。他把一個String類型的參數(shù)傳入方法届吁,并在方法內(nèi)改變了引用的值错妖。
然后他在方法外使用這個值,發(fā)現(xiàn)這個String還是之前的值疚沐,并沒有改變暂氯。

這里要向大家介紹一下,大家都知道java在傳參時分為值 傳遞引用傳遞 亮蛔。參數(shù)為基本類型時是值傳遞痴施,
參數(shù)為封裝類型時是引用傳遞。例如:

基本類型參數(shù)

public class Test {
    public static void main(String[] args) {
        int num = 0 ;
        changeNum(num);
        System.out.println("num="+num);
    }

    private static void changeNum(int num) {
        num = 1;
    }
}

打印的結(jié)果是num=0究流。

封裝類型參數(shù)

public class Test {
    public static void main(String[] args) {
        Product p = new Product();
        p.setProName("before");
        p.setNum(0);
        changeProduct(p);
        System.out.println("p.proName="+p.getProName());
        System.out.println("p.num="+p.getNum());
    }

    private static void changeProduct(Product p) {
        p.setProName("after");
        p.setNum(1);
    }
}

class Product {
    private int num;
    private String proName;

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getProName() {
        return proName;
    }

    public void setProName(String proName) {
        this.proName = proName;
    }
}

運行的結(jié)果是:p.proName=afterp.num=1 辣吃。

上面的兩個例子是明顯的值傳遞和引用傳遞。但是如果參數(shù)是String類型呢芬探?我們看一下具體的例子:

public class Test {
    public static void main(String[] args) {
        String str = "ab";
        changeString(str);
        System.out.println("str="+str);
    }

    private static void changeString(String str) {
        str = "cd";
    }
}

大家猜一下運行結(jié)果是什么呢神得?按照前面的例子,String應(yīng)該是一個封裝類型灯节,它應(yīng)該是引用傳遞循头,是可以改變值得绵估,
運行的結(jié)果應(yīng)該是"cd"。我們實際運行一下看看卡骂,

str=ab,這如何解釋呢国裳?難道String是基本類型?也說不通呀全跨。

這就要從java底層的機制講起了缝左,java的內(nèi)存模型分為

1.基本類型的變量放在棧里浓若;
2.封裝類型中渺杉,對象放在堆里,對象的引用放在棧里挪钓。

java在方法傳遞參數(shù)時是越,是將變量復(fù)制一份,然后傳入方法體去執(zhí)行碌上。 這句話是很難理解的倚评,也是解釋這個
問題的精髓。我們先按照這句話解釋一下基本類型的傳遞

  1. 虛擬機分配給num一個內(nèi)存地址馏予,并且存了一個值0.
  2. 虛擬機復(fù)制了一個num天梧,我們叫他num',num'和num的內(nèi)存地址不同霞丧,但存的值都是0呢岗。
  3. 虛擬機講num'傳入方法,方法將num'的值改為1.
  4. 方法結(jié)束蛹尝,方法外打印num的值后豫,由于num內(nèi)存中的值沒有改變,還是0箩言,所以打印是0.

我們再解釋封裝類型的傳遞:

  1. 虛擬機在堆中開辟了一個Product的內(nèi)存空間硬贯,內(nèi)存中包含proName和num。
  2. 虛擬機在棧中分配給p一個內(nèi)存地址陨收,這個地址中存的是1中的Product的內(nèi)存地址饭豹。
  3. 虛擬機復(fù)制了一個p,我們叫他p',p和p'的內(nèi)存地址不同务漩,但它們存的值是相同的拄衰,都是1中Product的內(nèi)存地址。
  4. 將p'傳入方法饵骨,方法改變了1中的proName和num翘悉。
  5. 方法結(jié)束,方法外打印p中變量的值居触,由于p和p'中存的都是1中Product的地址妖混,但是1中Product里的值發(fā)生了改變老赤,
    所以,方法外打印p的值制市,是方法執(zhí)行以后的抬旺。我們看到的效果是封裝類型的值是改變的。

最后我們再來解釋String在傳遞過程中的步驟:

  1. 虛擬機在堆中開辟一塊內(nèi)存祥楣,并存值"ab"开财。
  2. 虛擬機在棧中分配給str一個內(nèi)存,內(nèi)存中存的是1中的地址误褪。
  3. 虛擬機復(fù)制一份str责鳍,我們叫str',str和str'內(nèi)存不同兽间,但存的值都是1的地址历葛。
  4. 將str'傳入方法體
  5. 方法體在堆中開辟一塊內(nèi)存,并存值"cd"
  6. 方法體將str'的值改變渡八,存入5的內(nèi)存地址
  7. 方法結(jié)束啃洋,方法外打印str,由于str存的是1的地址屎鳍,所有打印結(jié)果是"ab"

這樣我們理解了java在方法傳參的整個過程。其實還是上面那句比較重要的話 java在方法傳遞參數(shù)時问裕,是將變量復(fù)制一份逮壁,然后傳入方法體去執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末粮宛,一起剝皮案震驚了整個濱河市窥淆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巍杈,老刑警劉巖忧饭,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異筷畦,居然都是意外死亡词裤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門鳖宾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吼砂,“玉大人,你說我怎么就攤上這事鼎文∮婕纾” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵拇惋,是天一觀的道長周偎。 經(jīng)常有香客問我抹剩,道長,這世上最難降的妖魔是什么蓉坎? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任澳眷,我火速辦了婚禮,結(jié)果婚禮上袍嬉,老公的妹妹穿的比我還像新娘境蔼。我一直安慰自己,他們只是感情好伺通,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布箍土。 她就那樣靜靜地躺著,像睡著了一般罐监。 火紅的嫁衣襯著肌膚如雪吴藻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天弓柱,我揣著相機與錄音沟堡,去河邊找鬼。 笑死矢空,一個胖子當(dāng)著我的面吹牛航罗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屁药,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼粥血,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了酿箭?” 一聲冷哼從身側(cè)響起复亏,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缭嫡,沒想到半個月后缔御,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡妇蛀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年耕突,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讥耗。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡有勾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出古程,到底是詐尸還是另有隱情蔼卡,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站雇逞,受9級特大地震影響荤懂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜塘砸,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一节仿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掉蔬,春花似錦廊宪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛉迹,卻和暖如春傅寡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背北救。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工荐操, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人珍策。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓托启,卻偏偏與公主長得像,于是被迫代替她去往敵國和親攘宙。 傳聞我的和親對象是個殘疾皇子驾中,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)模聋,斷路器,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,090評論 1 32
  • 不知不覺的它來了, 恍過你的雙眼它匆匆的去了. 來的時候它給你措手不及, 走的時候它悄無聲息. 它是世間的萬事萬物...
    心態(tài)決定一切堂主閱讀 277評論 0 0
  • 看過好多文章寫人老了怎么怎么樣唠亚,有的變成了空巢老人链方,有的變成了碰瓷大媽,詩中所謂的伊人和田園在這個社會里似乎...
    書簽作家淺色閱讀 437評論 2 3
  • 跟熟人或同事提起孩子灶搜,大家一致稱贊祟蚀,稱贊的地方很多,搞得我很不好意思割卖! 的確前酿,拋開學(xué)習(xí),孩子的確有可圈可點的地方鹏溯。...
    看景閱讀 221評論 0 0