最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Java零基礎(chǔ)快速入門|方法(下)

2021-02-04 09:47 作者:動(dòng)力節(jié)點(diǎn)小王本王  | 我要投稿



本篇文章主要內(nèi)容:

方法重載/overload

方法遞歸

難點(diǎn)解惑


方法重載/overload

關(guān)于方法重載是什么,以及怎么進(jìn)行重載,這些我們目前先不去研究,先來(lái)看看以下代碼不使用方法重載機(jī)制,存在哪些缺點(diǎn)?

運(yùn)行結(jié)果如下圖所示:

沒(méi)有重載,分析缺點(diǎn)

我們可以看到以上三個(gè)方法功能“相似”,都是求和,只不過(guò)參與求和的數(shù)據(jù)類型不同, 因此定義了三個(gè)方法,分別起了三個(gè)不同的方法名。這種方式會(huì)增加程序員編程的壓力,因?yàn)?程序員起碼要記憶三個(gè)方法名,另外代碼也不是很美觀。怎么解決呢?我們來(lái)看看使用方法重 載機(jī)制之后會(huì)是怎樣,請(qǐng)看以下代碼以及運(yùn)行結(jié)果:

那么,什么是方法重載呢?

方法重載(overload是指在一個(gè)類中定義多個(gè)同名的方法, 但要求每個(gè)方法具有不同的參數(shù)的類型或參數(shù)的個(gè)數(shù)。調(diào)用重載方法時(shí),Java?編譯器能通過(guò)檢查調(diào)用的方法的參數(shù)類型和個(gè)數(shù)選擇一個(gè)恰當(dāng)?shù)姆椒?。方法重載通常用于創(chuàng)建完成一組任務(wù)相似但參數(shù)的類型或參數(shù)的個(gè)數(shù)不同的方法。調(diào)用方法時(shí)通過(guò)傳遞給它們的不同個(gè)數(shù)和類型的實(shí)參來(lái)決定具體使用哪個(gè)方法。

什么情況下我們考慮使用方法重載呢?

在同一個(gè)類當(dāng)中,如果多個(gè)功能是相似的,可以考 慮將它們的方法名定義的一致,使用方法重載機(jī)制,這樣便于程序員的調(diào)用,以及代碼美觀, 但相反,如果兩個(gè)方法所完成的功能完全不同,那么方法名也一定要不一樣,這樣才是合理的。

代碼滿足什么條件的時(shí)候構(gòu)成方法重載呢?滿足以下三個(gè)條件:

  1. 在同一個(gè)類當(dāng)中。

  2. 方法名相同。

  3. 參數(shù)列表不同:個(gè)數(shù)不同算不同,順序不同算不同,類型不同也算不同。

接下來(lái)我們來(lái)看看以下程序哪些方法構(gòu)成了方法重載,哪些沒(méi)有:

哪些方法重載了,哪些沒(méi)有

編譯結(jié)果如下圖所示:

編譯錯(cuò)誤信息提示

通過(guò)觀察以上代碼以及測(cè)試結(jié)果我們得知,方法5和方法4是一樣的,這不是方法重載,?這叫“方法重復(fù)哈哈”,因?yàn)橹拔覀兙驼f(shuō)過(guò)方法形參中起決定性作用的是參數(shù)的數(shù)據(jù)類型,參數(shù)的名字隨意,因?yàn)槊恳粋€(gè)形參都是局部變量,變量名自然是隨意的。其中方法6和方1相同,顯然方法的重載和方法的返回值類型沒(méi)有關(guān)系,這也是合理的,因?yàn)橹拔覀兲徇^(guò),方法執(zhí)行結(jié)束之后的返回值我們可以接收也可以不接收。另外方法7和方法1也無(wú)法構(gòu)成重載, 顯然方法重載和修飾符無(wú)關(guān)。

總之,方法1和方法2要想構(gòu)成方法重載,首先它們?cè)谕粋€(gè)類當(dāng)中,方法名一樣,參數(shù)列表不同類型、個(gè)數(shù)、順序),這樣 java 虛擬機(jī)在運(yùn)行的時(shí)候就可以分清楚去調(diào)用哪個(gè)方法了。其實(shí),最終要調(diào)用哪個(gè)方法,還是取決于調(diào)用的時(shí)候傳遞的實(shí)際參數(shù)列表。所以在 java 編程中要區(qū)分兩個(gè)方法,首先看方法名,如果方法名一致,則繼續(xù)看它們的形式參數(shù)列表。

接下來(lái)我們來(lái)看一下方法重載在實(shí)際開發(fā)中的應(yīng)用,你有沒(méi)有覺(jué)得每一次輸出的時(shí)候“System.out.println();”這行代碼很麻煩,我們來(lái)封裝一個(gè)工具類,請(qǐng)看以下代碼:

運(yùn)行結(jié)果如下圖所示:

測(cè)試工具類U

看到以上的代碼,你是不是感覺(jué)以后要打印數(shù)據(jù)到控制臺(tái)就很方便了,代碼再也不需要寫這么多“System.out.println();”,你只需要“U.p();”,當(dāng)然,你需要把U.java 文件編譯生成的U.class?文件拷貝到你的硬盤當(dāng)中,一直攜帶著,什么時(shí)候需要的話,把U.class 文件放到classpath 當(dāng)中就可以使用了。

?

方法遞歸

什么是方法遞歸?我們先來(lái)看一段代碼:

以上代碼的執(zhí)行結(jié)果如下圖所示:

遞歸執(zhí)行結(jié)果

我們可以看到以上代碼的執(zhí)行過(guò)程中,一直輸出“m?begin”,“m?over”一次也沒(méi)有輸出, 直到最終發(fā)生了錯(cuò)誤:java.lang.StackOverflowError,這個(gè)錯(cuò)誤是棧內(nèi)存溢出錯(cuò)誤,錯(cuò)誤發(fā)生后, JVM?退出了,程序結(jié)束了。

實(shí)際上以上代碼在 m()方法執(zhí)行過(guò)程中又調(diào)用了 m()方法,方法自身調(diào)用自身,這就是方法遞歸調(diào)用。以上程序?qū)嶋H上等同于以下的偽代碼(說(shuō)明問(wèn)題,但是無(wú)法執(zhí)行的代碼):

說(shuō)明遞歸執(zhí)行原理的偽代碼

通過(guò)偽代碼我們可以看出,m()方法一直在被調(diào)用方法中的代碼必須遵循自上而下的順 序依次逐行執(zhí)行,不能跳行執(zhí)行,對(duì)于棧內(nèi)存來(lái)說(shuō)一直在進(jìn)行壓棧操作,m()方法從未結(jié)束 過(guò),所以沒(méi)有彈棧操作,即使棧內(nèi)存足夠大也是有限的內(nèi)存,總有一天棧內(nèi)存會(huì)不夠用的, 這個(gè)時(shí)候就會(huì)出現(xiàn)棧內(nèi)存溢出錯(cuò)誤。通過(guò)以上研究得出遞歸必須要有合法的結(jié)束條件,沒(méi)有結(jié) 束條件就一定會(huì)發(fā)生StackOverflowError。我們?cè)賮?lái)看看有結(jié)束條件的遞歸,例如以下代碼:

遞歸的過(guò)程中滿足了某個(gè)條件,遞歸結(jié)束了

綜上所述,遞歸其實(shí)就是方法在執(zhí)行的過(guò)程中調(diào)用了另一個(gè)方法,而另一個(gè)方法則是自己本身。在代碼角度來(lái)看就是在a()方法中調(diào)用a()方法,使用遞歸須謹(jǐn)慎,因?yàn)檫f歸在使用的時(shí)候必須有結(jié)束條件,沒(méi)有結(jié)束條件就會(huì)導(dǎo)致無(wú)終止的壓棧,棧內(nèi)存最終必然會(huì)溢出,程序因錯(cuò)誤的發(fā)生而終止。

大家再來(lái)思考一個(gè)問(wèn)題,一個(gè)遞歸程序有合法有效的結(jié)束條件就一定不會(huì)發(fā)生棧內(nèi)存溢出錯(cuò)誤嗎?在實(shí)際開發(fā)中遇到這個(gè)錯(cuò)誤應(yīng)該怎么辦?

一個(gè)遞歸程序有的時(shí)候存在合法有效的終止條件,但由于遞歸的太深,在還沒(méi)有等到條件 成立的時(shí)候,棧內(nèi)存已經(jīng)發(fā)生了溢出,這種情況也是存在的,所以實(shí)際開發(fā)中我們盡可能使用 循環(huán)來(lái)代替遞歸算法,原則是:能不用遞歸盡量不用,能用循環(huán)代替的盡可能使用循環(huán)。當(dāng)然, 如果在開發(fā)中遇到了由于使用遞歸導(dǎo)致棧內(nèi)存溢出錯(cuò)誤的發(fā)生,首先,我們要檢查遞歸的終止 條件是否合法,如果是合法的還是發(fā)生棧內(nèi)存溢出錯(cuò)誤,那么我們可以嘗試調(diào)整堆??臻g的大 小。怎么調(diào)整堆棧大小呢,大家可以研究一下下圖中的一些參數(shù),這里就不再講解內(nèi)存大小的 調(diào)整了,這不是初級(jí)程序員應(yīng)該掌握的。

