<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          值傳遞與引用傳遞

          共 3717字,需瀏覽 8分鐘

           ·

          2021-05-24 16:14

          “哥,說(shuō)說(shuō) Java 到底是值傳遞還是引用傳遞吧?”三妹一臉的困惑,看得出來(lái)她被這個(gè)問(wèn)題折磨得不輕。

          “說(shuō)實(shí)在的,我在一開(kāi)始學(xué) Java 的時(shí)候也被這個(gè)問(wèn)題折磨得夠嗆,總以為基本數(shù)據(jù)類型在傳參的時(shí)候是值傳遞,而引用類型是引用傳遞。”我對(duì)三妹袒露了心聲,為的就是讓她不再那么焦慮,她哥當(dāng)年也是這么過(guò)來(lái)的。

          C 語(yǔ)言是很多編程語(yǔ)言的母胎,包括 Java,那么對(duì)于 C 語(yǔ)言來(lái)說(shuō),所有的方法參數(shù)都是“通過(guò)值”傳遞的,也就是說(shuō),傳遞給被調(diào)用方法的參數(shù)值存放在臨時(shí)變量中,而不是存放在原來(lái)的變量中。這就意味著,被調(diào)用的方法不能修改調(diào)用方法中變量的值,而只能修改其私有變量的臨時(shí)副本的值。

          Java 繼承了 C 語(yǔ)言這一特性,因此 Java 是按照值來(lái)傳遞的。

          接下來(lái),我們必須得搞清楚,到底什么是值傳遞(pass by value),什么是引用傳遞(pass by reference),否則,討論 Java 到底是值傳遞還是引用傳遞就顯得毫無(wú)意義。

          當(dāng)一個(gè)參數(shù)按照值的方式在兩個(gè)方法之間傳遞時(shí),調(diào)用者和被調(diào)用者其實(shí)是用的兩個(gè)不同的變量——被調(diào)用者中的變量(原始值)是調(diào)用者中變量的一份拷貝,對(duì)它們當(dāng)中的任何一個(gè)變量修改都不會(huì)影響到另外一個(gè)變量,據(jù)說(shuō) Fortran 語(yǔ)言是通過(guò)引用傳遞的。

          “Fortran 語(yǔ)言?”三妹睜大了雙眼,似乎聽(tīng)見(jiàn)了什么新的名詞。

          “是的,F(xiàn)ortran 語(yǔ)言,1957 年由 IBM 公司開(kāi)發(fā),是世界上第一個(gè)被正式采用并流傳至今的高級(jí)編程語(yǔ)言。”

          當(dāng)一個(gè)參數(shù)按照引用傳遞的方式在兩個(gè)方法之間傳遞時(shí),調(diào)用者和被調(diào)用者其實(shí)用的是同一個(gè)變量,當(dāng)該變量被修改時(shí),雙方都是可見(jiàn)的。

          “我們之所以容易搞不清楚 Java 到底是值傳遞還是引用傳遞,主要是因?yàn)?Java 中的兩類數(shù)據(jù)類型的叫法容易引發(fā)誤會(huì),比如說(shuō) int 是基本類型,說(shuō)它是值傳遞的,我們就很容易理解;但對(duì)于引用類型,比如說(shuō) String,說(shuō)它也是值傳遞的時(shí)候,我們就容易弄不明白。”

          我們來(lái)看看基本數(shù)據(jù)類型和引用數(shù)據(jù)類型之間的差別。

          int age = 18;
          String name = "二哥";

          age 是基本類型,值就保存在變量中,而 name 是引用類型,變量中保存的是對(duì)象的地址。一般稱這種變量為對(duì)象的引用,引用存放在棧中,而對(duì)象存放在堆中。

          這里說(shuō)的棧和堆,是指內(nèi)存中的一塊區(qū)域,和數(shù)據(jù)結(jié)構(gòu)中的棧和堆不一樣。棧是由編譯器自動(dòng)分配釋放的,所以適合存放編譯期就確定生命周期的數(shù)據(jù);而堆中存放的數(shù)據(jù),編譯器是不需要知道生命周期的,創(chuàng)建后的回收工作由垃圾收集器來(lái)完成。

          “畫(huà)幅圖。”

          當(dāng)用 = 賦值運(yùn)算符改變 age 和 name 的值時(shí)。

          age = 16;
          name = "三妹";

          對(duì)于基本類型 age,賦值運(yùn)算符會(huì)直接改變變量的值,原來(lái)的值被覆蓋。

          對(duì)于引用類型 name,賦值運(yùn)算符會(huì)改變對(duì)象引用中保存的地址,原來(lái)的地址被覆蓋,但原來(lái)的對(duì)象不會(huì)被覆蓋。

          “三妹,注意聽(tīng),接下來(lái),我們來(lái)說(shuō)說(shuō)基本數(shù)據(jù)類型的參數(shù)傳遞。”

          Java 有 8 種基本數(shù)據(jù)類型,分別是 int、long、byte、short、float、double 、char 和 boolean,就拿 int 類型來(lái)舉例吧。

          class PrimitiveTypeDemo {
              public static void main(String[] args) {
                  int age = 18;
                  modify(age);
                  System.out.println(age);
              }

              private static void modify(int age1) {
                  age1 = 30;
              }
          }

          1)main() 方法中的 age 為基本類型,所以它的值 18 直接存儲(chǔ)在變量中。

          2)調(diào)用 modify() 方法的時(shí)候,將會(huì)把 age 的值 18 復(fù)制給形參 age1。

          3)modify() 方法中,對(duì) age1  做出了修改。

          4)回到 main() 方法中,age 的值仍然為 18,并沒(méi)有發(fā)生改變。

          如果我們想讓 age 的值發(fā)生改變,就需要這樣做。

          class PrimitiveTypeDemo1 {
              public static void main(String[] args) {
                  int age = 18;
                  age = modify(age);
                  System.out.println(age);
              }

              private static int modify(int age1) {
                  age1 = 30;
                  return age1;
              }
          }

          第一,讓 modify() 方法有返回值;

          第二,使用賦值運(yùn)算符重新對(duì) age 進(jìn)行賦值。

          “好了,再來(lái)說(shuō)說(shuō)引用類型的參數(shù)傳遞。”

          就以 String 為例吧。

          class ReferenceTypeDemo {
              public static void main(String[] args) {
                  String name = "二哥";
                  modify(name);
                  System.out.println(name);
              }

              private static void modify(String name1) {
                  name1 = "三妹";
              }
          }

          在調(diào)用 modify() 方法的時(shí)候,形參 name1 復(fù)制了 name 的地址,指向的是堆中“二哥”的位置。

          當(dāng) modify() 方法調(diào)用結(jié)束后,改變了形參 name1 的地址,但 main() 方法中 name 并沒(méi)有發(fā)生改變。

          總結(jié):

          • Java 中的參數(shù)傳遞是按值傳遞的。
          • 如果參數(shù)是基本類型,傳遞的是基本類型的字面量值的拷貝。
          • 如果參數(shù)是引用類型,傳遞的是引用的對(duì)象在堆中地址的拷貝。

          “好了,三妹,今天的學(xué)習(xí)就到這吧。”

          PS:點(diǎn)擊「閱讀原文」可直達(dá)《教妹學(xué)Java》專欄的 GitHub 開(kāi)源地址,記得 star 哦!

          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色逼逼 | 色婷婷国产精品一区在线观看 | 中文电视剧字幕在线播放网站 | 天堂中文资源库 | 日韩 欧美 国产高清91 |