作者主頁:paper jie的博客
本文作者:大家好,我是paper jie,感謝你閱讀本文,歡迎一建三連哦。
本文錄入于《JAVASE語法系列》專欄,本專欄是針對于大學(xué)生,編程小白精心打造的。筆者用重金(時間和精力)打造,將javaSE基礎(chǔ)知識一網(wǎng)打盡,希望可以幫到讀者們哦。
其他專欄:《算法詳解》《C語言》等
內(nèi)容分享:本期將會對JAVA語言進行一個初步大致的講解~
JAVA方法的定義與使用及理解
什么是Java中的方法
方法就是一個代碼片段. 和C 語言中的 "函數(shù)"特別像。它在Java中的作用大家可以理解為C語言中的函數(shù)。
方法存在的意義:
1. 是能夠模塊化的組織代碼(當代碼規(guī)模比較復(fù)雜的時候).
2. 做到代碼被重復(fù)使用, 一份代碼可以在多個位置使用.
3. 讓代碼更好理解更簡單.
4. 直接調(diào)用現(xiàn)有方法開發(fā), 不必重復(fù)造輪子.
比如:現(xiàn)在要開發(fā)一款計算器,在計算器中經(jīng)常要判斷兩個數(shù)相加
public static void main(String[] args) {
int a = 10;
int b = 20;
int sum = a + b;
System.out.println(sum);
}
這上面的代碼也可以用java中方法來定義,使用起來更加方便。
方法的定義?
方法語法格式
修飾符 返回值類型 方法名稱([參數(shù)類型 形參 ...]){
方法體代碼;
[return 返回值];
}
這里舉個栗子:實現(xiàn)一個方法,將兩數(shù)相加
public static int sum(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
// int sum = a + b;
System.out.println(sum(a,b));
}
【注意事項】
1. 修飾符:現(xiàn)階段直接使用public static 固定搭配
2. 返回值類型:如果方法有返回值,返回值類型必須要與返回的實體類型一致,如果沒有返回值,必須寫成void
3. 方法名字:采用小駝峰命名
4. 參數(shù)列表:如果方法沒有參數(shù),()中什么都不寫,如果有參數(shù),需指定參數(shù)類型,多個參數(shù)之間使用逗號隔開
5. 方法體:方法內(nèi)部要執(zhí)行的語句
6. 在java當中,方法必須寫在類當中
7. 在java當中,方法不能嵌套定義
8. 在java當中,沒有方法聲明一說?
方法調(diào)用的執(zhí)行過程
調(diào)用過程:
調(diào)用方法--->傳遞參數(shù)--->找到方法地址--->執(zhí)行被調(diào)方法的方法體--->被調(diào)方法結(jié)束返回--->回到主調(diào)方法繼續(xù)往下執(zhí)行?
注意:
定義方法的時候, 不會執(zhí)行方法的代碼. 只有調(diào)用的時候才會執(zhí)行
一個方法可以被多次調(diào)用?
舉個栗子:兩數(shù)相加
public class Method {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("第一次調(diào)用方法之前");
int ret = add(a, b);
System.out.println("第一次調(diào)用方法之后");
System.out.println("ret = " + ret);
System.out.println("第二次調(diào)用方法之前");
ret = add(30, 50);
System.out.println("第二次調(diào)用方法之后");
System.out.println("ret = " + ret);
}
public static int add(int x, int y) {
System.out.println("調(diào)用方法中 x = " + x + " y = " + y);
return x + y;
}
}
再舉一個栗子:計算 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;
}
}
這里使用方法,我們可?避免使用多次重復(fù), 要計算使用這個方法,可以讓代碼更簡單清晰?
形參和實參的關(guān)系?
方法的形參相當于數(shù)學(xué)函數(shù)中的自變量,Java中方法的形參就相當于sum函數(shù)中的自變量n,用來接收sum函數(shù)在調(diào)用時傳遞的值的。形參的名字可以隨意取,對方法都沒有任何影響,形參只是方法在定義時需要借助的一個變量,用來保存方法在調(diào)用時傳遞過來的值。?
public static int getSum(int N){ // N是形參
return (1+N)*N / 2;
}
getSum(10); // 10是實參,在方法調(diào)用時,形參N用來保存10
getSum(100); // 100是實參,在方法調(diào)用時,形參N用來保存100
public static int add(int a, int b){
return a + b;
} a
dd(2, 3); // 2和3是實參,在調(diào)用時傳給形參a和b
這就好比榨汁機一樣,實參就是我們要放入的水果,形參就是機器要放水果的那個位置,它可以放多種水果,看你選擇,炸出的果汁,就是我們return的值。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
這里要注意一個點:在Java中,實參的值永遠都是拷貝到形參中,形參和實參本質(zhì)是兩個實體。這和C語言是不一樣的,它可以傳指針,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);
}
}
// 運行結(jié)果
swap: x = 20 y = 10
main: a = 10 b = 20
通過運行代碼我們可以知道,在swap函數(shù)交換之后,形參x和y的值發(fā)生了改變,但是main方法中a和b還是交換之前的值,即沒有交換成功。?
原因分析?
實參a和b是main方法中的兩個變量,其空間在main方法的棧(一塊特殊的內(nèi)存空間)中,而形參x和y是swap方法中的兩個變量,x和y的空間在swap方法運行時的棧中,因此:實參a和b 與 形參x和y是兩個沒有任何關(guān)聯(lián)性的變量,在swap方法調(diào)用時,只是將實參a和b中的值拷貝了一份傳遞給了形參x和y,因此對形參x和y操作不會對實參a和b產(chǎn)生任何影響。對于基礎(chǔ)類型來說, 形參相當于實參的拷貝. 即 傳值調(diào)用?
解決辦法??
我們可以使用數(shù)組來解決:
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;
}
} /
/ 運行結(jié)果
arr[0] = 20 arr[1] = 10
void類型的方法
方法的返回值是可選的. 有些時候可以沒有的,沒有時返回值類型必須寫成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);
}
}
方法重載?
方法重載的意義
直接上代碼:
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轉(zhuǎn)換到int可能會有損失
我們發(fā)現(xiàn)由于參數(shù)類型不匹配, 所以不能直接使用現(xiàn)有的 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 呢,這里就需要用到我們方法重載的知識了。
什么是方法重載
在自然語言中,一個詞語如果有多重含義,那么就說該詞語被重載了,具體代表什么含義需要結(jié)合具體的場景,比如給女孩子們表白時被拒絕,人家說:你是個好人,很優(yōu)秀,但是我還不想談戀愛。嘿嘿,這里的好人和優(yōu)秀就變成了貶義詞了。
在Java中方法也是可以重載的。java中如果多個方法的名字相同,參數(shù)列表不同,則稱該幾種方法被重載了?
public class TestMethod {
public static void main(String[] args) {
add(1, 2); // 調(diào)用add(int, int)
add(1.5, 2.5); // 調(diào)用add(double, double)
add(1.5, 2.5, 3.5); // 調(diào)用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. 參數(shù)列表必須不同(參數(shù)的個數(shù)不同、參數(shù)的類型不同、類型的次序必須不同)
3. 與返回值類型是否相同無關(guān)?
// 注意:兩個方法如果僅僅只是因為返回值類型不同,是不能構(gòu)成重載的
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)
編譯器在編譯代碼時候呢,會對實參類型進行推演,根據(jù)推演的結(jié)果來確定調(diào)用哪個方法,所以你不用擔心它不知道用哪個函數(shù)啦,編譯器很智能的~
方法簽名?
這可不是明星給你簽名的簽名哦~
大家可以思考一下在同一個作用域中不能定義兩個相同名稱的標識符。比如:方法中不能定義兩個名字一樣的變量,那為什么類中就可以定義方法名相同的方法呢?
這里就是用到了方法簽名,方法簽名即:經(jīng)過編譯器編譯修改過之后方法最終的名字。具體方式:方法全路徑名+參數(shù)列表+返回值類型,構(gòu)成方法完整的名字?
舉個栗子:
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);
}
}
上面的代碼就是經(jīng)過編譯之后,然后使用JDK自帶的javap反匯編工具查看
具體操作:
1. 先對工程進行編譯生成.class字節(jié)碼文件
2. 在控制臺中進入到要查看的.class所在的目錄
3. 輸入:javap -v 字節(jié)碼文件名字即可?
方法簽名中的特殊符號:?
?遞歸
關(guān)于遞歸的一個好玩的叫法叫做:套娃,要是你玩的不好,就變成了無限套娃了,出也出不來。
上面的兩個圖片有個共同的特征,就是自身中又包含了自己,該種思想在數(shù)學(xué)和編程中非常用,因為有些時候,我們遇到的問題直接并不好解決,但是發(fā)現(xiàn)將原問題拆分成其子問題之后,子問題與原問題有相同的解法,等子問題解決之后,原問題就迎刃而解了,這就是遞歸的解決辦法。
什么是遞歸?
一個方法在執(zhí)行過程中調(diào)用自身, 就稱為 "遞歸".遞歸相當于數(shù)學(xué)上的 "數(shù)學(xué)歸納法", 有一個起始條件, 然后有一個遞推公式:?
求 N!
起始條件: N = 1 的時候, N! 為 1. 這個起始條件相當于遞歸的結(jié)束條件.
那么遞歸公式: 求 N!???N! => N * (N-1)!?
遞歸需要注意的兩個地方:
遞歸的必要條件:
1. 將原問題劃分成其子問題,注意:子問題必須要與原問題的解法相同
2. 遞歸出口
舉個栗子:
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;
} r
eturn n * factor(n - 1); // factor 調(diào)用函數(shù)自身
}
遞歸調(diào)用的執(zhí)行過程?
要理解清楚遞歸, 我們要先理解清楚 "方法的執(zhí)行過程", 尤其是 "方法執(zhí)行結(jié)束之后, 回到調(diào)用位置繼續(xù)往下執(zhí)行",這里以上面那個代碼為例,畫圖給大家分析一波:
?程序就是按照途中的紅線和紫線順序執(zhí)行的.
這里有一個棧的知識點:
方法調(diào)用的時候, 會有一個 "棧" 這樣的內(nèi)存空間描述當前的調(diào)用關(guān)系. 稱為調(diào)用棧.
每一次的方法調(diào)用就稱為一個 "棧幀", 每個棧幀中包含了這次調(diào)用的參數(shù)是哪些, 返回到哪里繼續(xù)執(zhí)行等信息.
我們借助 IDEA 很容易看到調(diào)用棧的內(nèi)容
?練習(xí)
下面有幾個遞歸練習(xí)的題目,大家有興趣可以練習(xí)一下:
遞歸求 1 + 2 + 3 + ... + 10?
public static void main(String[] args) {
int ret = sum(10);
System.out.println(ret);
}
public static int sum(int n) {
if(n==1)
return 1;
return n + sum(n-1);
}
按順序打印一個數(shù)字的每一位(例如 1234 打印出 1 2 3 4)??
public static void prin (int n) {
if(n<10) {
System.out.println(n);
return;
}
prin(n/10);
System.out.println(n%10);
}
寫一個遞歸方法,輸入一個非負整數(shù),返回組成它的數(shù)字之和. 例如,輸入 1729, 則應(yīng)該返回
1+7+2+9,它的和是19??
public static int sum(int num) {
if (num < 10) {
return num;
} r
eturn num % 10 + sum(num / 10);
}
求斐波那契數(shù)列的第 N 項??
遞歸版
public class Test {
public static void main(String[] args) {
System.out.println(fib(6));
}
public static int fib(int n) {
if(n==1 || n==2)
return 1;
return fib(n-1) + fib(n-2);
}
迭代版文章來源:http://www.zghlxwxcb.cn/news/detail-622557.html
迭代版的效率比遞歸高很多,盡量用迭代來求fib文章來源地址http://www.zghlxwxcb.cn/news/detail-622557.html
public static void main(String[] args) {
System.out.println(fib2(6));
}
public static int fib2(int n) {
if(n==1 || n==2) {
return 1;
}
int flg1 = 1;
int flg2 = 1;
int flg3 = 0;
int i = 3;
while(i<=n) {
flg3 = flg1 + flg2;
flg1 = flg2;
flg2 = flg3;
i++;
}
return flg3;
}
到了這里,關(guān)于【JAVA】帶你認識java方法|java中的方法&方法中的重載和遞歸的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!