1. 程式人生 > 其它 >【JavaSE】3、方法

【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("學生說話了");
    }
}