<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();就可以防止私有變量被修改的麻煩了。
    再來執行上面的程序,就會出現不一樣的結果。


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


    網站導航:
     
    主站蜘蛛池模板: 久久亚洲国产精品一区二区| 日本精品人妻无码免费大全 | 国产大片线上免费观看| 亚洲黄网在线观看| 91精品全国免费观看含羞草| 亚洲邪恶天堂影院在线观看| 99久久人妻精品免费二区| 亚洲精品乱码久久久久久下载| 在线观看免费精品国产| 亚洲国产精品自在自线观看| 国产在线观看免费不卡| 黄色大片免费网站| 亚洲国产一二三精品无码| 国产精品免费高清在线观看| 亚洲色图古典武侠| 全免费a级毛片免费**视频| 色妞www精品视频免费看| 丝袜熟女国偷自产中文字幕亚洲| 91在线视频免费观看| 综合自拍亚洲综合图不卡区| 久草在视频免费福利| 男男gvh肉在线观看免费| 国产精品亚洲产品一区二区三区| 久久美女网站免费| 亚洲av永久无码精品天堂久久 | 中文字幕无码成人免费视频| 国产亚洲精品成人久久网站| 亚洲色WWW成人永久网址| 91精品国产免费久久久久久青草| 亚洲风情亚Aⅴ在线发布| 亚洲色中文字幕无码AV| 黄页网站在线观看免费高清| 黄网站色成年片大免费高清| 久久亚洲精品成人| 日本一区二区三区日本免费| 免费精品久久天干天干| 中文字幕无码精品亚洲资源网久久| 亚洲成av人片在线观看天堂无码| 久久狠狠躁免费观看| 亚洲JIZZJIZZ妇女| 青青草原精品国产亚洲av|