日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

$emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?...

發(fā)布時(shí)間:2023/12/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 $emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

方法參數(shù)

首先回顧一下在程序設(shè)計(jì)語(yǔ)言中有關(guān)參數(shù)傳遞給方法(或函數(shù))的一些專(zhuān)業(yè)術(shù)語(yǔ)。值調(diào)用(call by value)表示方法接收的是調(diào)用者提供的值。而引用調(diào)用(call by reference)表示方法接收的是調(diào)用者提供的變量位置。可以想到,一個(gè)方法可以修改傳遞引用所對(duì)應(yīng)的變量值,而不能修改傳遞值調(diào)用所對(duì)應(yīng)的變量值。這一點(diǎn)不僅僅是Java 語(yǔ)言,其他程序設(shè)計(jì)語(yǔ)言也是如此。“……調(diào)用”(call by)是一個(gè)標(biāo)準(zhǔn)的計(jì)算機(jī)科學(xué)術(shù)語(yǔ),它用來(lái)描述各個(gè)程序設(shè)計(jì)語(yǔ)言中方法參數(shù)的傳遞方式。(事實(shí)上,以前還有名稱(chēng)調(diào)用(call by name),Algol程序設(shè)計(jì)語(yǔ)言—最古老的高級(jí)程序設(shè)計(jì)語(yǔ)言之一—使用的就是這種參數(shù)傳遞方式。不過(guò),對(duì)于今天來(lái)說(shuō),這種傳遞方式已經(jīng)成為歷史。)Java程序設(shè)計(jì)語(yǔ)言使用值調(diào)用。也就是說(shuō),方法得到的是所有參數(shù)值的一個(gè)拷貝,特別是,方法不能修改傳遞給它的任何參數(shù)變量的內(nèi)容。

例如,考慮下面的調(diào)用:

double percent = 10;

harry.raiseSalary(percent);

不必理睬這個(gè)方法的具體實(shí)現(xiàn),在方法調(diào)用之后,percent的值還是10。

下面再仔細(xì)地研究一下這種情況。假定一個(gè)方法試圖將一個(gè)參數(shù)值增加至3倍:

public static void tripleValue(double x) // doesn’t work{x = 3 * x;}然后調(diào)用這個(gè)方法:double percent = 10;tripleValue(percent);

可以看到,無(wú)論怎樣調(diào)用這個(gè)方法,執(zhí)行之后,percent的值還是10。下面看一下具體的執(zhí)行

過(guò)程:

1)x被初始化為percent值的一個(gè)拷貝(也就是10)。

2)x被乘以3后等于30。但是percent仍然是10(如圖4-6所示)。

3)這個(gè)方法結(jié)束之后,參數(shù)變量x不再使用。

然而,方法參數(shù)共有兩種類(lèi)型:

? 基本數(shù)據(jù)類(lèi)型(數(shù)字、布爾值)。

? 對(duì)象引用。

已經(jīng)看到,一個(gè)方法不可能修改一個(gè)基本數(shù)據(jù)類(lèi)型的參數(shù)。而對(duì)象引用作為參數(shù)就不同了,

我們可以很容易地利用下面這個(gè)方法實(shí)現(xiàn)將一個(gè)雇員的薪金提高兩倍的操作:

public static void tripleSalary(Employee x) // works{x.raiseSalary(200);}當(dāng)調(diào)用harry = new Employee(. . .);tripleSalary(harry);

具體的執(zhí)行過(guò)程為:

1)x被初始化為harry值的拷貝,這里是一個(gè)對(duì)象的引用。

2)raiseSalary方法應(yīng)用于這個(gè)對(duì)象引用。x和harry同時(shí)引用的那個(gè)Employee對(duì)象的薪金提高了200%。

3)方法結(jié)束后,參數(shù)變量x不再使用。當(dāng)然,對(duì)象變量harry繼續(xù)引用那個(gè)薪金增至3倍的雇員對(duì)象(如圖4-7所示)。

已經(jīng)看到,實(shí)現(xiàn)一個(gè)改變對(duì)象參數(shù)狀態(tài)的方法并不是一件難事。理由很簡(jiǎn)單,方法得到的是對(duì)象引用的拷貝,對(duì)象引用及其他的拷貝同時(shí)引用同一個(gè)對(duì)象。

很多程序設(shè)計(jì)語(yǔ)言(特別是,C++和Pascal)提供了兩種參數(shù)傳遞的方式:值調(diào)用和引用調(diào)用。有些程序員認(rèn)為Java 程序設(shè)計(jì)語(yǔ)言對(duì)對(duì)象采用的是引用調(diào)用,實(shí)際上,這種理解是不對(duì)的。

