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

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

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

    JAVA深入探索-參數傳遞

    Posted on 2011-07-28 13:31 無很 閱讀(259) 評論(0)  編輯  收藏

    按值傳參
    JAVA中的參數傳遞只存在傳值方式一種,但也有傳引用的概念。
    這是java參數傳遞的核心說明。java不像C/C++那樣可以通過指針符或地址符來區分傳值還是傳引用,因為它只有一種參數傳遞的方式,那就是傳值方式。這對初學java的人來說很難理解,通過下面的例子可以看出真正的傳值在java中是如何實現的。
    public static void swap(int a,int b){//交換兩個變量的值
           int temp = a;
           a = b;
           b = temp;
           System.out.println("swap:"+a+","+b);
    }
    ......
        int a = 3;
    int b = 5;
       swap(a,b);
           System.out.println(a +" "+b);//3 5
    ......
    程序打印結果:
    swap:5,3
    3   5
    由程序的結果可以看到,事實上,經過交換的方法swap()之后,主程序中的變量a,b的值并沒有被改變。
    分析過程如下:在調用swap()方法的時候,程序把a、b的副本送到swap()方法中的變量a、b中去,而主程序中的變量a、b中的內容并沒有被改變。所以就會出現上面的結果。
    其實,不僅是簡單的數據類型如此 ,如果傳遞的參數是一個對象,也會出現這樣的結果,這與簡單數據類型的情況類似,都可以劃為按值傳參一類中。我們看下面的程序及其分析過程:
    public class User{
    static void swap(User user1,User user2){
           User user = user1;
           user1 = user2;
           user2 = user;
    }
    public static void main(String[]args){
           User user3 = new User("ding", 20);
           User user4 = new User("zhao", 18);
           swap(user3, user4);  
       /*進行函數swap(user1,user2)的調用,但是并不會真正把user3和user4所指向的內存空間
          *進行交換,只是在調用的時候,會把user3中存放的內存地址復制一份傳給user1,把user4中存放的
          *內存地址復制一份傳給user2,相當于只是給user1和user2了一個副本,而真正的對象
          *user3和user4并沒有在swap()函數中被觸及。所以函數處理的結果是使user1和user2所指向的內存空間
          *進行交換,而user3和user4中的存放內容仍是原來的內容。*/
           System.out.println(user3.username + "   " +user3.age);//ding   20
           System.out.println(user4.username + "   " +user4.age);//zhao   18

    程序的運行結果:
    ding   20
    zhao   18

    傳遞引用
    既然說java中的參數傳遞只有by value一種,為什么還要說傳遞引用呢?實際上,java與C++一樣,同樣存在對一個對象的引用進行傳遞的問題,但java中的引用傳遞機制是,把原來變量中保存的內存地址傳遞作為一個參數進行傳遞,而不是直接把引用傳過去。所以在java中仍把它稱做按值傳參。
    同樣采用例子的方式來解釋java中的引用傳遞的問題:
    .......
    public static   void changAge(User user){
           User temp = user;//這時,temp中存放了和原對象相同的內存地址
           temp.age = temp.age + 20;//對user的年齡進行增加的操作,
           /*是對temp所指向的內存空間中的值直接進行操作,所以會對原對象的值造成影響。就相當于是傳遞了原對象的引用*/
    }
    ......
           User user = new User("li",25);//仍采用上例中的User
           changAge(user);//改變user的年齡
           System.out.println(user.age);//45
    .......
    有了上面例子的說明,我們可能就會想到,如果我們的程序中私有變量是一個對象類型的變量時,在主程序中有了這個私有變量的拷貝,是不是就有可能在修改這個拷貝時不小心把原來的私有變量的值也給改變了呢?
    我們來看下面的例子:
    class Test{
    private Date date=new Date();
    public Date getDate(){
    return date;
    }
    public static void main(String[] args){
    Test tt=new Test();
    Date myDate=tt.getDate();//返回了一個私有變量的拷貝
    System.out.println(myDate);
    myDate.setTime(new Date().getTime()-(long)(10*365.25*24*3600*1000));//對新產生的拷貝進行修改
    System.out.println(tt.getDate());
    System.out.println(myDate);
    }
    }
    先來猜一下運行的結果,是前兩句輸出一樣呢還是后兩句輸出一樣(最后一句輸出比第一句輸出的日期早十年)?很多人都會說是前兩句輸出一樣.實際上,你會驚奇地發現,輸出結果顯示后兩者輸出一樣,私有變量在程序外部被改變了,程序的封裝性遭到了破壞。
    出錯的原因很微妙.因為myDate和tt指向了同一個對象,對myDate的引用更改方法自動地改變了這個類的私有方法狀態。經過測試可以知道,如果myDate被重新賦值(比如myDate=new Date()),就不會出現上面的結果。但是現在的這個程序,私有變量還是在程序外部被改變了。
    如果需要返回一個指向可變對象的引用,我們就需要克隆它,這樣就不會導致上面的私有變量被更改。
    上面程序就應更改為:return (Date)date.clone();就可以防止私有變量被修改的麻煩了。
    再來執行上面的程序,就會出現不一樣的結果。


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


    網站導航:
     
    主站蜘蛛池模板: 国产一级在线免费观看| 久久久久免费精品国产| 久久久精品国产亚洲成人满18免费网站 | 最近中文字幕完整免费视频ww| 亚洲男人的天堂久久精品| 国产一卡二卡≡卡四卡免费乱码| 岛国精品一区免费视频在线观看| 亚洲第一二三四区| 免费欧洲美女牲交视频| 91精品成人免费国产| 亚洲综合中文字幕无线码| 亚洲偷自拍拍综合网| 亚洲国产婷婷六月丁香| 16女性下面无遮挡免费| 男女污污污超污视频免费在线看| 日韩亚洲Av人人夜夜澡人人爽| 永久中文字幕免费视频网站| 七色永久性tv网站免费看| 亚洲精品伦理熟女国产一区二区| 亚洲无码在线播放| 在线不卡免费视频| 99久久精品免费精品国产| 国产成人不卡亚洲精品91| 亚洲精品中文字幕乱码| 亚洲乱码中文字幕手机在线| 国产高清免费视频| 三级黄色片免费看| 国产AV无码专区亚洲AV蜜芽 | 国产成人福利免费视频| 一本大道一卡二大卡三卡免费| 亚洲欧洲校园自拍都市| 国产精品亚洲成在人线| 免费无码又爽又高潮视频| 99久久国产免费-99久久国产免费| 四虎国产精品成人免费久久| 色噜噜亚洲男人的天堂| 久久久久亚洲av无码专区喷水 | 亚洲黄网站wwwwww| 亚洲精品无码久久千人斩| 免费又黄又硬又爽大片| 一本到卡二卡三卡免费高 |