Java方法
- ??前言
- 一,方法的基本用法
- 方法的定義規則
- 方法的執行程序
- Java理解方法(函式)堆疊幀
- 實參和形參的關系
- 二,方法的多載
- 使用多載的目的
- 多載的規則
- 三,遞回
- 遞回公式解決問題
- 遞回分析程序
- 代碼遞回路線圖
- 形象分析圖
- 遞回練習
- ?總結
??前言
哈嘍大家好,我是Aaron,本文帶來在Java中方法的使用以及方法涉及知識點的分享,覺得對各位有幫助的可以給出三連支持哦~
👍點贊👍 + 👀關注👀 + 🤏收藏🤏

正文開始
一,方法的基本用法
對于初學者來說,方法的概念是第一次聽說,但其實他就類似于C語言中的函式,是一個可以多次使用,并且完成單一功能的代碼塊,
那么,為什么要引入方法的概念呢?
我們可以想一個問題,如果沒有方法的概念,那就意味著一個工程所有的功能實作代碼全部要寫在main函式里,那將會使代碼變得非常不具可閱讀性,并且難以維護,如果盲目修改代碼中的某一處,很有可能使程式多出無數個bug,所以,引入方法的概念是必不可少的~
如果使用方法去完成每一個單獨的功能,則將便于我們對程式進行維護,如果某一個功能出現bug,只需要在完成其功能的方法進行修改,而不會影響到其他方法和main方法的實作邏輯,
舉一個例子演示使用方法進行編程的好處:
例如,編程實作1!~ 5!求和,
如果用普通方法實作,需要使用到回圈嵌套:
public class Method {
/**
* 求1! ~ 5!的求和
* @param args
*/
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 5; i++) {
int ret = 1;
for (int j = 1; j <= i; j++) {
ret *= j;
}
sum += ret;
}
System.out.println(sum);
}
}
使用嵌套回圈比較容易寫出bug,而利用方法就可以有效避免,并且能將功能單一化:
public class Method {
/**
* 求n的階乘
* @param args
*/
public static int fac(int n) {
int ret = 1;
for (int i = 1; i <= n; i++) {
ret *= i;
}
return ret;
}
/**
* 求1~5的階乘之和
* @param args
*/
public static int sumFac(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += fac(i);
}
return sum;
}
public static void main(String[] args) {
int n = 5;
int ret = sumFac(n);
System.out.println(ret);
}
}
使用兩個不同的方法完成兩個獨立的功能,這種寫法更加體現代碼的可讀性和可維護性~
方法的定義規則
在Java中的使用規則需要用到類和物件的概念,但那不是本文主要講述的內容,所以這里不多贅述,只需要知道初學者大部分使用的方法都有固定的寫法:
例如:
public class Method {
public static void func() {
System.out.println("hehe");
}
public static void main(String[] args) {
func();
}
}
這里的func方法采用的寫法就是
public + static + 回傳型別 + 方法名(引數串列)
我們只需要知道他固定的寫法格式即可,具體含義在學習了類和物件即可理解,有興趣的小伙伴也可以看博主的專欄JavaSE
里面記錄了JavaSE需要掌握的全部內容~
注意:
- 引數串列中必須給出引數的資料型別,
(可以沒有引數) - 方法名必須采用小駝峰寫法,
總結:
- public和static在這里有特殊的含義,但不在本文作詳細介紹,有興趣可以看博主專欄JavaSE,
- 在方法定義中,可以沒有引數,但如果有引數,一定要指明引數型別,
- 方法定義中,可以沒有回傳值,但方法定義的回傳型別應該是void型別,
- 方法呼叫時的引數稱為實參,方法定義時的引數稱為形參,
- 方法的定義必須在類當中,但在類當中的具體為止不受約束,可處于代碼背景關系任意位置,
- Java中沒有函式宣告的概念,
方法的執行程序
這里我們需要注意一點,與C語言不同的是,Java中沒有函式宣告之類的東西,也就是說,我們在寫Java代碼時,不需要對方法進行宣告,這也就意味著,方法的所處的位置是任意的,
我們回憶一下在學習C語言時,函式定義必須在main函式定義之前,否則就需要在使用該函式之前進行函式宣告,而Java中因為沒有方法宣告這種概念,所以也就不需要將方法定義在main函式之前,
下面用一段代碼的執行程序分析方法的執行流程:
public class Method {
/**
* 求n的階乘
* @param n
* @return
*/
public static int fac(int n) {
int ret = 1;
for (int i = 1; i <= n; i++) {
ret *= i;
}
return ret;
}
public static void main(String[] args) {
int ret = fac(5);
System.out.println(ret);
}
}
運行結果:

我們這里分析一下代碼運行流程:
首先程式一定是從上往下執行,但是,遇到方法時并不執行,而是當方法呼叫時才開始執行,
任何程式都是以main函式為起點開始執行的,進入main函式之后執行代碼:int ret = fac(5);
這行代碼的意思是將回傳型別為int的方法fac的回傳值賦值給ret,從這里開始進入fac方法,
注意: main函式中fac方法是方法呼叫,括號里的是實參,方法定義中引數串列里的是形參,實參和形參的個數必須一致,資料型別必須一一對應,
方法呼叫基本規則:
- 方法代碼定義時,不會被執行,只有被呼叫后才會被執行,也就意味著同一個方法可能被執行多次,
- 方法在呼叫時,會將實參臨時拷貝給形參,(具體只是可以看圖解函式堆疊幀 - 函式的創建與銷毀),
- 引數傳遞(拷貝)后,就會開始執行方法的代碼,
- 當方法代碼被執行完之后(遇到return)就會回傳被呼叫方法中,繼續執行下面的代碼,
- 一個方法可以被多次呼叫,
Java理解方法(函式)堆疊幀
函式堆疊幀是用來理解C語言的重要只是,有興趣的小伙伴可以閱讀我的博文:圖解函式堆疊幀 -
函式的創建與銷毀
博主在里面用C語言和匯編語言詳細介紹了函式的底層實作,
Java是面向物件的語言,其反匯編的封裝做的比較完善,所以不容易分析其方法堆疊幀的原理,所以這里博主通過畫圖的方式簡單介紹即可,
- 我們知道,任何程式的開端都是main方法,而所有的方法都是在堆疊上以壓堆疊的形式開辟的,

- 在main方法里呼叫func方法,則會在堆疊頂為func方法開辟堆疊幀空間,

- 當func方法return之后,則銷毀func方法的堆疊幀,并帶回回傳值交給main方法中呼叫方法的執行陳述句,

實參和形參的關系
實參和形參的關系是我們必須了解的內容,形參其實就是實參的一份臨時拷貝,即實參可以影響形參,但形參無法影響實參,
舉個簡單的例子:交換兩個整數
public class Method {
public static void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
public static void main(String[] args) {
int a = 3;
int b = 5;
System.out.println(a);
System.out.println(b);
swap(a, b);
System.out.println(a);
System.out.println(b);
}
}
運行結果:

可以發現,這里無法通過形參的交換而改變實參,
畫圖解釋:
- 這里有兩個實參,

- 將實參做一份臨時拷貝給形參

- 通過第三個變數交換形參,

- 交換后

交換后形參發生了改變,但實參并沒有進行交換,當該swap方法執行完之后,其方法堆疊幀將會被銷毀,也就意味著這個方法什么功能都沒能實作,
到這,可能有碼友會問,那能不能類似于C語言,進行傳址呼叫呢?
答案是否定的,在Java中沒有取地址(&)這種操作,也沒有指標的概念,只有類似的參考,所以想要完成這樣的交換功能,只能通過參考的方式,但如果要介紹這道題的正確解法,需要用到類和物件以及參考的知識,就不多介紹,有需要的可以去JavaSE專欄找到相應文章,
這里只把相應代碼展示,以供參考:
public class Method {
public static void swap(int[] arr) {
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}
public static void main(String[] args) {
int[] arr = {10, 20};
swap(arr);
System.out.println("a = " + arr[0] + " b = " + arr[1]);
}
}
二,方法的多載
在Java中方法是可以多載的(overload),
使用多載的目的
用一個簡單的例子說明為什么需要多載,
比如:我要寫一個加法方法,
public class Method {
public static int add(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int a = 3;
int b = 5;
int ret = add(a, b);
System.out.println(ret);
}
}
這個方法只適用于兩個整型的相加,如果我想讓三個整型相加或者兩個浮點數相加則做不到,必須重新寫一個新的方法,其方法名不能和該方法相同,
而方法多載的概念就是改變引數串列,方法名不變,看以下代碼:
public class Method {
public static int add(int x, int y, int z) {
return x + y + z;
}
public static int add(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int a = 3;
int b = 5;
int c = 1;
int ret1 = add(a, b);
int ret2 = add(a, b, c);
System.out.println(ret2);
}
}
此時的public static int add(int x, int y, int z)和public static int add(int x, int y)就構成了多載的關系,
無獨有偶,
public class Method {
public static double add(double x, double y) {
return x + y;
}
public static int add(int x, int y, int z) {
return x + y + z;
}
public static int add(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int a = 3;
int b = 5;
int c = 1;
int ret1 = add(a, b);
int ret2 = add(a, b, c);
// System.out.println(ret2);
double d1 = 3.4;
double d2 = 2.4;
double ret3 = add(d1, d2);
System.out.println(ret3);
}
}
此時的public static double add(double x, double y)和public static int add(int x, int y, int z)以及public static int add(int x, int y)都構成了多載的關系,
這樣寫代碼就可以共用一個函式名,通過不同的引數串列對不同的資料型別實作相同的功能,
多載的規則
- 方法名必須相同,
- 引數串列必須不同(個數,型別),
- 與回傳型別無關,
首先,方法名必須相同,因為實作的是相同的功能,我們可以理解為是同一個方法對于不同資料的衍生處理,
例如:
public class Method {
public static int add1(int x, int y) {
return x + y;
}
public static int add2(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int a = 3;
int b = 5;
int ret1 = add1(a, b);
int ret2 = add2(a, b);
System.out.println(ret1);
System.out.println(ret2);
}
}
此時的add1和add2是完全不同的兩個方法,他們不構成多載關系,
滿足多載關系的條件還有引數串列的不同,也就是說引數個數,型別,有一個滿足不同即可,
最后一點,也是初學者最容易產生誤區的一點,方法的回傳型別并不能影響多載,
也就是說如果方法名相同,引數串列不同的兩個方法,不管回傳型別是否一樣,都構成多載關系,
而如果方法名相同,引數串列也相同的兩個方法,不管回傳型別是否一樣,都不構成多載關系,
三,遞回
程式呼叫自身的編程技巧稱為遞回( recursion),遞回作為一種演算法在程式設計語言中被廣泛應用,
一個程序或方法在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞回策略只需少量的程式就可描述出解題程序所需要的多次重復計算,大大地減少了程式的代碼量,遞回的能力在于用有限的陳述句來定義物件的無限集合,一般來說,遞回需要有邊界條件、遞回前進段和遞回回傳段,當邊界條件不滿足時,遞回前進;當邊界條件滿足時,遞回回傳,
以上概念來自百度百科,雖然話術比較官方,但還算言簡意賅,
其實簡單來說,程式運行時,某一個方法自己呼叫自己,就被稱作遞回,
其實遞回很好理解,他就類似于我們高中學的"數學歸納法",或者又類似于"通項",我們就是要找出其起始條件,推出遞回公式即可完成任務,
遞回公式解決問題
例如:我們要求n!
其遞回公式為n * (n - 1)!
我們要直接求n!不容易,但通過遞回公式就很容易得到,
public class Method {
public static int fac(int n) {
if (n > 1) {
return n * fac(n - 1);
}else {
return 1;
}
}
public static void main(String[] args) {
int ret = fac(5);
System.out.println(ret);
}
}
運行結果:

又比如要求斐波那契數列,我們也可以直接使用遞回公式,
public class Method {
public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
}else {
return fib(n - 1) + fib(n - 2);
}
}
public static void main(String[] args) {
int ret = fib(10);
System.out.println(ret);
}
}
運行結果:

遞回分析程序
其實遞回的名字是有由來的,遞回表示的是兩個動作,即遞和歸,當滿足約束條件時,則遞,不滿足時,則歸,
代碼遞回路線圖
遞回的程序其實是橫向的,接下來畫圖分析,
就拿階乘舉例:

假設給定n為3,
-
下面展示遞程序

-
接下來是歸程序

此時就完成了遞回的全程序,最終將3!的答案6回傳給呼叫方法,
為了方便理解,再用另一種方法描述,
形象分析圖
同樣還是用階乘的代碼來描述,
如圖:

假設這是一個階乘方法的流程,從上至下運行,
遇到遞回呼叫,則重新開辟堆疊幀然后進入新的堆疊幀,

最后一個fac方法走完之后(遇到return)往回歸,

這樣就完成了遞回的內容,并將回傳值帶回,
說了那么多概念和解釋,用幾道簡單的小例題加以鞏固,
遞回練習
- 示例代碼1: 按順序列印一個數字的每一位(例如 1234 列印出 1 2 3 4)
public class Method {
/**
* 按順序列印一個數字的每一位(例如 1234 列印出 1 2 3 4)
* @param args
*/
public static void print(int n) {
if (n < 10) {
System.out.print(n + " ");
}else {
print(n / 10);
System.out.print(n % 10 + " ");
}
}
public static void main(String[] args) {
print(1234);
}
}
- 代碼示例2: 遞回求 1 + 2 + 3 + … + 10
public class Method {
/**
* 遞回求 1 + 2 + 3 + ... + 10
* @param args
*/
public static int sum(int n) {
if (n > 1) {
return n + sum(n - 1);
}else {
return 1;
}
}
public static void main(String[] args) {
int ret = sum(10);
System.out.println(ret);
}
}
- 代碼示例3: 寫一個遞回方法,輸入一個非負整數,回傳組成它的數字之和, 例如,輸入1729,則應該回傳1+7+2+9,它的和是19,
public class Method {
/**
* 寫一個遞回方法,輸入一個非負整數,回傳組成它的數字之和, 例如,輸入 1729, 則應該回傳1+7+2+9,
* 它的和是19
* @param args
*/
public static int sumEveryOne(int n) {
if (n < 10) {
return n;
}else {
return n % 10 + sumEveryOne(n / 10);
}
}
public static void main(String[] args) {
int ret = sumEveryOne(1729);
System.out.println(ret);
}
}
?總結
在學習Java的程序中,會遇到很多和C語言類似的地方,而Java方法就是其轉折點,從Java方法的學習開始,就將和C語言的內容截然不同了,
本文主要介紹了Java方法的概念和用法,并拓展了Java方法引出的方法多載以及方法遞回,希望本文能對大家的學習有幫助,最后求一波三連支持~
👍點贊👍 + 👀關注👀 + 🤏收藏🤏

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/345731.html
標籤:java