由于這種誤解具有一定的普遍性,所以下面給出一個(gè)反例,來(lái)詳細(xì)地闡述一下這個(gè)問(wèn)題。

首先,編寫(xiě)一個(gè)交換兩個(gè)雇員對(duì)象的方法:

public static void swap(Employee x, Employee y) // doesn't work{Employee temp = x;x = y;y = temp;}

如果Java程序設(shè)計(jì)語(yǔ)言對(duì)對(duì)象采用的是引用調(diào)用的話,這個(gè)方法應(yīng)該能夠?qū)崿F(xiàn)交換數(shù)據(jù)的效果:

Employee a = new Employee("Alice", . . .);

Employee b = new Employee("Bob", . . .);

swap(a, b);

// does a now refer to Bob, b to Alice?

但是,方法并沒(méi)有改變存儲(chǔ)在變量a和b中的對(duì)象引用。swap方法的參數(shù)x和y被初始化為兩個(gè)對(duì)象引用的拷貝,這個(gè)方法交換的是這兩個(gè)拷貝。

// x refers to Alice, y to Bob

Employee temp = x;

x = y;

y = temp;

// now x refers to Bob, y to Alice

最終,白費(fèi)力氣。在方法結(jié)束時(shí)參數(shù)變量x和y被丟棄了。原來(lái)的變量a和b仍然引用這個(gè)方法調(diào)用之前所引用的對(duì)象(如圖4-8所示)。

這個(gè)過(guò)程說(shuō)明:Java 程序設(shè)計(jì)語(yǔ)言對(duì)對(duì)象采用的不是引用調(diào)用,實(shí)際上,對(duì)象引用進(jìn)行的是值傳遞。

下面總結(jié)一下在Java程序設(shè)計(jì)語(yǔ)言中,方法參數(shù)的使用情況:

? 一個(gè)方法不能修改一個(gè)基本數(shù)據(jù)類(lèi)型的參數(shù)(即數(shù)值型和布爾型值)。

? 一個(gè)方法可以改變一個(gè)對(duì)象參數(shù)的狀態(tài)。

? 一個(gè)方法不能讓對(duì)象參數(shù)引用一個(gè)新的對(duì)象。

例4-4中的程序給出了相應(yīng)的演示。在這個(gè)程序中,首先試圖將一個(gè)值參數(shù)的值提高兩倍,但沒(méi)有成功:

Testing tripleValue:

Before: percent=10.0

End of method: x=30.0

After: percent=10.0

隨后,成功地將一個(gè)雇員的薪金提高了兩倍:

Testing tripleSalary:

Before: salary=50000.0

End of method: salary=150000.0

After: salary=150000.0

方法結(jié)束之后,harry引用的對(duì)象狀態(tài)發(fā)生了改變。這是因?yàn)檫@個(gè)方法可以通過(guò)對(duì)象引用的拷貝修改所引用的對(duì)象狀態(tài)。

最后,程序演示了swap方法的失敗效果:

Testing swap:

Before: a=Alice

Before: b=Bob

End of method: x=Bob

End of method: y=Alice

After: a=Alice

After: b=Bob

可以看出,參數(shù)變量x和y被交換了,但是變量a和b沒(méi)有受到影響。

例4-4 ParamTest.java

對(duì)象構(gòu)造

前面已經(jīng)學(xué)會(huì)了編寫(xiě)簡(jiǎn)單的構(gòu)造器,以便對(duì)定義的對(duì)象進(jìn)行初始化。但是,由于對(duì)象構(gòu)造非常重要,所以Java提供了多種機(jī)制來(lái)編寫(xiě)構(gòu)造器。下面將介紹這些內(nèi)容。

重載

從前面可以看到,GregorianCalendar類(lèi)有多個(gè)構(gòu)造器。我們可以使用:

GregorianCalendar today = new GregorianCalendar( );

或者

GregorianCalendar deadline = new GregorianCalendar(2099, Calendar.DECEMBER, 31);

這種能力叫做重載(overloading)。如果多個(gè)方法(比如,GregorianCalendar構(gòu)造器方法)有相同的名字、不同的參數(shù),便產(chǎn)生了重載。編譯器必須挑選出具體執(zhí)行哪個(gè)方法,它通過(guò)用各個(gè)方法給出的參數(shù)類(lèi)型與特定方法調(diào)用所使用的值類(lèi)型進(jìn)行匹配來(lái)挑選出正確的方法。如果編譯器找不到匹配的參數(shù),或者找出多個(gè)可能的匹配,就會(huì)產(chǎn)生編譯時(shí)錯(cuò)誤(這個(gè)過(guò)程被稱(chēng)為重載解析(overloading resolution)。)

默認(rèn)域初始化

