亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java 應用程序中的按值傳遞語義以及相關評論

2019-11-18 13:12:57
字體:
來源:轉載
供稿:網友

  節選理解參數是按值而不是按引用傳遞的說明 java 應用程序有且僅有的一種參數傳遞機制,即按值傳遞。寫它是為了揭穿普遍存在的一種神話,即認為 Java 應用程序按引用傳遞參數,以避免因依靠“按引用傳遞”這一行為而導致的常見編程錯誤。
  
  對此節選的某些反饋意見認為,我把這一問題搞糊涂了,或者將它完全搞錯了。許多不同意我的讀者用 C++ 語言作為例子。因此,在此欄目中我將使用 C++ 和 Java 應用程序進一步闡明一些事實。
  
  要點
  讀完所有的評論以后,問題終于明白了,至少在一個主要問題上產生了混淆。某些評論認為我的節選是錯的,因為對象是按引用傳遞的。對象確實是按引用傳遞的;節選與這沒有沖突。節選中說所有參數都是按值 -- 另一個參數 -- 傳遞的。下面的說法是正確的:在 Java 應用程序中永遠不會傳遞對象,而只傳遞對象引用。因此是按引用傳遞對象。但重要的是要區分參數是如何傳遞的,這才是該節選的意圖。Java 應用程序按引用傳遞對象這一事實并不意味著 Java 應用程序按引用傳遞參數。參數可以是對象引用,而 Java 應用程序是按值傳遞對象引用的。
  
  C++ 和 Java 應用程序中的參數傳遞
  Java 應用程序中的變量可以為以下兩種類型之一:引用類型或基本類型。當作為參數傳遞給一個方法時,處理這兩種類型的方式是相同的。兩種類型都是按值傳遞的;沒有一種按引用傳遞。這是一個重要特性,正如隨后的代碼示例所示的那樣。
  
  在繼續討論之前,定義按值傳遞和按引用傳遞這兩個術語是重要的。按值傳遞意味著當將一個參數傳遞給一個函數時,函數接收的是原始值的一個副本。因此,假如函數修改了該參數,僅改變副本,而原始值保持不變。按引用傳遞意味著當將一個參數傳遞給一個函數時,函數接收的是原始值的內存地址,而不是值的副本。因此,假如函數修改了該參數,調用代碼中的原始值也隨之改變。
  
  關于 Java 應用程序中參數傳遞的某些混淆源于這樣一個事實:許多程序員都是從 C++ 編程轉向 Java 編程的。C++ 既包含非引用類型,又包含引用類型,并分別按值和按引用傳遞它們。Java 編程語言有基本類型和對象引用;因此,認為 Java 應用程序像 C++ 那樣對基本類型使用按值傳遞,而對引用使用按引用傳遞是符合邏輯的。究竟您會這么想,假如正在傳遞一個引用,則它一定是按引用傳遞的。很輕易就會相信這一點,實際上有一段時間我也相信是這樣,但這不正確。
  
  在 C++ 和 Java 應用程序中,當傳遞給函數的參數不是引用時,傳遞的都是該值的一個副本(按值傳遞)。區別在于引用。在 C++ 中當傳遞給函數的參數是引用時,您傳遞的就是這個引用,或者內存地址(按引用傳遞)。在 Java 應用程序中,當對象引用是傳遞給方法的一個參數時,您傳遞的是該引用的一個副本(按值傳遞),而不是引用本身。請注重,調用方法的對象引用和副本都指向同一個對象。這是一個重要區別。Java 應用程序在傳遞不同類型的參數時,其作法與 C++ 并無不同。Java 應用程序按值傳遞所有參數,這樣就制作所有參數的副本,而不管它們的類型。
  
  示例
  我們將使用前面的定義和討論分析一些示例。首先考慮一段 C++ 代碼。C++ 語言同時使用按值傳遞和按引用傳遞的參數傳遞機制:
  
  清單 1:C++ 示例
  
  #include #include void modify(int a, int *P, int &r);int main (int argc, char** argv){ int val, ref; int *pint; val = 10; ref = 50; pint = (int*)malloc(sizeof(int)); *pint = 15;   
  這段代碼的輸出為:
  
  清單 2:C++ 代碼的輸出
  
  val is 10pint is 4262128*pint is 15ref is 50calling modifyin modify...a is 0p is 0r is 0returned from modifyval is 10pint is 4262128*pint is 7ref is 0
  
  這段代碼聲明了三個變量:兩個整型變量和一個指針變量。設置了每個變量的初始值并將其打印出來。同時打印出了指針值及其所指向的值。然后將所有三個變量作為參數傳遞給 modify 函數。前兩個參數是按值傳遞的,最后一個參數是按引用傳遞的。modify 函數的函數原型表明最后一個參數要作為引用傳遞?;叵胍幌?,C++ 按值傳遞所有參數,引用除外,后者是按引用傳遞的。
  
  modify 函數更改了所有三個參數的值:
  
  將第一個參數設置為 0。
  將第二個參數所指向的值設置為 7,然后將第二個參數設置為 0。
  將第三個參數設置為 0。
  
  將新值打印出來,然后函數返回。當執行返回到 main 時,再次打印出這三個參數的值以及指針所指向的值。作為第一個和第二個參數傳遞的變量不受 modify 函數的影響,因為它們是按值傳遞的。但指針所指向的值改變了。請注重,與前兩個參數不同,作為最后一個參數傳遞的變量被 modify 函數改變了,因為它是按引用傳遞的。
  
  現在考慮用 Java 語言編寫的類似代碼:
  
  清單 3:Java 應用程序
  
  class Test{ public static void main(String args[]) { int val; StringBuffer sb1, sb2; val = 10; sb1 = new StringBuffer("apples"); sb2 = new StringBuffer("pears"); System.out.println("val is " + val); System.out.println("sb1 is " + sb1); System.out.println("sb2 is " + sb2); System.out.println(""); System.out.println("calling modify"); //按值傳遞所有參數 modify(val, sb1, sb2); System.out.println("returned from modify"); System.out.println(""); System.out.println("val is " + val); System.out.println("sb1 is " + sb1); System.out.println("sb2 is " + sb2); } public static void modify(int a, StringBuffer r1, StringBuffer r2) { System.out.println("in modify..."); a = 0; r1 = null; //1 r2.append(" taste good"); System.out.println("a is " + a); System.out.println("r1 is " + r1); System.out.println("r2 is " + r2); }}
  
  這段代碼的輸出為:
  
  清單 4:Java 應用程序的輸出
  
  val is 10sb1 is applessb2 is pearscalling modifyin modify...a is 0r1 is nullr2 is pears taste goodreturned from modifyval is 10sb1 is applessb2 is pears taste good
  
  這段代碼聲明了三個變量:一個整型變量和兩個對象引用。設置了每個變量的初始值并將它們打印出來。然后將所有三個變量作為參數傳遞給 modify 方法。
  
  modify 方法更改了所有三個參數的值:
  
  將第一個參數(整數)設置為 0。
  將第一個對象引用 r1 設置為 null。
  保留第二個引用 r2 的值,但通過調用 append 方法更改它所引用的對象(這與前面的 C++ 示例中對指針 p 的處理類似)。
  
  當執行返回到 main 時,再次打印出這三個參數的值。正如預期的那樣,整型的 val 沒有改變。對象引用 sb1 也沒有改變。假如 sb1 是按引用傳遞的,正如許多人聲稱的那樣,它將為 null。但是,因為 Java 編程語言按值傳遞所有參數,所以是將 sb1 的引用的一個副本傳遞給了 modify 方法。當 modify 方法在 //1 位置將 r1 設置為 null 時,它只是對 sb1 的引用的一個副本進行了該操作,而不是像 C++ 中那樣對原始值進行操作。
  
  另外請注重,第二個對象引用 sb2 打印出的是在 modify 方法中設置的新字符串。即使 modify 中的變量 r2 只是引用 sb2 的一個副本,但它們指向同一個對象。因此,對復制的引用所調用的方法更改的是同一個對象。
  
  編寫一個交換方法
  假定我們知道參數是如何傳遞的,在 C++ 中編寫一個交換函數可以用不同的方式完成。使用指針的交換函數類似以下代碼,其中指針是按值傳遞的:
  
  清單 5:使用指針的交換函數
  
  #include #include void swap(int *a, int *b);int main (int argc, char** argv){ int val1, val2; val1 = 10; val2 = 50; swap(&val1, &val2); return 0;}void swap(int *a, int *b){ int temp = *b; *b = *a; *a = temp;}
  
  使用引用的交換函數類似以下代碼,其中引用是按引用傳遞的:
  
  清單 6:使用引用的交換函數
  
  #include #include void swap(int &a, int &b);int main (int argc, char** argv){ int val1, val2; val1 = 10; val2 = 50; swap(val1, val2); return 0;}void swap(int &a, int &b){ int temp = b; b = a; a = temp;}
  
  兩個 C++ 代碼示例都像所希望的那樣交換了值。假如 Java 應用程序使用“按引用傳遞”,則下面的交換方法應像 C++ 示例一樣正常工作:
  
  清單 7:Java 交換函數是否像 C++ 中那樣按引用傳遞參數
  
  class Swap{ public static void main(String args[]) { Integer a, b; a = new Integer(10); b = new Integer(50); System.out.println("before swap..."); System.out.println("a is " + a); System.out.println("b is " + b); swap(a, b); System.out.println("after swap

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩禁在线播放| 91欧美精品成人综合在线观看| 欧美孕妇性xx| 亚洲久久久久久久久久久| 萌白酱国产一区二区| 亚洲国产精品久久久久秋霞蜜臀| 国产午夜精品一区二区三区| 国产亚洲欧美另类中文| www.久久色.com| 国产香蕉97碰碰久久人人| 亚洲精品成a人在线观看| 亚洲精品视频二区| www亚洲欧美| 国产香蕉精品视频一区二区三区| 人九九综合九九宗合| 中文字幕av一区二区| 97视频在线观看网址| 国产视频精品一区二区三区| 日韩在线观看免费| 国产一区二区三区三区在线观看| 欧美一二三视频| 亚洲国产成人在线播放| 国产精品18久久久久久麻辣| 亚洲精品国产福利| 久久久女人电视剧免费播放下载| 国产v综合ⅴ日韩v欧美大片| 一区二区成人精品| 日本19禁啪啪免费观看www| 欧美亚洲午夜视频在线观看| 国产精品久久久久久久久久小说| 欧美视频在线观看 亚洲欧| 国产99在线|中文| 国产精品福利在线观看网址| 国模精品视频一区二区三区| 2019中文字幕在线观看| 最近2019中文字幕一页二页| 奇门遁甲1982国语版免费观看高清| 欧美日韩国产丝袜美女| 久久久黄色av| 国产精品免费一区二区三区都可以| 欧美激情视频播放| 亚洲国语精品自产拍在线观看| 精品久久久久久久大神国产| 自拍偷拍亚洲区| 青青在线视频一区二区三区| 亚洲视频在线观看网站| 久久久综合免费视频| 91久久中文字幕| 亚洲视屏在线播放| 岛国精品视频在线播放| 欧美巨乳在线观看| 色悠悠国产精品| 亚洲最大成人在线| 欧美在线视频一区二区| 亚洲www永久成人夜色| 免费成人高清视频| 这里只有精品在线播放| 欧美激情一区二区三区在线视频观看| 国产成人中文字幕| 日韩中文字幕视频| 欧美精品www| 久久久久久久久久久成人| 欧美黄色三级网站| 色偷偷888欧美精品久久久| 欧美成人中文字幕在线| 最新国产成人av网站网址麻豆| 日韩精品高清视频| 日韩人体视频一二区| 高清一区二区三区四区五区| 国产小视频国产精品| 日韩精品极品视频| 日韩亚洲第一页| 国产精品美女av| 91高清视频在线免费观看| 亚洲三级av在线| 日本三级韩国三级久久| 久久青草福利网站| 欧美成人性色生活仑片| 欧美xxxwww| 色午夜这里只有精品| 国产视频久久久久| 日本不卡视频在线播放| 亚洲天堂开心观看| 亚洲国产成人一区| 久久久爽爽爽美女图片| 久久久精品国产| 国产成人精品一区| 这里只有精品丝袜| 国产日产久久高清欧美一区| 另类专区欧美制服同性| 38少妇精品导航| 日韩一级黄色av| 亚洲精品之草原avav久久| 在线日韩中文字幕| 欧美成人免费全部观看天天性色| 国产97在线视频| 国产精品久久久久久网站| 2018国产精品视频| 秋霞成人午夜鲁丝一区二区三区| 国产精品情侣自拍| 欧美亚洲国产视频小说| 精品网站999www| 亚洲开心激情网| 日韩电影中文字幕| 久久九九国产精品怡红院| 欧美精品xxx| 欧美性受xxx| 国产精品高潮呻吟久久av无限| 91精品久久久久久久久久久| 精品久久久久久久久久ntr影视| 成人欧美一区二区三区在线湿哒哒| 91免费国产网站| 在线视频欧美日韩精品| 欧美日韩在线视频一区二区| 九九热精品视频在线播放| 亚洲第一精品电影| 国产99久久精品一区二区永久免费| 国产精品午夜国产小视频| 日韩在线视频线视频免费网站| 亚洲一级黄色av| 欧洲成人性视频| 欧美激情视频免费观看| 欧美国产日韩一区二区三区| 国产不卡精品视男人的天堂| 欧美大学生性色视频| 精品亚洲一区二区三区| 亚洲第一网中文字幕| 精品偷拍各种wc美女嘘嘘| 国内免费久久久久久久久久久| 日韩精品免费在线视频观看| 日本久久久久久久| 欧美成人网在线| 亚洲国产精品va在线| 日韩欧美亚洲成人| 午夜精品一区二区三区在线视频| 欧美男插女视频| 亚洲男人天堂视频| 久久久91精品| 亚洲精品国产精品乱码不99按摩| 97成人精品视频在线观看| 欧美精品久久久久久久| 亚洲精品影视在线观看| 亚洲美女视频网站| 欧美精品激情在线观看| 亚洲天堂2020| 亚洲网址你懂得| 欧美www视频在线观看| 久久综合久中文字幕青草| 亚洲国产精品一区二区三区| 中日韩美女免费视频网站在线观看| 中文字幕免费精品一区| 国产视频观看一区| 综合网中文字幕| 97成人精品区在线播放| 在线视频亚洲欧美| 在线免费看av不卡| 国产一区二区三区在线观看网站| 国产裸体写真av一区二区| www.日韩欧美| 久久国产色av| 久久影视电视剧凤归四时歌| 国产精品日韩久久久久| 中文字幕视频在线免费欧美日韩综合在线看| 欧美精品18videosex性欧美|