Java——方法的使用

目錄

一.方法的概念及使用

1 什么是方法(method)

?2.方法定義

3 方法調用的執行過程

4 實參和形參的關系(重要)

5.沒有返回值的方法

二.方法重載

1.為什么需要方法重載

2.方法重載概念

3.方法簽名 ?

三.遞歸

1.遞歸的概念

2.遞歸執行過程分析

3.?遞歸練習


一.方法的概念及使用

1 什么是方法(method)

方法就是一個代碼片段 . 類似于 C 語言中的 " 函數 " 。方法存在的意義 ( 不要背 , 重在體會 ):
(1)是能夠模塊化的組織代碼 ( 當代碼規模比較復雜的時候 ).
(2)做到代碼被重復使用 , 一份代碼可以在多個位置使用 .
(3)讓代碼更好理解更簡單 .
(4)直接調用現有方法開發 , 不必重復造輪子 .
比如:現在要開發一款日歷,在日歷中經常要判斷一個年份是否為閏年,則有如下代碼:
int year = 1900;
if((0 == year % 4 && 0 != year % 100) || 0 == year % 400){System.out.println(year+"年是閏年");
}else{System.out.println(year+"年不是閏年");
}

?2.方法定義

?方法語法格式

// 方法定義
修飾符 返回值類型 方法名稱([參數類型 形參 ...]){方法體代碼;[return 返回值];
}
示例一 :實現一個函數,檢測一個年份是否為閏年
public class Method{
// 方法定義public static boolean isLeapYear(int year){if((0 == year % 4 && 0 != year % 100) || 0 == year % 400){return true;}else{return false;}}
}
示例二 : 實現一個兩個整數相加的方法
注意事項
(1)修飾符:現階段直接使用 public static 固定搭配
(2)返回值類型: 如果方法有返回值,返回值類型必須要與返回的實體類型一致,如果沒有返回值,必須寫成 void
(3)方法名字:采用小駝峰命名
(4)參數列表:如果方法沒有參數, () 中什么都不寫,如果有參數,需指定參數類型,多個參數之間使用逗號隔開
(5)方法體:方法內部要執行的語句
(6)在 java 當中,方法必須寫在類當中
(7)在 java 當中,方法不能嵌套定義
(8)在 java 當中,沒有方法聲明一說(不同于C語言)

3 方法調用的執行過程

方法調用過程
調用方法 --- > 傳遞參數 --- > 找到方法地址 --- > 執行被調方法的方法體 --- > 被調方法結束返回 --- > 回到主調方法繼續往下 執行

?

注意事項
(1)定義方法的時候 , 不會執行方法的代碼 . 只有調用的時候才會執行 .
(2)一個方法可以被多次調用 .

代碼示例 1 計算兩個整數相加
public class Method {public static void main(String[] args) {int a = 10;int b = 20;System.out.println("第一次調用方法之前");int ret = add(a, b);System.out.println("第一次調用方法之后");System.out.println("ret = " + ret);System.out.println("第二次調用方法之前");ret = add(30, 50);System.out.println("第二次調用方法之后");System.out.println("ret = " + ret);
}public static int add(int x, int y) {System.out.println("調用方法中 x = " + x + " y = " + y);return x + y;}
}
// 執行結果
一次調用方法之前
調用方法中 x = 10 y = 20
第一次調用方法之后
ret = 30
第二次調用方法之前
調用方法中 x = 30 y = 50
第二次調用方法之后
ret = 80

?代碼示例: 計算 1! + 2! + 3! + 4! + 5!

public class TestMethod {public static void main(String[] args) {int sum = 0;for (int i = 1; i <= 5; i++) {sum += fac(i);}System.out.println("sum = " + sum);}public static int fac(int n) {System.out.println("計算 n 的階乘中n! = " + n);int result = 1;for (int i = 1; i <= n; i++) {result *= i;}return result;}
}
// 執行結果
計算 n 的階乘中 n! = 1
計算 n 的階乘中 n! = 2
計算 n 的階乘中 n! = 3
計算 n 的階乘中 n! = 4
計算 n 的階乘中 n! = 5
sum = 153
使用方法 , 避免使用二重循環 , 讓代碼更簡單清晰