如果在構(gòu)造器中沒(méi)有顯式地給域賦予初值,它就會(huì)被自動(dòng)地賦為默認(rèn)值:數(shù)值為0、布爾值為flase、對(duì)象引用為null。然而,只有缺少程序設(shè)計(jì)經(jīng)驗(yàn)的人才會(huì)這樣做。確實(shí),如果不明確地對(duì)域進(jìn)行初始化,就會(huì)影響程序代碼的可讀性。

默認(rèn)構(gòu)造器

所謂默認(rèn)構(gòu)造器是指沒(méi)有參數(shù)的構(gòu)造器。例如,Employee類(lèi)的默認(rèn)構(gòu)造器:

public Employee( ){name = "";salary = 0;hireDay = new Date( );}

如果在編寫(xiě)一個(gè)類(lèi)時(shí)沒(méi)有編寫(xiě)構(gòu)造器,系統(tǒng)就會(huì)提供一個(gè)默認(rèn)構(gòu)造器。這個(gè)默認(rèn)構(gòu)造器將所有的實(shí)例域設(shè)置為默認(rèn)值。于是,實(shí)例域中的數(shù)值型數(shù)據(jù)設(shè)置為0、布爾型數(shù)據(jù)設(shè)置為false、所有對(duì)象變量將設(shè)置為null。

如果類(lèi)中提供了至少一個(gè)構(gòu)造器,但是沒(méi)有提供默認(rèn)的構(gòu)造器,那么在構(gòu)造對(duì)象時(shí)若不提供構(gòu)造參數(shù)就被視為不合法。例如,在例4-2中的Employee類(lèi)提供了一個(gè)簡(jiǎn)單的構(gòu)造器:

Employee(String name, double salary, int y, int m, int d)

對(duì)于這個(gè)類(lèi),構(gòu)造默認(rèn)的雇員屬于不合法。也就是,調(diào)用

e = new Employee( );

將會(huì)產(chǎn)生錯(cuò)誤。

顯式域初始化

由于類(lèi)的構(gòu)造器方法可以重載,所以可以采用多種形式設(shè)置類(lèi)的實(shí)例域的初始狀態(tài)。確保不管怎樣調(diào)用構(gòu)造器,每個(gè)實(shí)例域都可以被設(shè)置為一個(gè)有意義的初值。這是一種很好的設(shè)想。

可以在類(lèi)的定義中,簡(jiǎn)單地將一個(gè)值賦給任何域。例如:

在執(zhí)行構(gòu)造器之前,先執(zhí)行賦值。當(dāng)一個(gè)類(lèi)的所有構(gòu)造器都希望將相同的值賦予某個(gè)特定的實(shí)例域時(shí),這種方式特別有用。

初始值不一定是常量。在下面的例子中,域可以調(diào)用方法來(lái)進(jìn)行初始化。仔細(xì)看一下Employee類(lèi),其中每個(gè)雇員有一個(gè)id域。可以使用下列方式進(jìn)行初始化:

參數(shù)名

在編寫(xiě)很小的構(gòu)造器時(shí)(這是十分常見(jiàn)的),常常在參數(shù)命名上出現(xiàn)錯(cuò)誤。

通常,參數(shù)用單個(gè)字符命名:

然而,這樣做有一個(gè)缺陷:只有閱讀代碼才能夠了解參數(shù)n和參數(shù)s的含義。

于是,有些程序員在每個(gè)參數(shù)前面加上一個(gè)前綴“a”:

這樣很清晰。每一個(gè)讀者一眼就能夠看懂參數(shù)的含義。

還一種常用的技巧,它基于這樣的事實(shí):參數(shù)變量用同樣的名字將實(shí)例域屏蔽起來(lái)。例如,如果將參數(shù)命名為salary,那么salary將引用這個(gè)參數(shù),而不是實(shí)例域。但是,可以采用this.salary的形式訪問(wèn)實(shí)例域。回想一下,this指示隱式參數(shù),也就是被構(gòu)造的對(duì)象。下面是一個(gè)例子:

調(diào)用另一個(gè)構(gòu)造器

關(guān)鍵字this引用方法的隱式參數(shù)。然而,這個(gè)關(guān)鍵字還有另外一個(gè)含義。

如果構(gòu)造器的第一個(gè)語(yǔ)句形如this(...),那么這個(gè)構(gòu)造器將調(diào)用同一個(gè)類(lèi)的另一個(gè)構(gòu)造器。下面是一個(gè)典型的例子:

當(dāng)調(diào)用new Employee(60000) 時(shí),Employee(double) 構(gòu)造器將調(diào)用Employee(String, double) 構(gòu)造器。

