【JavaSE】3、方法
1.何謂方法
方法:解決一類問題的步驟的有序組合,包含於類或物件中;方法在程式中被建立,在其他地方被引用。
設計方法的原則:保持方法的原子性,就是一個方法只完成1個功能,這樣利於後期的擴充套件。
tips:System.out.println(),那麼它是什麼呢?呼叫系統類System中的標準輸出物件out的printIn方法。
2.方法的定義及呼叫
方法包含一個方法頭和一個方法體。
1、方法定義:
- 修飾符:可選的,告訴編譯器如何呼叫該方法。定義了該方法的訪問型別。如public。
- 返回值型別:是方法返回值的資料型別。有些方法沒有返回值,這時returnValueType是void。
- 方法名:是方法的實際名稱。方法名和引數表共同構成方法簽名。
- 引數:是可選的。形式引數:在方法被呼叫時用於接收外界輸入的資料。實參:呼叫方法時實際傳給方法的資料。
- 方法體:方法體包含具體的語句,定義該方法的功能。
- return:如果有返回值,return需要放在最後。還可被用來終止方法。
2、呼叫方法:物件名.方法名(實參列表)
Java支援兩種呼叫方法的方式,根據方法是否返回值來選擇:
-
當方法返回一個值的時候,方法呼叫通常被當做一個值。
-
如果方法返回值是void,方法呼叫一定是一條語句。
3.按值呼叫&按引用呼叫
java是按值呼叫。方法可以修改傳遞引用所對應的變數值,而不能修改傳遞值呼叫所對應的變數值,這句話相當重要,這是按值呼叫與引用呼叫的根本區別。
1、按值呼叫(call by value):表示方法接受的是——呼叫者提供的值。
package github.method; public class HomeWork01 { private static int x = 10; public static void updataeValue(int value){ value = 3 * value; System.out.println("value的值:" + value); } public static void main(String[] args) { System.out.println("呼叫前的值:" + x); // 10 updataeValue(x); // 30,方法中value被初始化為x的一個拷貝,方法結束後,value被回收。 System.out.println("呼叫後的值:" + x); // 10 } }
結論:當傳遞方法引數型別為基本資料型別(數字以及布林值)時,一個方法是不可能修改一個基本資料型別的引數。
2、按引用呼叫(call by reference):表示方法接收的是——呼叫者提供的變數地址(C語言是指標,當然java沒有指標的概念)
java中除了基本資料型別還有引用資料型別
,也就是物件引用
,對於這種資料型別是什麼情況呢?看下面例子:
// 一、宣告一個User物件型別
package github.method;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 二、執行class
package github.method;
public class HomeWork02 {
public static void updateUser(User student){
student.setName("subeiLY"); // 2、student的setName作用在引用物件上,User物件內部值被修改。
}
public static void main(String[] args) {
User user = new User("SUBEI");
System.out.println("呼叫user前:" + user.getName()); // SUBEI
updateUser(user); // 1、student變數被初始化為user值的拷貝,這裡是一個物件的引用
// 3、updateUser方法結束後,student被釋放,但user還沒有變,依然指向User物件。
System.out.println("呼叫user後:" + user.getName()); // subeiLY
}
}
結論:User的值被改變了,但這是將最開始所對應得值改變了,把User的本身屬性改變了,才會進行值得變化,雖然看似是按引用傳遞值,但是實際上是將值改變了。
到這裡可能有些蒙逼,下面通過一個反例來說明:
package github.method;
public class HomeWork03 {
public static void swap(User x,User y){
User temp = x;
x = y;
y = temp;
}
public static void main(String[] args) {
User user = new User("user");
User stu = new User("stu");
System.out.println("呼叫前user:"+ user.getName()); // user
System.out.println("呼叫前stu:"+ stu.getName()); // stu
swap(user, stu); // x、y被初始化為兩個物件引用的拷貝,方法並沒有改變儲存在變數user和stu中的物件引用
System.out.println("呼叫後user:"+ user.getName()); // user
System.out.println("呼叫後stu:"+ stu.getName()); // stu
}
}
這個過程說明了java對物件採用的不是引用呼叫,而是物件引用進行的是值傳遞,這裡可以簡單理解為這就是按值呼叫和引用呼叫的區別。
必須明白即使java函式在傳遞引用資料型別時,只是拷貝了引用的值,之所以能修改引用資料是因為它們同時指向了一個物件,但這仍然是按值呼叫而不是引用呼叫。
總結:
- 一個方法不能修改一個基本資料型別的引數(數值型和布林型)。
- 一個方法可以修改一個引用所指向的物件狀態,但這仍然是按值呼叫而非引用呼叫。
- 上面兩種傳遞都進行了值拷貝的過程。
4.方法過載
過載就是在一個類中,有相同的函式名稱,但形參不同的函式。
1、方法的過載的規則:方法名稱必須相同。引數列表必須不同(個數不同,或型別不同,引數排列順序不同等)。方法的返回型別可以相同也可以不相同。
實現理論:方法名稱相同時,編譯器會根據呼叫方法的引數個數、引數型別等去逐個匹配,以選擇對應的方法,如果匹配失敗,則編譯器報錯。
tips:命令列傳參——執行一個程式時傳遞給它訊息,這要靠傳遞命令列引數給main()函式實現。(在檔案所在目錄編譯java檔案,在src下執行class檔案)
2、可變引數
JDK1.5開始,Java支援傳遞同類型的可變引數(不定項)給一個方法。
在方法宣告中,在指定引數型別後加一個省略號(...)。一個方法中只能指定一個可變引數,它必須是方法的最後一個引數。任何普通的引數必須在它之前宣告。
public void test(int... i){}
5.總結:
方法的呼叫:
靜態方法:可以通過類直接呼叫,在類載入時載入,不能呼叫非靜態方法。
非靜態方法:通過例項化物件呼叫
public class Demo {
public static void main(String[] args) {
Student1.say(); // 通過類呼叫靜態方法(static)
// Student2.say(); 會報錯,不能通過類直接呼叫非靜態方法(public)
Student2 student2 = new Student2(); // 通過例項化物件呼叫非靜態方法(public)
student2.say();
}
}
public class Student1 {
public static void say(){
System.out.println("學生說話了");
}
}
public class Student2 {
public void say(){
System.out.println("學生說話了");
}
}