4 實參和形參的關系(重要)

  • 方法的形參相當于數學函數中的自變量,比如:1 + 2 + 3 + … + n的公式為sum(n) =1/2(1+n)*n
  • Java中方法的形參就相當于sum函數中的自變量n,用來接收sum函數在調用時傳遞的值的。形參的名字可以隨意取,對方法都沒有任何影響,形參只是方法在定義時需要借助的一個變量,用來保存方法在調用時傳遞過來的值
public static int getSum(int N){ // N是形參return (1+N)*N / 2;
}
getSum(10); // 10是實參,在方法調用時,形參N用來保存10
getSum(100); // 100是實參,在方法調用時,形參N用來保存100
再比如:
public static int add(int a, int b){return a + b;
}
add(2, 3); // 2和3是實參,在調用時傳給形參a和b

注意: Java 中,實參的值永遠都是拷貝到形參中,形參和實參本質是兩個實體
代碼示例 : 交換兩個整型變量
public class TestMethod {public static void main(String[] args) {int a = 10;int b = 20;swap(a, b);System.out.println("main: a = " + a + " b = " + b);
}
public static void swap(int x, int y) {int tmp = x;x = y;y = tmp;System.out.println("swap: x = " + x + " y = " + y);}
}
// 運行結果
swap: x = 20 y = 10
main: a = 10 b = 20
可以看到,在 swap 函數交換之后,形參 x y 的值發生了改變,但是 main 方法中 a b 還是交換之前的值,即沒有交換成功。

實參 a b main 方法中的兩個變量,其空間在 main 方法的棧 ( 一塊特殊的內存空間 ) 中,而形參 x y swap 方法中的兩個變量,x y 的空間在 swap 方法運行時的棧中,因此:實參 a b 與形參 x y 是兩個沒有任何關聯性的變量, swap 方法調用時,只是將實參 a b 中的值拷貝了一份傳遞給了形參 x y ,因此對形參 x y 操作不會對實參 a b產生任何影響。
注意:對于 基礎類型 來說 , 形參相當于實參的拷貝 . 傳值調用
int a = 10;
int b = 20;
int x = a;
int y = b;
int tmp = x;
x = y;
y = tmp;
可以看到 , x y 的修改 , 不影響 a b。
解決辦法 : 傳引用類型參數 ( 例如數組來解決這個問題 )
public class TestMethod {public static void main(String[] args) {int[] arr = {10, 20};swap(arr);System.out.println("arr[0] = " + arr[0] + " arr[1] = " + arr[1]);
}
public static void swap(int[] arr) {int tmp = arr[0];arr[0] = arr[1];arr[1] = tmp;}
}
// 運行結果
arr[0] = 20 arr[1] = 10

5.沒有返回值的方法

方法的返回值是可選的 . 有些時候可以沒有的,沒有時返回值類型必須寫成 void
代碼示例:
class Test {public static void main(String[] args) {int a = 10;int b = 20;print(a, b);
}public static void print(int x, int y) {System.out.println("x = " + x + " y = " + y);}
}
另外 , 如剛才的交換兩個整數的方法 , 就是沒有返回值的 .

二.方法重載

1.為什么需要方法重載

public class TestMethod {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轉換到int可能會有損失
double ret2 = add(a2, b2);^
由于參數類型不匹配 , 所以不能直接使用現有的 add 方法 .
一種比較簡單粗暴的解決方法如下:
public class TestMethod {public static void main(String[] args) {int a = 10;int b = 20;int ret = addInt(a, b);System.out.println("ret = " + ret);double a2 = 10.5;double b2 = 20.5;double ret2 = addDouble(a2, b2);System.out.println("ret2 = " + ret2);
}public static int addInt(int x, int y) {return x + y;
}public static double addDouble(double x, double y) {return x + y;}
}
上述代碼確實可以解決問題,但不友好的地方是:需要提供許多不同的方法名,而取名字本來就是讓人頭疼的事 情。那能否將所有的名字都給成 add 呢?

2.方法重載概念

在自然語言中,經常會出現一詞多義的現象,比如:好人”。

在自然語言中,一個詞語如果有多重含義,那么就說該詞語被重載了,具體代表什么含義需要結合具體的場景。 在Java 中方法也是可以重載的。

Java中,如果多個方法的名字相同,參數列表不同,則稱該幾種方法被重載了

public class TestMethod {public static void main(String[] args) {add(1, 2); // 調用add(int, int)add(1.5, 2.5); // 調用add(double, double)add(1.5, 2.5, 3.5); // 調用add(double, double, double)
}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;}
}

?注意:

(1)方法名必須相同

(2)參數列表必須不同(參數的個數不同、參數的類型不同、類型的次序必須不同)

(3)與返回值類型是否相同無關
// 注意:兩個方法如果僅僅只是因為返回值類型不同,是不能構成重載的
public class TestMethod {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 個錯誤
(4)?編譯器在編譯代碼時,會對實參類型進行推演,根據推演的結果來確定調用哪個方法

3.方法簽名 ?

(1)在同一個作用域中不能定義兩個相同名稱的標識符。比如:方法中不能定義兩個名字一樣的變量,那 為什么類中就 可以定義方法名相同的方法呢?
(2)方法簽名即:經過編譯器編譯修改過之后方法最終的名字。具體方式: 方法全路徑名 + 參數列表 + 返回值類型,構成 方法完整的名字。
public class TestMethod {public static int add(int x, int y){return x + y;}public static double add(double x, double y){return x + y;}public static void main(String[] args) {add(1,2);add(1.5, 2.5);}
}
上述代碼經過編譯之后,然后使用 JDK 自帶的 javap 反匯編工具查看,具體操作:
(1)先對工程進行編譯生成
(2)在控制臺中進入到要查
(3)輸入: javap -v 字節碼

?

方法簽名中的一些特殊符號說明:
特殊字符數據類型
Vvoid
Zboolean
Bbyte
Cchar
S

short

Iint
Jlong
Ffloat
Ddouble
[
數組 ( [ 開頭,配合其他的特殊字符,表述對應數據類型的數組,幾個 [ 表述幾維數組 )
L
引用類型,以 L 開頭,以 ; 結尾,中間是引用類型的全類名

三.遞歸

生活中的故事
從前有坐山,山上有座廟,廟里有個老和尚給小和尚將故事,講的就是:
" 從前有座山,山上有座廟,廟里有個老和尚給小和尚講故事,講的就是:
" 從前有座山,山上有座廟 ..."
" 從前有座山 ……"
"

上面的兩個故事有個共同的特征: 自身中又包含了自己 ,該種思想在數學和編程中非常有用,因為有些時候,我們 遇到的問題直接并不好解決,但是發現將原問題拆分成其子問題之后,子問題與原問題有相同的解法,等子問題解 決之后,原問題就迎刃而解了


1.遞歸的概念

一個方法在執行過程中調用自身, 就稱為 "遞歸". 遞歸相當于數學上的 "數學歸納法", 有一個起始條件, 然后有一個遞推公式.

例如 , 我們求 N!
起始條件 : N = 1 的時候 , N! 1. 這個起始條件相當于遞歸的結束條件.
遞歸公式 : N! , 直接不好求 , 可以把問題轉換成 N! => N * (N-1)!

遞歸的必要條件:
1. 將原問題劃分成其子問題,注意:子問題必須要與原問題的解法相同
2. 遞歸出口

代碼示例: 遞歸求 N 的階乘

public static void main(String[] args) {int n = 5;int ret = factor(n);System.out.println("ret = " + ret);
}
public static int factor(int n) {if (n == 1) {return 1;}return n * factor(n - 1); // factor 調用函數自身
}
// 執行結果
ret = 120

2.遞歸執行過程分析

遞歸的程序的執行過程不太容易理解 , 要想理解清楚遞歸 , 必須先理解清楚 " 方法的執行過程 ", 尤其是 " 方法執行結束之后, 回到調用位置繼續往下執行 ".

代碼示例 : 遞歸求 N 的階乘
public static void main(String[] args) {int n = 5;int ret = factor(n);System.out.println("ret = " + ret);
}
public static int factor(int n) {System.out.println("函數開始, n = " + n);if (n == 1) {System.out.println("函數結束, n = 1 ret = 1");return 1;}int ret = n * factor(n - 1);System.out.println("函數結束, n = " + n + " ret = " + ret);return ret;
}
// 執行結果
函數開始, n = 5
函數開始, n = 4
函數開始, n = 3
函數開始, n = 2
函數開始, n = 1
函數結束, n = 1 ret = 1
函數結束, n = 2 ret = 2
函數結束, n = 3 ret = 6
函數結束, n = 4 ret = 24
函數結束, n = 5 ret = 120
ret = 120
執行過程圖

遞歸比較耗費內存,,空間復雜度高

關于 " 調用棧 ":
方法調用的時候 , 會有一個 " " 這樣的內存空間描述當前的調用關系 . 稱為調用棧 .
每一次的方法調用就稱為一個 " 棧幀 ", 每個棧幀中包含了這次調用的參數是哪些 , 返回到哪里繼續執行等信息 . 后面我們借助 IDEA 很容易看到調用棧的內容 .

3.?遞歸練習

代碼示例1 按順序打印一個數字的每一位(例如 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 寫一個遞歸方法,輸入一個非負整數,返回組成它的數字之和 . 例如,輸入 1729, 則應該返回1+7+2+9,它的和是 19
public static int sum(int num) {if (num < 10) {return num;}return num % 10 + sum(num / 10);
}
代碼示例 4 求斐波那契數列的第 N
斐波那契數列介紹 : https://baike.sogou.com/v267267.htm?
fromTitle=%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97
public static int fib(int n) {if (n == 1 || n == 2) {return 1;}return fib(n - 1) + fib(n - 2);
}
當我們求 fib(40) 的時候發現 , 程序執行速度極慢 . 原因是進行了大量的重復運算
class Test {public static int count = 0; // 這個是類的成員變量. 后面會詳細介紹到.public static void main(String[] args) {System.out.println(fib(40));System.out.println(count);
}
public static int fib(int n) {if (n == 1 || n == 2) {return 1;}if (n == 3) {count++;}return fib(n - 1) + fib(n - 2);}
}
// 執行結果
102334155
39088169 // fib(3) 重復執行了 3 千萬次.
可以使用循環的方式來求斐波那契數列問題 , 避免出現冗余運算
public static int fib(int n) {int last2 = 1;int last1 = 1;int cur = 0;for (int i = 3; i <= n; i++) {cur = last1 + last2;
//這兩個式子不能互換last2 = last1;last1 = cur;}return cur;
}
此時程序的執行效率大大提高了

4.漢羅塔問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696574.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696574.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696574.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

貓頭虎分享已解決Bug || 容器編排問題:OrchestrationFailure, ContainerManagementError

博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的寶典&#xff01;《IDEA開發秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鴻蒙》 …

代碼隨想錄算法訓練營第四十二天|122. 買賣股票的最佳時機 II

674. 最長連續遞增序列 public static int findLengthOfLCIS(int[] nums) {int[] dp new int[nums.length];dp[0] 1;for (int i 1; i < nums.length; i) {dfs(nums, dp, i);}Arrays.sort(dp);return dp[dp.length - 1];}public static void dfs(int[] nums, int[] dp, i…

【Python】【VS Code】VS Code中python.json和setting.json文件配置說明

目錄 1. python.json配置 2. setting.json配置 3. 解決中文亂碼 4. 實現效果 1. python.json配置 python.json 獲取步驟&#xff1a;文件 -> 首選項 -> 配置用戶代碼片段 -> python 此為VS Code的頭文件設置&#xff0c;復制以下內容到 python.json {"HEADER…

個人做抖店如何能夠快速起店?掌握好技巧是關鍵!建議收藏!

大家好&#xff0c;我是電商小布。 相信我們每個朋友在店鋪開通后&#xff0c;最關心的事情就是小店成功起店了。 那么個人做抖店想要快速起店&#xff0c;該怎么來進行操作呢&#xff1f; 接下來&#xff0c;小布重點給大家說三點&#xff1a; 首先來說一下小店的主體類型…

git常用命令記錄

1、第一次初始化 git init git add . git commit -m ‘first commit’ git remote add origin gitgithub.com:帳號名/倉庫名.git git pull origin master git push origin master # -f 強推 git clone gitgithub.com:git帳號名/倉庫名.git 2、工作基本操作 git checkout master…

dell r740服務器黃燈閃爍維修現場解決

1&#xff1a;首先看一下這款DELL非常主力的PowerEdge R740服務器長啥樣&#xff0c;不得不說就外觀來說自從IBM拋棄System X系列服務器后&#xff0c;也就戴爾這個外觀看的比較順眼。 圖一&#xff1a;是DELL R740前視圖&#xff08;這款是8盤機型&#xff09; 圖二&#xff…

QT 數據庫的增加操作和畫圖 Win

第一步、先配置CMakeLists.txt 在CMakeLists.txt中添加 find_package(Qt6 REQUIRED COMPONENTS Sql) find_package(Qt6 REQUIRED COMPONENTS Charts)target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Sql) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Charts)避…

springboot集成JWT實現token權限認證

vuespringboot登錄與注冊功能的實現 注&#xff1a;對于JWT的學習&#xff0c;首先要完成注冊和登錄的功能&#xff0c;本篇博客是基于上述博客的進階學習&#xff0c;代碼頁也是在原有的基礎上進行擴展 ①在pom.xml添加依賴 <!-- JWT --> <dependency><grou…

Linux篇:Shell命令以及運行原理 和 權限

一. Shell命令及原理 Linux操作系統狹義上是Linux內核&#xff0c;廣義上是指Linux內核Linux外殼(Shell)和對應的配套程序 Linux外殼&#xff1a;Linux 外殼是用戶與內核之間的接口&#xff0c;用戶通過外殼與操作系統進行交互和操作。在 Linux 系統中&#xff0c;用戶可以選…

C語言——static的三大用法

被稱為面試愛考愛問題的它到底有何奧義 它難度不大并且非常常用&#xff0c;話不多說&#xff0c;直接開始 一、局部靜態變量 定義 在函數內部使用static修飾的變量被稱為局部靜態變量&#xff0c;與普通的局部變量不同&#xff0c;局部靜態變量在使用后不會被銷毀&#xff…

pycharm 遠程運行報錯 Failed to prepare environment

什么也沒動的情況下&#xff0c;遠程連接后運行是沒問題的&#xff0c;突然在運行時就運行不了了&#xff0c;解決方案 清理緩存&#xff1a; 有時候 PyCharm 的內部緩存可能出現問題&#xff0c;可以嘗試清除緩存&#xff08;File > Invalidate Caches / Restart&#xff0…

mysql優化指南之原理篇

之前碰到一個線上問題&#xff0c;在接手一個同事的項目后&#xff0c;因為工期比較趕&#xff0c;我還沒來得及了解業務背景和大致實現&#xff0c;只是了解了上線發布的順序和驗證方式就進行了上線&#xff0c;在上線進行金絲雀的時候系統還沒發生什么異常&#xff0c;于是我…

【面試題】談談MySQL的事務

事務是啥 MySQL的事務就是把多個sql語句操作打包在一起執行&#xff0c;要么全部執行&#xff0c;要么一個都別執行。這種操作稱為“原子性”&#xff0c;是事務最核心的特征。當某個sql操作出錯時&#xff0c;就會進行“回滾/rollback”操作&#xff0c;即把執行過的操作逆向…

MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄 一、索引概述二、索引結構三、結構 - B-Tree四、結構 - BTree五、結構 - Hash六、索引分類七、索引語法1.案例代碼 八、SQL性能分析1.查看SQl執行頻率2.慢查詢日志3.PROFILES詳情4.EXPLAIN執行計劃 九、 索引使用規則十、SQL 提示十一、覆蓋索引十二、前綴索引十三、單…

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時&#xff0c;接口返回數據時間會很長&#xff0c;數據回顯時間長&#xff0c;Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…

考研高數(高階導數的計算)

1.歸納法 常見高階導數 2.泰勒展開式 3.萊布尼茲公式 4.用導數定義證明導函數在某一點連續的例題

【kubernetes】二進制部署k8s集群之cni網絡插件flannel和calico工作原理(中)

↑↑↑↑接上一篇繼續部署↑↑↑↑ 目錄 一、k8s集群的三種接口 二、k8s的三種網絡模式 1、pod內容器之間的通信 2、同一個node節點中pod之間通信 3、不同的node節點的pod之間通信 Overlay Network VXLAN 三、flannel網絡插件 1、flannel插件模式之UDP模式&#xff0…

java對象所占內存大小輸出

如何計算java對象所占內存大小&#xff0c;可以使用下述三種方法。 使用jdk8自帶API 使用下面語句打印對象所占內存大小&#xff1a;需要保證jdk版本是jdk8。System.out.println(ObjectSizeCalculator.getObjectSize(3L)); 借助org.apache.lucene工具類 引入maven坐標 <…

2024/2/22

P8680 [藍橋杯 2019 省 B] 特別數的和 題目描述 小明對數位中含有 2、0、1、9 的數字很感興趣&#xff08;不包括前導 00&#xff09;&#xff0c;在 1 到 40 中這樣的數包括 1、2、9、10 至 32、39 和 40&#xff0c;共28 個&#xff0c;他們的和是574。 請問&#xff0c;在…