




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
授課:李遠(yuǎn)輝Java對象及其引用
湖南工程學(xué)院計算機(jī)與通信學(xué)院湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程簡單類型是按值傳遞的packagecom.lyh.test;public
classTest{public
static
voidtest(booleantest){test=!test;System.out.println("Intest(boolean):test="+test);}public
static
voidmain(String[]args){booleantest=true;System.out.println("Beforetest(boolean):test="+test);test(test);System.out.println("Aftertest(boolean):test="+test);}}湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程Java方法的參數(shù)是簡單類型的時候,是按值傳遞的(passbyvalue)運(yùn)行結(jié)果:
Beforetest(boolean):test=true
Intest(boolean):test=false
Aftertest(boolean):test=true
不難看出,雖然在test(boolean)方法中改變了傳進(jìn)來的參數(shù)的值,但對這個參數(shù)源變量本身并沒有影響,即對main(String[])方法里的test變量沒有影響。那說明,參數(shù)類型是簡單類型的時候,是按值傳遞的。以參數(shù)形式傳遞簡單類型的變量時,實(shí)際上是將參數(shù)的值作了一個拷貝傳進(jìn)方法函數(shù)的,那么在方法函數(shù)里再怎么改變其值,其結(jié)果都是只改變了拷貝的值,而不是源值。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程什么是引用Java是傳值還是傳引用,問題主要出在對象的傳遞上,因?yàn)镴ava中簡單類型沒有引用。既然爭論中提到了引用這個東西,為了搞清楚這個問題,我們必須要知道引用是什么。
簡單的說,引用其實(shí)就像是一個對象的名字或者別名(alias),一個對象在內(nèi)存中會請求一塊空間來保存數(shù)據(jù),根據(jù)對象的大小,它可能需要占用的空間大小也不等。訪問對象的時候,我們不會直接是訪問對象在內(nèi)存中的數(shù)據(jù),而是通過引用去訪問。引用也是一種數(shù)據(jù)類型,我們可以把它想象為類似C語言中指針的東西,它指示了對象在內(nèi)存中的地址??只不過我們不能夠觀察到這個地址究竟是什么。
如果我們定義了不止一個引用指向同一個對象,那么這些引用是不相同的,因?yàn)橐靡彩且环N數(shù)據(jù)類型,需要一定的內(nèi)存空間來保存。但是它們的值是相同的,都指示同一個對象在內(nèi)存的中位置。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程對象創(chuàng)建過程newBook()對象book引用變量內(nèi)存狀態(tài)datasegcodesegstackheapid:0name:nullcategory:nullbook:XXXBook湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程比如
Stringa="Hello";
Stringb=a;
這里,a和b是不同的兩個引用,我們使用了兩個定義語句來定義它們。但它們的值是一樣的,都指向同一個對象"Hello"。也許你還覺得不夠直觀,因?yàn)镾tring對象的值本身是不可更改的(像b="World";b=a;這種情況不是改變了"World"這一對象的值,而是改變了它的引用b的值使之指向了另一個String對象a)。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程那么我們用StringBuffer來舉一個例子:
publicclassTest{
publicstaticvoidmain(String[]args){
StringBuffera=newStringBuffer("Hello");
StringBufferb=a;
b.append(",World");
System.out.println("ais"+a);
}
}
運(yùn)行結(jié)果:
aisHello,World
這個例子中a和b都是引用,當(dāng)改變了b指示的對象的值的時候,從輸出結(jié)果來看,a所指示的對象的值也改變了。所以,a和b都指向同一個對象即包含"Hello"的一個StringBuffer對象。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程這里我描述了兩個要點(diǎn):
1.引用是一種數(shù)據(jù)類型,保存了對象在內(nèi)存中的地址,這種類型即不是我們平時所說的簡單數(shù)據(jù)類型也不是類實(shí)例(對象);
2.不同的引用可能指向同一個對象,換句話說,一個對象可以有多個引用,即該類類型的變量。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程對象是如何傳遞的呢湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程關(guān)于對象的傳遞,有兩種說法,即“它是按值傳遞的”和“它是按引用傳遞的”。這兩種說法各有各的道理,但是它們都沒有從本質(zhì)上去分析,即致于產(chǎn)生了爭論。既然現(xiàn)在我們已經(jīng)知道了引用是什么東西,那么現(xiàn)在不妨來分析一下對象作是參數(shù)是如何傳遞的。還是先以一個程序?yàn)槔?/p>
publicclassTest{
publicstaticvoidtest(StringBufferstr){
str.append(",World!");
}
publicstaticvoidmain(String[]args){
StringBufferstring=newStringBuffer("Hello");
test(string);
System.out.println(string);
}
}
運(yùn)行結(jié)果:
Hello,World!湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程運(yùn)行結(jié)果:
Hello,World!
test(string)調(diào)用了test(StringBuffer)方法,并將string作為參數(shù)傳遞了進(jìn)去。這里string是一個引用,這一點(diǎn)是勿庸置疑的。前面提到,引用是一種數(shù)據(jù)類型,而且不是對象,所以它不可能按引用傳遞,所以它是按值傳遞的,它么它的值究竟是什么呢?是對象的地址。
由此可見,對象作為參數(shù)的時候是按值傳遞的,對嗎?錯!為什么錯,讓我們看另一個例子:湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程由此可見,對象作為參數(shù)的時候是按值傳遞的,對嗎?錯!為什么錯,讓我們看另一個例子:
publicclassTest{
publicstaticvoidtest(Stringstr){
str="World";
}
publicstaticvoidmain(String[]args){
Stringstring="Hello";
test(string);
System.out.println(string);
}
}
運(yùn)行結(jié)果:
Hello湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程為什么會這樣呢?因?yàn)閰?shù)str是一個引用,而且它與string是不同的引用,雖然它們都是同一個對象的引用。str="World"則改變了str的值,使之指向了另一個對象,然而str指向的對象改變了,但它并沒有對"Hello"造成任何影響,而且由于string和str是不同的引用,str的改變也沒有對string造成任何影響,結(jié)果就如例中所示。
其結(jié)果是推翻了參數(shù)按值傳遞的說法。那么,對象作為參數(shù)的時候是按引用傳遞的了?也錯!因?yàn)樯弦粋€例子的確能夠說明它是按值傳遞的。
結(jié)果,就像光到底是波還是粒子的問題一樣,Java方法的參數(shù)是按什么傳遞的問題,其答案就只能是:即是按值傳遞也是按引用傳遞,只是參照物不同,結(jié)果也就不同。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程實(shí)際上,問題來源于C,而不是Java。
C語言中有一種數(shù)據(jù)類型叫做指針,于是將一個數(shù)據(jù)作為參數(shù)傳遞給某個函數(shù)的時候,就有兩種方式:傳值,或是傳指針,它們的區(qū)別,可以用一個簡單的例子說明:/*例5*/
voidSwapValue(inta,intb){intt=a;a=b;b=t;}
voidSwapPointer(int*a,int*b){intt=*a;*a=*b;*b=t;}
voidmain(){
inta=0,b=1;printf("1:a=%d,b=%dn",a,b);SwapValue(a,b);
printf("2:a=%d,b=%dn",a,b);SwapPointer(&a,&b);
printf("3:a=%d,b=%dn",a,b);}
運(yùn)行結(jié)果:1:a=0,b=12:a=0,b=13:a=1,b=0湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程大家可以明顯的看到,按指針傳遞參數(shù)可以方便的修改通過參數(shù)傳遞進(jìn)來的值,而按值傳遞就不行。
當(dāng)Java成長起來的時候,許多的C程序員開始轉(zhuǎn)向?qū)W習(xí)Java,他們發(fā)現(xiàn),使用類似SwapValue的方法仍然不能改變通過參數(shù)傳遞進(jìn)來的簡單數(shù)據(jù)類型的值,但是如果是一個對象,則可能將其成員隨意更改。于是他們覺得這很像是C語言中傳值/傳指針的問題。但是Java中沒有指針,那么這個問題就演變成了傳值/傳引用的問題??上⑦@個問題放在Java中進(jìn)行討論并不恰當(dāng)。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程討論這樣一個問題的最終目的只是為了搞清楚何種情況才能在方法函數(shù)中方便的更改參數(shù)的值并使之長期有效。Java中,改變參數(shù)的值有兩種情況,第一種,使用賦值號“=”直接進(jìn)行賦值使其改變,如例1和例4;第二種,對于某些對象的引用,通過一定途徑對其成員數(shù)據(jù)進(jìn)行改變,如例3。對于第一種情況,其改變不會影響到方法該方法以外的數(shù)據(jù),或者直接說源數(shù)據(jù)。而第二種方法,則相反,會影響到源數(shù)據(jù)??因?yàn)橐弥甘镜膶ο鬀]有變,對其成員數(shù)據(jù)進(jìn)行改變則實(shí)質(zhì)上是改變的該對象。湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程如何實(shí)現(xiàn)類似swap的方法湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程傳值還是傳引用的問題,到此已經(jīng)算是解決了,但是我們?nèi)匀徊荒芙鉀Q這樣一個問題:如果我有兩個int型的變量a和b,我想寫一個方法來交換它們的值,應(yīng)該怎么辦?
結(jié)論很讓人失望??沒有辦法!因此,我們只能具體情況具體討論,以經(jīng)常使用交換方法的排序?yàn)槔汉瞎こ虒W(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程結(jié)論很讓人失望??沒有辦法!因此,我們只能具體情況具體討論,以經(jīng)常使用交換方法的排序?yàn)槔?/p>
publicclassTest{
publicstaticvoidswap(int[]data,inta,intb){
intt=data[a];data[a]=data;data=t;
}
湖南工程學(xué)院計算機(jī)與通信學(xué)院授課:李遠(yuǎn)輝Java編程技術(shù)教程publicstaticvoidmain(String[]args){
int[]data=newint[10];
for(inti=0;i<10;i++){
data=(int)(Math.random()*100);
System.out.print(""+data);}
System.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 出國建筑合同范本
- 健身車外貿(mào)合同范本
- 代建租賃合同范本
- 凍庫驗(yàn)收合同范本
- ipad制作合同范本
- 長寧區(qū)制作家具施工方案
- 使用保姆合同范本
- ppp 外貿(mào)合同范本
- 公寓租給酒店合同范本
- 仿古街建設(shè)合同范本
- 2024年山東理工職業(yè)學(xué)院高職單招語文歷年參考題庫含答案解析
- 三叉神經(jīng)痛的護(hù)理問題
- 2025北京平谷初三(上)期末數(shù)學(xué)真題試卷(含答案解析)
- VQ-100無人機(jī)手冊(一)
- 2024年01月河北2024滄州銀行總行科技開發(fā)部招考筆試歷年參考題庫附帶答案詳解
- 2024-2030年中國橡膠密封件行業(yè)運(yùn)行動態(tài)及發(fā)展前景規(guī)劃研究報告
- 八省八校2025屆高三上學(xué)期12月聯(lián)合測評語文試題及參考答案
- 現(xiàn)代物流基礎(chǔ)習(xí)題+參考答案
- 商洛職業(yè)技術(shù)學(xué)院《會計信息系統(tǒng)單統(tǒng)計學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 生產(chǎn)線搬新場地驗(yàn)證方案計劃
- 《古詩三首》五年級下冊第一單元教學(xué)方案
評論
0/150
提交評論