java 虛擬機(jī)內(nèi)存設(shè)置參數(shù)

接下來(lái)我們來(lái)研究一下在不使用遞歸的前提下,完成 1~N 的求和,這個(gè)應(yīng)該很簡(jiǎn)單,請(qǐng)看下面代碼:

運(yùn)行結(jié)果如下圖所示:

不使用遞歸計(jì)算 1~N 的和

那么,使用遞歸應(yīng)該怎么寫呢?請(qǐng)看以下代碼:

運(yùn)行結(jié)果如下圖所示:

使用遞歸計(jì)算 1~N 的和

我們來(lái)使用偽代碼對(duì)以上代碼的執(zhí)行過(guò)程進(jìn)行分析,請(qǐng)看以下偽代碼:

?以上程序的內(nèi)存變化是這樣的,請(qǐng)看下圖:

1~N 遞歸求和內(nèi)存圖

為了加強(qiáng)大家對(duì)遞歸算法的理解,我們?cè)賮?lái)看一張圖:

另一種形式的遞歸內(nèi)存圖

其實(shí)大家把上圖逆時(shí)針旋轉(zhuǎn) 90 度,你會(huì)看到一個(gè)棧數(shù)據(jù)結(jié)構(gòu)對(duì)嗎?

?

難點(diǎn)解惑

對(duì)于本章節(jié)內(nèi)容來(lái)說(shuō),要求理解的內(nèi)容較多,其中包括兩個(gè)難點(diǎn):

  1. 方法執(zhí)行過(guò)程中內(nèi)存的變化;

  2. 遞歸算法

其實(shí)只要對(duì)方法執(zhí)行過(guò)程中內(nèi)存的變化有很深入的理解,所有方法執(zhí)行過(guò)程中內(nèi)存變化都能畫出來(lái),遞歸算法也就理解了。

對(duì)于畫內(nèi)存圖在這里囑咐大家?guī)讉€(gè)關(guān)鍵點(diǎn),以幫助你掌握方法的內(nèi)存變化以及對(duì)遞歸的理解:

  • 方法體當(dāng)中的代碼必須遵循自上而下的順序依次逐行執(zhí)行,當(dāng)前行代碼不結(jié)束,下一行代碼 是絕對(duì)不會(huì)執(zhí)行的;

  • 一定要理解棧數(shù)據(jù)結(jié)構(gòu)的原理是遵循先進(jìn)后出、后進(jìn)先出 原則,每當(dāng)方法調(diào)用時(shí)分配空間,此時(shí)“進(jìn)”棧,每當(dāng)方法執(zhí)行結(jié)束時(shí)釋放空間,此時(shí)“出” 棧。永遠(yuǎn)都是最后執(zhí)行的方法最先結(jié)束,最先執(zhí)行的方法最后結(jié)束。

小結(jié)

本章節(jié)內(nèi)容主要講解了?Java?中方法相關(guān)的語(yǔ)法機(jī)制,其實(shí)這個(gè)在?C?語(yǔ)言中被稱為函數(shù),?一般在開發(fā)中我們都會(huì)把獨(dú)立的功能單獨(dú)定義成一個(gè)方法,在需要的時(shí)候調(diào)用就行了,這樣可以讓寫過(guò)的代碼得到重復(fù)利用。

本章節(jié)中對(duì)于方法的作用是需要大家理解的,對(duì)于方法的定義與調(diào)用是需要大家必須掌握?的,另外要求大家對(duì)方法的形參和返回值存在的意義有深刻的理解。還有大家要想徹底掌握Java??程序中的方法,還需要對(duì)方法執(zhí)行過(guò)程中內(nèi)存的變化有深刻的理解。另外還要掌握方法的重載機(jī)制,以及方法的遞歸算法。尤其是遞歸時(shí)的內(nèi)存變化有助于你對(duì)遞歸執(zhí)行原理的理解。


最后附Java零基礎(chǔ)視頻教程給大家,配合學(xué)習(xí)效果更佳?。?/p>



Java零基礎(chǔ)快速入門|方法(下)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
九龙县| 汶上县| 乐安县| 南投县| 久治县| 调兵山市| 吕梁市| 卫辉市| 宁晋县| 息烽县| 易门县| 浑源县| 永善县| 腾冲县| 壤塘县| 东宁县| 新疆| 简阳市| 长汀县| 大邑县| 东乌珠穆沁旗| 固阳县| 铜鼓县| 博湖县| 江山市| 班戈县| 抚顺县| 兴仁县| 四子王旗| 河北省| 文登市| 桂林市| 镇坪县| 东辽县| 炎陵县| 雷波县| 卢氏县| 筠连县| 昌宁县| 马边| 开远市|