一、什麼是方法,爲什麼會有方法?
現在有兩個需求,需要計算100和200的和,還有300和400的和。
//需求1:求100和200的和
int x =100;
int y =100;
int z = x + y;
//需求2:求300和400的和
int a =300;
int b =400;
int c = a+b
需求1和需求2在本質上是一樣的,本來就可以只寫一次的,如果沒有方法,那麼就會存在複用性很差。所以可以將上面寫到方法裏面,然後用變量去接受。
方法是一段可以重複利用的代碼片段,並且這個代碼片段是可以完成某個特定功能的,可以重複利用的代碼片段。
注意:x、y、z在方法中都屬於局部變量,方法結束以後,局部變量佔用的空間會自動結束。
二、方法怎麼定義,語法機制是什麼?
[訪問修飾符] 返回值 方法名(形式參數){
方法體;
}
注意:
(1)返回值類型可以是任何類型,基本數據類型和引用數據類型。
(2)返回值一般指的是一個方法執行結束之後的結果。方法就是爲了完成某個特定的功能,方法結束之後大部分情況下都是有一個結果的,而體現結果的一般都是數據。數據得有類型,這就是返回值類型。
(3)當方法不返回任何值的時候,需要寫上void。
(4)如果返回值類型“不是void”,那麼在方法體執行結束的時候必須使用"return值";這樣的語句來完成“值”的返回,如果沒有"return值;"這樣的語句編譯器就會報錯。
(5)如果返回值類型未void,那麼方法體中可以寫”return;“
(6)形式參數列表
形式參數列表中的每一個參數都是“局部變量",方法結束之後內存釋放,形參的個數是:0~N個。
新參有多個的話使用"逗號,"隔開,逗號是英文的,形參的數據類型起決定性作用,形參對應的變量名是隨意的。
(7)方法體
由Java語句構成。java語句以“;”結尾。方法體當中編寫的是業務邏輯代碼,完成某個特定功能,在方法體中的代碼遵循自上而下的順序依次逐行執行。在方法體中處理業務邏輯代碼的時候需要數據,數據來源就是這些形參。
三、方法定義之後,如何調用?
//方法必須調用才能執行,語法是什麼?
類名.方法名(實際參數列表);
注意:(1)實際參數和形式參數的類型必須要一一對應,個數要對應。
(2)如果返回值是int類型,可以用double接收嗎?可以的,因爲Int爲小容量,double爲大容量,自動類型轉換。
(3)當一個方法有返回值的時候,可以不接受嗎?可以,你可以返回值,我可以選擇不這個值。返回之後內存馬上釋放,因爲沒有變量去接受。
Methord.sum(100,200);
四、在調用方法的時候類名什麼時候省略掉?
在同一個類中,A方法調用B方法的時候,類名可以省略。如果不在同一個類中,類名.不可以省略。
Public class MethodTest{
Public static void main(String [] args){
sayHello();
Myclass.sayHello()
}
Public void sayHello(){
System.out.println("Hello");
}
}
Class Myclass{
Public void sayHello(){
System.out.println("Hello");
}
}
五、方法執行過程中內存如何變化的
(1)JVM
首先警告編譯階段形成了.class文件,然後有類加載器classloader去加載.class文件到JVM虛擬機的方法區當中,雖然叫方法區,但是和方法沒有半毛錢關係,虛擬機尋找main方法,從main方法中開始執行,main方法的內存會分配到棧中。
(2)方法執行過程中內存是如何變化的:
方法調用時:壓棧,分配空間。
方法結束時:彈棧,釋放空間。
(3)棧中存儲的是什麼?
棧中存儲的是方法執行的空間和存儲方法的局部變量。
六、方法重載
(一)沒有方法重載的代碼
public int sum(int a,int b ){
int sum = 0 ;
sum = a+b;
return sum ;
}
public double sum1(double a ,double b){
double sum = 0;
sum = a+b;
return sum;
}
沒有方法重載的代碼的缺點:
(1)代碼不美觀
(2)程序員需要記憶更多的方法名稱,比較累。
如果使用方法重載機制,解決之前的兩個缺點:
(1)代碼整齊美觀
(2)"功能相似"的,可以讓"方法名相同",更易於以後的代碼編寫。
(二)什麼時候會考慮方法重載?
在同一個類當中,如果"功能1"和"功能2"他們的功能是相似的,那麼可以考慮將他們的方法名一致,這樣代碼既美觀,又便於後期的代碼編寫。
(三)什麼時候代碼會發生方法重載?
條件1:在同一個類當中。
條件2:方法名相同
條件3:參數列表不同
參數的個數不同算不同,參數的類型不同算不同,參數的順序不同算不同。
(四)方法重載和返回值類型沒有關係,同時也和修飾符列表沒有關係。
Public static int m5(){
Return 1;
}
Public static double m5(){
Return 0.5;
}
Int m6(){
}
Public static double m6(){
Return 0.5;
}
七、方法的遞歸
(1)什麼是方法的遞歸?
方法自己調用自己,這就是方法遞歸。
(2)當遞歸時程序沒有結束條件,一定會發生棧溢出錯誤,所以遞歸一定要有結束條件。
(3)如果遞歸是有結束條件,就一定不會發生棧溢出錯誤嗎?
不一定。有可能遞歸的太深了,導致內存不夠用了。
(4)在實際開發中,如果有一天遇到了StackOverflowError,你怎麼解決這個問題?
首先,第一步:
先檢查遞歸的結束條件對不對,如果遞歸的結束條件不對,必須對條件進一步的修改,直到正確爲止。
第二步:如果遞歸的條件沒有問題,怎麼辦?
這個時候可以調整JVM的棧內存初始化大小,可以將棧內存的空間調整的大一點。
第三部:調整了大小,如果運行還有錯誤,只能繼續擴大棧的內存大小。
八、判斷以下方法是否合格?
Public class MyClass{
Public static int main(String [] args){
Boolean flag = true;
If(flag){
System.out.println("哈哈哈");
}
}
}
分析:編譯器不會去判斷flag是不是true,他只是認爲flag是boolean類型的,if語句有可能執行也有可能不執行,不執行的話,就沒有辦法返回return了,所以會報錯。
(2)如果我們在return後面寫值呢?
因爲在reurn後面寫值就會無法訪問了。
九、總結
我個人感覺方法就是爲了方便程序員開發,對代碼進行封裝的一種機制,這樣做有利於對代碼的複用,減少內存的開銷,其實它和數學的函數很相似,都是有一種映射關係在裏面,它是接受變量,變量又是存儲數據的,同時方法裏面可以寫控制語句,方法名又是標識符,說到底就是把變量,標識符,控制語句等的一種雜燴。同時根本上是對數據的一種處理。