在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

Java 應用程序中的按值傳遞語義(轉)

Java 應用程序中的按值傳遞語義(轉)

更新時間:2022-04-26 文章作者:未知 信息來源:網絡 閱讀次數:

Java 應用程序中的按值傳遞語義
原文http://www.cn.ibm.com/developerWorks/java/passbyval/index.shtml

節選理解參數是按值而不是按引用傳遞的說明 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;

printf("val is %d\n", val);
printf("pint is %d\n", pint);
printf("*pint is %d\n", *pint);
printf("ref is %d\n\n", ref);

printf("calling modify\n");
//按值傳遞 val 和 pint,按引用傳遞 ref。
modify(val, pint, ref);
printf("returned from modify\n\n");

printf("val is %d\n", val);
printf("pint is %d\n", pint);
printf("*pint is %d\n", *pint);
printf("ref is %d\n", ref);

return 0;
}

void modify(int a, int *p, int &r)
{
printf("in modify...\n");
a = 0;
*p = 7;
p = 0;
r = 0;
printf("a is %d\n", a);
printf("p is %d\n", p);
printf("r is %d\n", r);
}




這段代碼的輸出為:

清單 2:C++ 代碼的輸出 val is 10
pint is 4262128
*pint is 15
ref is 50

calling modify
in modify...
a is 0
p is 0
r is 0
returned from modify

val is 10
pint is 4262128
*pint is 7
ref 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 10
sb1 is apples
sb2 is pears

calling modify
in modify...
a is 0
r1 is null
r2 is pears taste good
returned from modify

val is 10
sb1 is apples
sb2 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...");
System.out.println("a is " + a);
System.out.println("b is " + b);
}

public static void swap(Integer a, Integer b)
{
Integer temp = a;
a = b;
b = temp;
}
}



因為 Java 應用程序按值傳遞所有參數,所以這段代碼不會正常工作,其生成的輸入如下所示:

清單 8:清單 7 的輸出 before swap...
a is 10
b is 50
after swap...
a is 10
b is 50



那么,在 Java 應用程序中如何編寫一個方法來交換兩個基本類型的值或兩個對象引用的值呢?因為 Java 應用程序按值傳遞所有的參數,所以您不能這樣做。要交換值,您必須用在方法調用外部用內聯來完成。

結論
我在書中包括該信息的意圖并不是作瑣細的分析或試圖使問題復雜化,而是想警告程序員:在 Java 應用程序中假定“按引用傳遞”語義是危險的。如果您在 Java 應用程序中假定“按引用傳遞”語義,您就可能寫出類似上面的交換方法,然后疑惑它為什么不正常工作。