采用這種方式使用this關(guān)鍵字非常有用,這樣對(duì)公共的構(gòu)造器代碼部分只編寫(xiě)一次即可。

初始化塊

前面已經(jīng)講過(guò)兩種初始化數(shù)據(jù)域的方法:

? 在構(gòu)造器中設(shè)置值

? 在聲明中賦值

實(shí)際上,Java還有第三種機(jī)制,稱(chēng)為初始化塊。在一個(gè)類(lèi)的聲明中,可以包含多個(gè)代碼塊。

只要構(gòu)造類(lèi)的對(duì)象,這些塊就會(huì)被執(zhí)行。例如,

在這個(gè)例子中,無(wú)論使用哪個(gè)構(gòu)造器構(gòu)造對(duì)象,id域都在對(duì)象初始化塊中被初始化。首先運(yùn)行初始化塊,然后才運(yùn)行構(gòu)造器的主體部分。

這種機(jī)制不是必須的,也不常見(jiàn)。通常,直接將初始化代碼放置在一個(gè)構(gòu)造器的內(nèi)部。

由于初始化數(shù)據(jù)域有多種途徑,所以列出構(gòu)造過(guò)程的所有路徑可能相當(dāng)混亂。下面是調(diào)用構(gòu)造器的具體處理步驟:

1)所有數(shù)據(jù)域被初始化為默認(rèn)值(0、false或null)。

2)按照在類(lèi)聲明中出現(xiàn)的次序依次執(zhí)行所有域初始化語(yǔ)句和初始化塊。

3)如果構(gòu)造器第一行調(diào)用了第二個(gè)構(gòu)造器,則執(zhí)行第二個(gè)構(gòu)造器主體。

4)執(zhí)行這個(gè)構(gòu)造器的主體。

當(dāng)然,應(yīng)該精心地組織好初始化代碼,這樣有利于其他程序員的理解。例如,如果讓類(lèi)的構(gòu)造器行為依賴于數(shù)據(jù)域聲明的順序,就會(huì)顯得很奇怪并且容易引起錯(cuò)誤。

可以通過(guò)提供一個(gè)初始化值,或者使用一個(gè)靜態(tài)的初始化塊來(lái)對(duì)靜態(tài)域進(jìn)行初始化。前面已經(jīng)介紹過(guò)第一種機(jī)制:

static int nextId = 1;

如果對(duì)類(lèi)的靜態(tài)域進(jìn)行初始化的代碼比較復(fù)雜,就可以使用靜態(tài)的初始化塊。

將代碼放置在一個(gè)塊中,并標(biāo)記關(guān)鍵字static。下面是一個(gè)例子。其功能是將雇員ID的起始值賦予一個(gè)小于10 000的隨機(jī)整數(shù)。

在類(lèi)第一次加載的時(shí)候,將會(huì)進(jìn)行靜態(tài)域的初始化。與實(shí)例域一樣,靜態(tài)域的默認(rèn)初值是 0、false或null,除非將它們顯式設(shè)置成其他值。所有的靜態(tài)初始化語(yǔ)句以及靜態(tài)初始化塊都將按照類(lèi)定義中出現(xiàn)的順序執(zhí)行。

例4-5 ConstructorTest.java

java.util.Random 1.0

? Random( )

構(gòu)造一個(gè)新的隨機(jī)數(shù)生成器。

? int nextInt(int n) 1.2

返回一個(gè)0~n-1之間的隨機(jī)數(shù)。

對(duì)象析構(gòu)與finalize方法

有些面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言,特別是C++,有顯式的析構(gòu)器方法,其中放置一些當(dāng)對(duì)象不再使用時(shí)所需要用到的清理代碼。在析構(gòu)器中,最常見(jiàn)的操作是回收分配給對(duì)象的存儲(chǔ)空間。

由于Java有自動(dòng)的垃圾回收器,不需要人工回收內(nèi)存,所以Java不支持析構(gòu)器。

當(dāng)然,某些對(duì)象使用了內(nèi)存之外的其他資源,如文件或使用了系統(tǒng)資源的另一個(gè)對(duì)象的句柄。在這種情況下,當(dāng)資源不再需要的時(shí)候,將其回收和再利用十分重要。

可以為任何一個(gè)類(lèi)添加finalize方法。finalize方法將在垃圾回收器清除對(duì)象之前被調(diào)用。在實(shí)際應(yīng)用中,不要使用finalize方法回收任何短缺的資源,這是因?yàn)楹茈y知道這個(gè)方法什么時(shí)候才能夠被調(diào)用。

覺(jué)得有收貨的話,可以轉(zhuǎn)發(fā)關(guān)注小編,之后持續(xù)更新技術(shù)干貨!!!!!

總結(jié)

以上是生活随笔為你收集整理的$emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。