Java中方法使用的深入講解
方法的使用
1.方法的基本用法
什么是方法,方法就是一個代碼片段,類似于C/C++ 語言中的"函數(shù)"。
1.1方法存在的意義:
- 是能夠模塊化的組織代碼(當(dāng)代碼規(guī)模比較復(fù)雜的時候).
- 做到代碼被重復(fù)使用, 一份代碼可以在多個位置使用.
- 讓代碼更好理解更簡單.
- 直接調(diào)用現(xiàn)有方法開發(fā),不必重復(fù)造輪子。
1.2方法定義語法
基本語法:
// 方法定義 public static 方法返回值 方法名稱([參數(shù)類型 形參 ...]){ 方法體代碼; [return 返回值]; } // 方法調(diào)用 返回值變量 = 方法名稱(實參...);
代碼示例:實現(xiàn)一個方法實現(xiàn)兩個正數(shù)相加
class Test { public static void main(String[] args) { int a = 10; int b = 20; // 方法的調(diào)用 int ret = add(a, b); System.out.println("ret = " + ret); } // 方法的定義 public static int add(int x, int y) { return x + y; } } // 執(zhí)行結(jié)果 ret = 30
注意事項:
- 就目前而言,只要在 main 函數(shù)中調(diào)用的方法,需要寫 public 和 static 這兩個關(guān)鍵字。
- 方法定義時, 參數(shù)可以沒有,如果有,則每個參數(shù)都要指定類型。
- 方法定義時, 返回值也可以沒有, 如果沒有返回值, 則返回值類型應(yīng)寫成 void。
- 方法定義時的參數(shù)稱為 “形參”, 方法調(diào)用時的參數(shù)稱為 “實參”。
- 方法的定義必須在類之中, java中沒有函數(shù)聲明的概念,所以代碼書寫在調(diào)用位置的上方或者下方均可。
1.3 方法調(diào)用的執(zhí)行過程
基本規(guī)則:
- 定義方法的時候, 不會執(zhí)行方法的代碼。只有調(diào)用的時候才會執(zhí)行。
- 當(dāng)方法被調(diào)用的時候, 會將實參賦值給形參。
- 參數(shù)傳遞完畢后, 就會執(zhí)行到方法體代碼。
- 當(dāng)方法執(zhí)行完畢之后(遇到 return 語句), 就執(zhí)行完畢, 回到方法調(diào)用位置繼續(xù)往下執(zhí)行。
- 一個方法可以被多次調(diào)用。
代碼示例:計算1!+2!+3!+4!+5!
public static void main(String[] args) { int sum = 0; for (int i = 1; i <= 5; i++) { sum += factor(i); } System.out.println("sum = " + sum); } public static int factor(int n) { System.out.println("計算" + n + "的階乘中!"); int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } } // 執(zhí)行結(jié)果 計算 1 的階乘中! 計算 2 的階乘中! 計算 3 的階乘中! 計算 4 的階乘中! 計算 5 的階乘中! sum = 153
使用方法,避免使用二重循環(huán),當(dāng)然也可以將整個過程都放到一個方法中,讓代碼更簡單清晰。
1.4 實參和形參的關(guān)系(重要)
代碼示例:交換兩個整型變量
class Test { public static void main(String[] args) { int a = 10; int b = 20; swap(a, b); System.out.println("a = " + a + " b = " + b); } public static void swap(int x, int y) { int tmp = x; x = y; y = tmp; } } // 運行結(jié)果 a = 10 b = 20
那么可以看到,變量a和b的值并沒有完成交換。
原因分析:
對于基礎(chǔ)類型來說,形參相當(dāng)于實參的拷貝,即傳值調(diào)用。
解決方法:
如果目前想要解決這個問題,可以傳引用類型參數(shù)(例如數(shù)組來解決這個問題)。對于數(shù)組的使用,現(xiàn)在先做了解,后面我會總結(jié)。
class Test { public static void main(String[] args) { int[] arr = {10, 20}; swap(arr); System.out.println("a = " + arr[0] + " b = " + arr[1]); } public static void swap(int[] arr) { int tmp = arr[0]; arr[0] = arr[1]; arr[1] = tmp; } } // 運行結(jié)果 a = 20 b = 10
1.5 沒有返回值的方法
方法的返回值是可選的,有些時候可以沒有的。
代碼示例:
class Test { public static void show(int x, int y) { System.out.println("Hello World!"); } public static void main(String[] args) { show(); } } //運行結(jié)果: Hello World!
例如剛才的交換兩個整數(shù)的方法,也是沒有返回值的。在使用時要注意方法是否有返回值,如果有則需要用相同類型的變量來接受。
2.方法的重載
有些時候我們需要用一個函數(shù)同時兼容多種參數(shù)的情況,這時候我們就用到方法的重載。
2.1重載要解決的問題
代碼示例:
class Test { public static void main(String[] args) { int a = 10; int b = 20; int ret = add(a, b); System.out.println("ret = " + ret); double a2 = 10.5; double b2 = 20.5; double ret2 = add(a2, b2); System.out.println("ret2 = " + ret2); } public static int add(int x, int y) { return x + y; } } // 編譯出錯 Test.java:13: 錯誤: 不兼容的類型: 從double轉(zhuǎn)換到int可能會有損失 double ret2 = add(a2, b2); ^
由于參數(shù)類型不匹配,所以不能直接使用現(xiàn)有的add方法。
2.2 使用重載
代碼示例:
class Test { public static int add(int x, int y) { return x + y; } public static double add(double x, double y) { return x + y; } public static double add(double x, double y, double z) { return x + y + z; } public static void main(String[] args) { int a = 10; int b = 20; int ret = add(a, b); System.out.println("ret = " + ret); double a2 = 10.5; double b2 = 20.5; double ret2 = add(a2, b2); System.out.println("ret2 = " + ret2); double a3 = 10.5; double b3 = 10.5; double c3 = 20.5; double ret3 = add(a3, b3, c3); System.out.println("ret3 = " + ret3); } }
那么可以看到方法名字都叫add,但是有的add是int相加,有的是double相加,有的計算三個數(shù)字相加,所以,對于同一個方法名字,提供不同版本的實現(xiàn),稱為方法重載。
2.3重載的規(guī)則
針對同一個類:
- 方法名相同。
- 方法的參數(shù)不同(參數(shù)個數(shù)或者參數(shù)類型)。
- 方法的返回值類型不影響重載。
代碼示例:
class Test { public static void main(String[] args) { int a = 10; int b = 20; int ret = add(a, b); System.out.println("ret = " + ret); } public static int add(int x, int y) { return x + y; } public static double add(int x, int y) { return x + y; } } // 編譯出錯 Test.java:13: 錯誤: 已在類 Test中定義了方法 add(int,int) public static double add(int x, int y) { ^ 1 個錯誤
那么可以看到,當(dāng)兩個方法的名字相同,參數(shù)也相同,但是只有返回值不同的時候,不構(gòu)成函數(shù)重載。
3.方法遞歸
3.1遞歸的概念
一個方法在執(zhí)行過程中調(diào)用自身, 就稱為 “遞歸”。
遞歸相當(dāng)于數(shù)學(xué)上的 “數(shù)學(xué)歸納法”, 有一個起始條件, 然后有一個遞推公式。
例如, 我們求 N!
起始條件: N = 1 的時候, N! 為 1。這個起始條件相當(dāng)于遞歸的結(jié)束條件。
遞歸公式: 求 N! , 直接不好求, 可以把問題轉(zhuǎn)換成 N!=> N*(N-1)!
代碼示例:遞歸求 N 的階乘
public static int factor(int n) { if (n == 1) { return 1; } return n * factor(n - 1); // factor 調(diào)用函數(shù)自身 } public static void main(String[] args) { int n = 5; int ret = factor(n); System.out.println("ret = " + ret); } // 執(zhí)行結(jié)果 ret = 120
有了方法遞歸,可以發(fā)現(xiàn)不用使用循環(huán),那么他的過程是怎么執(zhí)行的,且看下面分析。
3.2遞歸執(zhí)行過程分析
遞歸的程序的執(zhí)行過程不太容易理解, 要想理解清楚遞歸, 必須先理解清楚方法的執(zhí)行過程", 尤其是 "方法執(zhí)行結(jié)束之后,回到調(diào)用位置繼續(xù)往下進行。
代碼示例:遞歸求 N 階乘,加上"日志"版本
public static int factor(int n) { System.out.println("函數(shù)開始, n = " + n); if (n == 1) { System.out.println("函數(shù)結(jié)束, n = 1 ret = 1"); return 1; } int ret = n * factor(n - 1); System.out.println("函數(shù)結(jié)束, n = " + n + " ret = " + ret); return ret; } public static void main(String[] args) { int n = 5; int ret = factor(n); System.out.println("ret = " + ret); } // 執(zhí)行結(jié)果 函數(shù)開始, n = 5 函數(shù)開始, n = 4 函數(shù)開始, n = 3 函數(shù)開始, n = 2 函數(shù)開始, n = 1 函數(shù)結(jié)束, n = 1 ret = 1 函數(shù)結(jié)束, n = 2 ret = 2 函數(shù)結(jié)束, n = 3 ret = 6 函數(shù)結(jié)束, n = 4 ret = 24 函數(shù)結(jié)束, n = 5 ret = 120 ret = 120
執(zhí)行過程圖:
3.3遞歸練習(xí)
代碼示例1:按順序打印一個數(shù)字的每一位(例如 1234 打印出 1 2 3 4)
public static void print(int num) { if (num > 9) { print(num / 10); } System.out.println(num % 10); }
代碼示例2:遞歸求 1 + 2 + 3 + … + 10
public static int sum(int num) { if (num == 1) { return 1; } return num + sum(num - 1); }
代碼示例3:寫一個遞歸方法,輸入一個非負整數(shù),返回組成它的數(shù)字之和. 例如,輸入 1729, 則應(yīng)該返回1+7+2+9,它的和是19
public static int sum(int num) { if (num < 10) { return num; } return num % 10 + sum(num / 10); }
代碼示例4:求斐波那契數(shù)列的第N項
public static int fib(int n) { if (n == 1 || n == 2) { return 1; } return fib(n - 1) + fib(n - 2); }
用遞歸來求解,可以發(fā)現(xiàn)求前幾項是非??焖俚?,但當(dāng)我們求fib(40)的時候,發(fā)現(xiàn)程序運行速度極慢,原因是遞歸會造成大量的重復(fù)運算。
那么有效的解決方法就是利用迭代的方法來求解。
public static int fib(int n) { int f1 = 1; int f2 = 1; int cur = 0; for (int i = 3; i <= n; i++) { cur = f1 + f2; f2 = f1; f1 = cur; } return cur; } //此時可以發(fā)現(xiàn)求解fib(40)非常的快,結(jié)果是102334155
3.4遞歸小結(jié)
- 遞歸是一種重要的編程解決問題的方式。
- 有些問題天然就是使用遞歸方式定義的(例如斐波那契數(shù)列, 二叉樹等), 此時使用遞歸來解就很容易。
- 有些問題使用遞歸和使用非遞歸(循環(huán))都可以解決. 那么此時更推薦使用循環(huán), 相比于遞歸, 非遞歸程序更加高效。
總結(jié)
到此這篇關(guān)于Java中方法使用的文章就介紹到這了,更多相關(guān)Java方法使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot ThreadLocal 簡單介紹及使用詳解
ThreadLocal 叫做線程變量,意思是 ThreadLocal 中填充的變量屬于當(dāng)前線程,該變量對其他線程而言是隔離的,也就是說該變量是當(dāng)前線程獨有的變量,這篇文章主要介紹了SpringBoot ThreadLocal 的詳解,需要的朋友可以參考下2024-01-01SpringBoot實現(xiàn)發(fā)送郵件任務(wù)
這篇文章主要為大家詳細介紹了SpringBoot實現(xiàn)發(fā)送郵件任務(wù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02Java中快速排序優(yōu)化技巧之隨機取樣、三數(shù)取中和插入排序
快速排序是一種常用的基于比較的排序算法,下面這篇文章主要給大家介紹了關(guān)于Java中快速排序優(yōu)化技巧之隨機取樣、三數(shù)取中和插入排序的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-09-09SpringBoot?SpringSecurity?JWT實現(xiàn)系統(tǒng)安全策略詳解
Spring?Security是Spring的一個核心項目,它是一個功能強大且高度可定制的認證和訪問控制框架。它提供了認證和授權(quán)功能以及抵御常見的攻擊,它已經(jīng)成為保護基于spring的應(yīng)用程序的事實標準2022-11-11Java集合基礎(chǔ)知識 List/Set/Map詳解
這篇文章主要介紹了Java集合基礎(chǔ)知識 List/Set/Map,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03