我必須承認,在我第一次認識到 Java 應用程序按值傳遞所有參數時,我也曾表示懷疑。我曾一直假定因為 Java 應用程序有兩種類型,所以他們按值傳遞基本類型而按引用傳遞引用,就像 C++ 那樣。在轉向 Java 編程之前我已用 C++ 編程好幾年了,感覺任何其他事情似乎都不直觀。但是,一旦我理解了發生的事情,我就相信 Java 語言按值傳遞所有參數的方法更加直觀。The Java Programming Language,Second Edition 的作者,Ken Arnold 和 James Gosling 在 2.6.1 節中說得最好:“在 Java 中只有一種參數傳遞模式 -- 按值傳遞 -- 這有助于使事情保持簡單。”

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 亚洲欧美日韩三级| 黄色手机在线视频| 国产高清www| 黄色三级中文字幕| 草草视频在线免费观看| 日本在线xxx| 女人扒开屁股爽桶30分钟| 男人天堂成人在线| 青青草久久伊人| 毛片av在线播放| 国产偷人视频免费| 91看片在线免费观看| 国产av不卡一区二区| 香港三级韩国三级日本三级| 老熟妇仑乱视频一区二区| 日本激情视频在线播放| 秋霞在线一区二区| 波多野结衣50连登视频| 色婷婷一区二区三区av免费看| 五月天综合婷婷| 北条麻妃在线视频| 久久综合亚洲精品| 粉嫩虎白女毛片人体| 波多野结衣免费观看| 久久久久久久久久久99| 亚洲涩涩在线观看| 亚洲自偷自拍熟女另类| 黄色片免费网址| 黄色大片在线免费看| 亚洲色图欧美自拍| 一女被多男玩喷潮视频| 伊人成人免费视频| 国产精品igao| 国产超级av在线| 欧美中日韩在线| 中文字幕线观看| 四虎永久在线精品无码视频| 狠狠精品干练久久久无码中文字幕| 色诱视频在线观看| 黄色激情在线视频| 深夜做爰性大片蜜桃| 日本人视频jizz页码69| 99999精品视频| 91丨porny丨探花| 日本美女爱爱视频| 免费黄频在线观看| 深夜黄色小视频| 精品日韩久久久| mm131亚洲精品| 中文字幕亚洲欧洲| 8x8x最新地址| 一级片视频免费观看| 四季av一区二区| 国产裸体免费无遮挡| 国产精品人人妻人人爽人人牛| 777久久久精品一区二区三区| 国产 欧美 日本| 男的插女的下面视频| 水蜜桃色314在线观看| 日韩亚洲欧美视频| 欧美,日韩,国产在线| 97国产在线播放| 青青在线视频免费| 伊人国产在线视频| 特级西西444www| 欧美日韩午夜爽爽| 免费成人午夜视频| 亚洲视频在线观看一区二区三区| 男人搞女人网站| www.污网站| 国产黄色激情视频| 116极品美女午夜一级| 国产精品视频分类| 中文字幕一区二区三区四| 天堂а√在线中文在线| 成熟了的熟妇毛茸茸| 亚洲天堂av线| 男人的天堂视频在线| 久久久久久久久久久福利| 亚洲 欧美 日韩系列| 青青草原国产免费| 久久亚洲中文字幕无码| 欧美国产日韩在线播放| 黄色一级片网址| 青青青在线播放| 少妇高潮大叫好爽喷水| 国产欧美在线一区| 亚洲第一页在线视频| 国产毛片视频网站| 天堂v在线视频| 国产真人无码作爱视频免费| 日韩精品第1页| 中文字幕永久视频| 少妇av一区二区三区无码| 成年网站免费在线观看| 自拍日韩亚洲一区在线| 国产三级中文字幕| 国产高潮免费视频| 国产伦精品一区二区三区四区视频_ | 一本久道综合色婷婷五月| 亚洲色图都市激情| 久热精品在线观看视频| 免费成人在线视频网站| 一本—道久久a久久精品蜜桃| 精品久久久噜噜噜噜久久图片| 国产www免费| 国产一区 在线播放| 搡的我好爽在线观看免费视频| 日韩视频免费在线播放| 3d动漫一区二区三区| 青青在线免费观看| 色哟哟免费网站| 天天干天天色天天爽| www.污污视频| 日韩av卡一卡二| xx欧美撒尿嘘撒尿xx| 嫩草影院国产精品| 中文字幕在线观看第三页| 欧美三级午夜理伦三级| 日本一本二本在线观看| 国产免费黄色av| 亚洲中文字幕无码不卡电影| www.玖玖玖| 中文字幕一区二区三区四区在线视频| 欧美一级片中文字幕| 免费激情视频在线观看| 国产一伦一伦一伦| 超碰中文字幕在线观看| 国产一二三四五| 精品成在人线av无码免费看| 97超碰人人澡| 中文字幕无码不卡免费视频| 青青青在线视频免费观看| 视频在线观看免费高清| www.成人黄色| 欧美一级视频免费看| 色综合久久久久无码专区| 92看片淫黄大片一级| 五月天av在线播放| 欧美a级黄色大片| 人人干视频在线| 孩娇小videos精品| 久久免费视频2| 欧美视频在线播放一区| 在线观看国产福利| 日韩国产一级片| 色www免费视频| 97在线国产视频| 不用播放器的免费av| 久久天天东北熟女毛茸茸| 成年人免费在线播放| 波多野结衣免费观看| 欧美日韩亚洲一| avove在线观看| 在线视频日韩一区 | 在线视频一二区| 成人免费性视频| 免费不卡av网站| 91n.com在线观看| 欧美黑人经典片免费观看| 中日韩av在线播放| 日韩欧美亚洲天堂| 亚洲国产午夜精品| 日韩欧美xxxx| 两根大肉大捧一进一出好爽视频| 奇米777在线| 亚洲精品成人在线播放| 成人黄色片视频| 波多野结衣乳巨码无在线| 老司机午夜网站| 在线观看视频黄色| 国产福利精品一区二区三区| 少妇人妻互换不带套| 日日橹狠狠爱欧美超碰| 日韩欧美不卡在线| 欧美中文字幕在线观看视频 | 91网址在线观看精品| 91小视频网站| 欧美精品一区二区三区免费播放| 免费的一级黄色片| 18视频在线观看娇喘| 日本特黄在线观看| 国产永久免费网站| 五月六月丁香婷婷| 亚洲国产欧美91| 色噜噜狠狠一区二区三区狼国成人| 人人爽人人av| caoporn超碰97| 国产精品久久久毛片| 一道本在线免费视频| 男人的天堂日韩| 能看的毛片网站| 日韩成人精品视频在线观看| 亚洲黄色av片| 乱熟女高潮一区二区在线| 久久成人福利视频| 免费观看精品视频| 污污动漫在线观看| 福利在线小视频| 狠狠97人人婷婷五月|