Thinker

            - long way to go...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            24 隨筆 :: 0 文章 :: 143 評論 :: 0 Trackbacks
          先給出兩個例子引出今天所要討論的問題:
           1 
           2 public class Person
           3 {
           4   private String name = null;
           5   private int age = 0;
           6 
           7   public Person(String name, int age) {
           8     this.name = name;
           9     this.age = age;
          10   }
          11 
          12   public void changeName(String newName) {
          13     this.name = newName;
          14   }
          15 
          16   public void changeAge(int newAge) {
          17     this.age = newAge;
          18   }
          19 
          20   public String toString() {
          21     return "Person - Name: " + name + ", Age: " + age;
          22   }
          23 }
          24 
          25 public class PassByValue
          26 {
          27   public static void main(String[] args) {
          28     // one example
          29     String value1 = "value1: aaa";
          30     String value2 = "value2: bbb";
          31 
          32     swapValue(value1, value2);
          33 
          34     System.out.println(value1);
          35     System.out.println(value2);
          36 
          37     // another example
          38     Person person = new Person("張三"20);
          39 
          40     System.out.println(person.toString());
          41 
          42     changePerson(person);
          43 
          44     System.out.println(person.toString());
          45   }
          46 
          47   public static void swapValue(String tmpValue1, String tmpValue2) {
          48     String tempStr = tmpValue1;
          49     tmpValue1 = tmpValue2;
          50     tmpValue2 = tempStr;
          51   }
          52 
          53   public static void changePerson(Person tmpPerson) {
          54     tmpPerson.changeName("李四");
          55     tmpPerson.changeAge(30);
          56   }
          57 }
          58 

          考慮一下上面這段代碼的輸出結果是什么?
          我相信絕大多數人都能快速的給出正確答案:
          value1: aaa
          value2: bbb
          Person - Name: 張三, Age: 20
          Person - Name: 李四, Age: 30
          答案為什么是這樣的呢?那么 Java 到底是按值傳遞還是按引用傳遞參數的呢?
          例子1中的 swapValue() 方法不起作用,看起來是按值傳遞參數的,例子2中的 changeName() 和 changeAge() 方法起作用,從表面上看起來好像又是按引用傳遞參數的。呵呵,別急,先讓我們來弄清楚一個重要的概念,就是 Java 操縱對象都是通過引用來實現的,所有的對象變量都是所指向的對象的引用,那也就是說所有對象變量的值并不是它所指向的對象本身,而是該對象的引用,這句話聽起來可能有點讓人犯暈,舉個例子來說,String str = new String("aaa"); 這條語句的意思是 new 了一個值為 "aaa" 的字符串對象,然后用一個名字叫 str 的對象變量來指向它,保存它的引用,假設在內存中 new 出來的這個字符串對象的實際地址為 0xA242, 那么 str 的值實際上是 0xA242。
          現在來看看例子1,假設
          String value1 = "value1: aaa" 的地址為 0xA242,
          String value2 = "value2: bbb" 的地址為 0xA24B,
          然我們來看看 swapValue(value1, value2); 語句 Java 是怎么執行的。當程序執行到這句語句的時候,JVM 在棧中創建兩個臨時變量 tmpValue1,tmpValue2,用來接收傳進來的 value1 和 value2 的值,而 value1 和 value2 的值分別為 0xA242 和 0xA24B,所以那兩個臨時變量 tmpValue1和tmpValue2 的值也被賦值為 0xA242 和 0xA24B,此時接下來的三條語句分別是
          tempStr = 0xA242,
          tmpValue1 = 0xA24B,
          tmpValue2 = 0xA242;
          此時 tmpValue1 的值是指向 "value2: bbb" 這個對象的,
             tmpValue2 的值是指向 "value1: aaa" 這個對象,你可以在 swapValue() 方法內部打印 tmpValue1 和 tmpValue2 的值驗證一下。
          不過這里的 tmpValue1和tmpValue2 是在棧中的臨時變量,而并不是 main 方法中 value1和value2,main 方法中 value1和value2 的值并沒有改變,那這里所謂的值傳遞是指什么呢?因為 value1 的值是 0xA242("value1: aaa" 這個對象的引用),而并不是 "value1: aaa" 這個對象,傳遞參數時傳遞的是 "value1: aaa" 這個對象的引用也就是 value1 的值,所以是值傳遞。
          例子2也是一樣的,假設
          Person person = new Person("張三", 20) 的地址為 0xA242,
          那么 person 的值是 0xA242, 那么通過調用 changePerson(person); 將 0xA242 傳遞給 tmpPerson, 也就是 tmpPerson 此時的值為 0xA242 也就是 new Person("張三", 20) 這個對象的引用,也就是說 tmpPerson 指向 new Person("張三", 20) 對象,對 tmpPerson 引用對象的修改實際上就是對 person 引用對象的修改,這看起來很想引用傳遞的概念,但實際上是值傳遞,為什么呢?因為在參數傳遞過程中傳遞的是 person 的值,也就是 0xA242。
          呵呵,好好體會吧。
          歡迎來信指正錯誤。

          http://www.aygfsteel.com/qujinlong123/
          posted on 2007-04-16 19:52 Long 閱讀(9020) 評論(18)  編輯  收藏 所屬分類: Java

          評論

          # re: Java 是值傳遞還是引用傳遞? 2007-04-16 19:59 劉甘泉
          老問題了,T.I.J里面也有詳細的解釋  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-04-17 10:16 嘎嘎
          java傳的是對象引用的地址??  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-04-17 12:18 Long
          @嘎嘎
          對于對象來說,java 傳的是對象的引用  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-04-17 13:18 ice4x
          對于值類型來說,傳遞的就是值,對于對象,傳遞的就是對象的引用。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-04-18 13:30 靜兒
          本來覺得是很簡單的問題 。經閣下一講解,發現自己原來真的有點概念不清。謝謝了!  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-05-17 23:37 Jerry Tao
          簡單的說,Java 只有值傳遞。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-05-18 00:32 Long
          @Jerry Tao
          不錯,Java是只有值傳遞,但是這個“值”是別有深意的,而且也經常會困擾初學者的。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-05-26 00:21 天涯客
          樓主的例子上當然還涉及到一個問題:因為String是Imutable的  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-05-26 00:22 天涯客
          樓主的例子上當然還涉及到一個問題:因為String是Immutable的   回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-05-26 00:40 Long
          @天涯客
          至于Java對String對象本身的管理對傳遞參數來說是無關系的,無論String是不是Immutable,它都是一個對象,對象的傳遞方式都是一樣的。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2007-07-02 16:42 青松
          java是值傳遞.

          只不過對象的引用是和對象是遙控器與電視的關系.遙控器和電視都沒有變.
          變的只是節目  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2010-06-21 10:48 ne_akari
          這帖子居然在搜索第一頁,害人不淺啊。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2010-06-21 10:55 ne_akari
          這個例子根本沒有任何說服力,可以看出,博主本身并沒有理解這個問題。
          第一個String沒有改變值可以說明,在這個例子中是值傳遞。
          而第二個Person屬性的值的改變,是示例方法里使用的是引用的形式來改變屬性的,與對象本身的調用是值傳遞或者引用傳遞沒有任何關系。
          人們總是很輕易地相信一個事實,總是很輕易地得到一個結論,而不去考慮更多。
          什么是值傳遞,什么是引用傳遞,這個定義你搞清楚了嗎?
          好好思考下吧,或者好好GOOGLE下吧,難道引用地址就不可以再被復制一份嗎?你沒想到的,有可能正是答案的所在。  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞?[未登錄] 2010-07-13 12:14 java
          @ne_akari
          亂七八糟的SB回復  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2011-02-10 17:39 tone
          tempStr = 0xA242,
          tmpValue1 = 0xA24B,
          tmpValue2 = 0xA242

          你寫的是什么,tmpValue1 和 tmpValue2 傳的不都是引用??
          因為他們是tmp臨時的對象 然后接收了引用了

          但是又要記住你這不是new出來的,是常量池中的數據所以,改變不了

          而且
          值參數傳遞那么, 等號= 左邊的變量肯定是開辟一個新的地址(物理內存),然后把等號右邊的地址中的內容弄過來,弄過來的是內容!

          而引用傳遞, 就是 等號= 左邊的就是一個地址(類似指針),然后把等號右邊的地址給弄過來

            回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2011-02-10 17:44 tone
          @tone
          我QQ669112773 你來找我  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2011-02-10 18:31 tone
          對象也是引用傳遞啊

          和數組一樣 數組名 傳的是它的首地址 引用傳遞
          而后面的 元素或者說屬性 的傳遞 是值傳遞  回復  更多評論
            

          # re: Java 是值傳遞還是引用傳遞? 2011-05-23 10:19
          樓主本來就有理解錯誤,JAVA本來就是用值傳遞.第一個就是典型的值傳遞,值傳遞是開辟一個新內存把原變量來指向的值復制過來...回去看一下值傳遞和引用傳遞概念再發文章吧,不要在這里誤導人  回復  更多評論
            

          主站蜘蛛池模板: 会宁县| 略阳县| 云浮市| 社会| 安西县| 甘孜县| 休宁县| 芦山县| 封丘县| 武山县| 扶风县| 罗城| 靖州| 三穗县| 柳州市| 舞阳县| 桦川县| 康平县| 承德市| 石渠县| 南城县| 边坝县| 仙桃市| 苍南县| 永胜县| 古丈县| 铁岭县| 资源县| 银川市| 绍兴市| 青神县| 搜索| 金华市| 南雄市| 天门市| 盐津县| 汉中市| 乐至县| 志丹县| 广东省| 济南市|