<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java,J2EE,Weblogic,Oracle

    java項目隨筆
    隨筆 - 90, 文章 - 6, 評論 - 61, 引用 - 0
    數(shù)據(jù)加載中……

    java 值傳遞 引用傳遞

    Java代碼
    public class ParamTest {  
        // 初始值為0  
        protected int num = 0;  
     
        // 為方法參數(shù)重新賦值  
        public void change(int i) {  
            i = 5;  
        }  
     
        // 為方法參數(shù)重新賦值  
        public void change(ParamTest t) {  
            ParamTest tmp = new ParamTest();  
            tmp.num = 9;  
            t = tmp;  
        }  
     
        // 改變方法參數(shù)的值  
        public void add(int i) {  
            i += 10;  
        }  
     
        // 改變方法參數(shù)屬性的值  
        public void add(ParamTest pt) {  
            pt.num += 20;  
        }  
     
        public static void main(String[] args) {  
            ParamTest t = new ParamTest();  
     
            System.out.println("參數(shù)--基本類型");  
            System.out.println("原有的值:" + t.num);  
            // 為基本類型參數(shù)重新賦值  
            t.change(t.num);  
            System.out.println("賦值之后:" + t.num);  
            // 為引用型參數(shù)重新賦值  
            t.change(t);  
            System.out.println("運算之后:" + t.num);  
     
            System.out.println();  
     
            t = new ParamTest();  
            System.out.println("參數(shù)--引用類型");  
            System.out.println("原有的值:" + t.num);  
            // 改變基本類型參數(shù)的值  
            t.add(t.num);  
            System.out.println("賦引用后:" + t.num);  
            // 改變引用類型參數(shù)所指向?qū)ο蟮膶傩灾?nbsp; 
            t.add(t);  
            System.out.println("改屬性后:" + t.num);  
        }  

    這段代碼的運行結(jié)果如下:

    參數(shù)--基本類型
    原有的值:0
    賦值之后:0
    運算之后:0

    參數(shù)--引用類型
    原有的值:0
    賦引用后:0
    改屬性后:20

    從上面這個直觀的結(jié)果中我們很容易得出如下結(jié)論:

    對于基本類型,在方法體內(nèi)對方法參數(shù)進(jìn)行重新賦值,并不會改變原有變量的值。
    對于引用類型,在方法體內(nèi)對方法參數(shù)進(jìn)行重新賦予引用,并不會改變原有變量所持有的引用。
    方法體內(nèi)對參數(shù)進(jìn)行運算,不影響原有變量的值。
    方法體內(nèi)對參數(shù)所指向?qū)ο蟮膶傩赃M(jìn)行運算,將改變原有變量所指向?qū)ο蟮膶傩灾怠?

    上面總結(jié)出來的不過是我們所看到的表面現(xiàn)象。那么,為什么會出現(xiàn)這樣的現(xiàn)象呢?這就要說到值傳遞和引用傳遞的概念了。這個問題向來是頗有爭議的。

    大家都知道,在JAVA中變量有以下兩種:

    基本類型變量,包括char、byte、short、int、long、float、double、boolean。
    引用類型變量,包括類、接口、數(shù)組(基本類型數(shù)組和對象數(shù)組)。

    當(dāng)基本類型的變量被當(dāng)作參數(shù)傳遞給方法時,JAVA虛擬機所做的工作是把這個值拷貝了一份,然后把拷貝后的值傳遞到了方法的內(nèi)部。因此在上面的例子中,我們回頭來看看這個方法:
    Java代碼 
    // 為方法參數(shù)重新賦值   
    public   void  change( int  i) {  
        i = 5 ;  
    }  
    Java代碼
    // 為方法參數(shù)重新賦值  
    public void change(int i) {  
        i = 5;  

     // 為方法參數(shù)重新賦值
     public void change(int i) {
      i = 5;
     }

    在這個方法被調(diào)用時,變量i和ParamTest型對象t的屬性num具有相同的值,卻是兩個不同變量。變量i是由JAVA虛擬機創(chuàng)建的作用域在 change(int i)方法內(nèi)的局部變量,在這個方法執(zhí)行完畢后,它的生命周期就結(jié)束了。在JAVA虛擬機中,它們是以類似如下的方式存儲的:

     

    很明顯,在基本類型被作為參數(shù)傳遞給方式時,是值傳遞,在整個過程中根本沒有牽扯到引用這個概念。這也是大家所公認(rèn)的。對于布爾型變量當(dāng)然也是如此,請看下面的例子:
    Java代碼 
    public   class  BooleanTest {  
        // 布爾型值   
        boolean  bool =  true ;  
      
        // 為布爾型參數(shù)重新賦值   
        public   void  change( boolean  b) {  
            b = false ;  
        }  
      
        // 對布爾型參數(shù)進(jìn)行運算   
        public   void  calculate( boolean  b) {  
            b = b && false ;  
            // 為了方便對比,將運算結(jié)果輸出   
            System.out.println("b運算后的值:"  + b);  
        }  
      
        public   static   void  main(String[] args) {  
            BooleanTest t = new  BooleanTest();  
      
            System.out.println("參數(shù)--布爾型" );  
            System.out.println("原有的值:"  + t.bool);  
            // 為布爾型參數(shù)重新賦值   
            t.change(t.bool);  
            System.out.println("賦值之后:"  + t.bool);  
      
            // 改變布爾型參數(shù)的值   
            t.calculate(t.bool);  
            System.out.println("運算之后:"  + t.bool);  
        }  
    }  
    Java代碼
    public class BooleanTest {  
        // 布爾型值  
        boolean bool = true;  
     
        // 為布爾型參數(shù)重新賦值  
        public void change(boolean b) {  
            b = false;  
        }  
     
        // 對布爾型參數(shù)進(jìn)行運算  
        public void calculate(boolean b) {  
            b = b && false;  
            // 為了方便對比,將運算結(jié)果輸出  
            System.out.println("b運算后的值:" + b);  
        }  
     
        public static void main(String[] args) {  
            BooleanTest t = new BooleanTest();  
     
            System.out.println("參數(shù)--布爾型");  
            System.out.println("原有的值:" + t.bool);  
            // 為布爾型參數(shù)重新賦值  
            t.change(t.bool);  
            System.out.println("賦值之后:" + t.bool);  
     
            // 改變布爾型參數(shù)的值  
            t.calculate(t.bool);  
            System.out.println("運算之后:" + t.bool);  
        }  

    public class BooleanTest {
     // 布爾型值
     boolean bool = true;

     // 為布爾型參數(shù)重新賦值
     public void change(boolean b) {
      b = false;
     }

     // 對布爾型參數(shù)進(jìn)行運算
     public void calculate(boolean b) {
      b = b && false;
      // 為了方便對比,將運算結(jié)果輸出
      System.out.println("b運算后的值:" + b);
     }

     public static void main(String[] args) {
      BooleanTest t = new BooleanTest();

      System.out.println("參數(shù)--布爾型");
      System.out.println("原有的值:" + t.bool);
      // 為布爾型參數(shù)重新賦值
      t.change(t.bool);
      System.out.println("賦值之后:" + t.bool);

      // 改變布爾型參數(shù)的值
      t.calculate(t.bool);
      System.out.println("運算之后:" + t.bool);
     }
    }

    輸出結(jié)果如下:

    參數(shù)--布爾型
    原有的值:true
    賦值之后:true
    b運算后的值:false
    運算之后:true

    那么當(dāng)引用型變量被當(dāng)作參數(shù)傳遞給方法時JAVA虛擬機又是怎樣處理的呢?同樣,它會拷貝一份這個變量所持有的引用,然后把它傳遞給JAVA虛擬機為方法創(chuàng)建的局部變量,從而這兩個變量指向了同一個對象。在篇首所舉的示例中,ParamTest類型變量t和局部變量pt在JAVA虛擬機中是以如下的方式存儲的:

     

    有一種說法是當(dāng)一個對象或引用類型變量被當(dāng)作參數(shù)傳遞時,也是值傳遞,這個值就是對象的引用,因此JAVA中只有值傳遞,沒有引用傳遞。還有一種說法是引用可以看作是對象的別名,當(dāng)對象被當(dāng)作參數(shù)傳遞給方法時,傳遞的是對象的引用,因此是引用傳遞。這兩種觀點各有支持者,但是前一種觀點被絕大多數(shù)人所接受,其中有《Core Java》一書的作者,以及JAVA的創(chuàng)造者James Gosling,而《Thinking in Java》一書的作者Bruce Eckel則站在了中立的立場上。

    我個人認(rèn)為值傳遞中的值指的是基本類型的數(shù)值,即使對于布爾型,雖然它的表現(xiàn)形式為true和false,但是在棧中,它仍然是以數(shù)值形式保存的,即0表示false,其它數(shù)值表示true。而引用是我們用來操作對象的工具,它包含了對象在堆中保存地址的信息。即使在被作為參數(shù)傳遞給方法時,實際上傳遞的是它的拷貝,但那仍是引用。因此,用引用傳遞來區(qū)別與值傳遞,概念上更加清晰。

    最后我們得出如下的結(jié)論:

    基本類型和基本類型變量被當(dāng)作參數(shù)傳遞給方法時,是值傳遞。在方法實體中,無法給原變量重新賦值,也無法改變它的值。
    對象和引用型變量被當(dāng)作參數(shù)傳遞給方法時,在方法實體中,無法給原變量重新賦值,但是可以改變它所指向?qū)ο蟮膶傩浴V劣诘降姿侵祩鬟f還是引用傳遞,這并不重要,重要的是我們要清楚當(dāng)一個引用被作為參數(shù)傳遞給一個方法時,在這個方法體內(nèi)會發(fā)生什么。

    基本類型:int,float,byte,short,char,double,string,long傳值。
    其它對象類型:傳引用。
    在你的方法g里面,int num是是基本類型,傳值,ParamTest tmp 是對象,傳引用。

    posted on 2008-10-05 03:11 龔椿深 閱讀(3250) 評論(3)  編輯  收藏

    評論

    # re: java 值傳遞 引用傳遞   回復(fù)  更多評論   

    寫的很經(jīng)典,今天拜讀了,謝謝
    2009-03-10 22:25 | jackee

    # re: java 值傳遞 引用傳遞   回復(fù)  更多評論   

    很詳細(xì),很清晰~~謝謝了!
    2011-07-13 16:34 | yfx

    # re: java 值傳遞 引用傳遞 [未登錄]  回復(fù)  更多評論   

    。。。很好。。。在加一條:對象和引用型變量被當(dāng)作參數(shù)傳遞給方法時,在方法實體中,無法給原變量重新賦值,但是可以改變它所指向?qū)ο蟮膶傩浴!!!!!!!!!!!!!!!!!!!!jP(guān)鍵在于怎么改變,要調(diào)用對象或者引用變量內(nèi)部的方法去改變,才能真正的改變。。比如,用=號修改,是不能改變的,
    2012-05-20 11:59 | QQ

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 最新中文字幕免费视频| 91精品免费国产高清在线| 成人毛片18女人毛片免费96| 一区二区三区亚洲| 免费观看男人吊女人视频| 亚洲av永久无码精品漫画| 91在线免费观看| 中文亚洲AV片在线观看不卡| 一区在线免费观看| 亚洲午夜无码久久久久| 免费精品久久天干天干| 亚洲色欲色欲综合网站| av无码久久久久不卡免费网站 | 永久免费视频网站在线观看| 亚洲精品无码久久毛片波多野吉衣| 日本免费一区二区三区四区五六区 | 国产成人免费视频| 亚洲精品在线网站| 免费无码AV片在线观看软件| 日本亚洲色大成网站www久久| 日韩免费a级在线观看| 日本黄页网址在线看免费不卡| 久久亚洲中文字幕精品一区四| 美女在线视频观看影院免费天天看| 亚洲男人天堂av| 免费阿v网站在线观看g| 亚洲AV无码一区二区三区性色| 亚洲精品线路一在线观看| 91精品全国免费观看青青| 久久久久亚洲av无码专区导航 | 亚洲天堂免费在线视频| 久久夜色精品国产亚洲AV动态图 | xx视频在线永久免费观看| 亚洲欧美日韩自偷自拍| 中文字幕亚洲综合久久男男| 久久99青青精品免费观看| 亚洲熟女乱色一区二区三区| 怡红院亚洲怡红院首页| A在线观看免费网站大全| 日本永久免费a∨在线视频| 亚洲人成在线电影|