Java 基礎(chǔ) 03. Java 方法

1. 何謂方法

  • Java 方法是語句的集合得滤,它們在一起執(zhí)行一個功能。

    • 方法是解決一類問題的步驟的有序組合爪膊;
    • 方法包含于類或?qū)ο笾校?/li>
    • 方法在程序中被創(chuàng)建,在其他地方被引用砸王。
  • 設(shè)計方法的原則:方法的本意是功能塊推盛,就是實現(xiàn)某個功能的語句塊的集合。我們設(shè)計方法的時候谦铃,最好保持方法的原子性耘成,就是 一個方法只完成 1 個功能,這樣利于我們后期的擴展驹闰。

    package github.method;
    
    public class Demo01 {
        // main方法
        public static void main(String[] args) {
            int sum = add(1, 2);
            System.out.println(sum);
        }
        // 加法
        public static int add(int a,int b){
            return a+b;
        }
    }
    

2. 方法的定義及調(diào)用

  • Java 的方法類似于其它語言的函數(shù)瘪菌,是一段用來完成特定功能的代碼片段,一般情況下嘹朗,定義一個方法包含以下語法:

  • 方法包含一個方法頭和一個方法體师妙。下面是一個方法的所有部分:

    • 修飾符:是可選的,告訴編譯器如何調(diào)用該方法屹培。定義了該方法的訪問類型默穴。

    • 返回值類型:方法可能會返回值。 returnValueType 是方法返回值的數(shù)據(jù)類型褪秀。有些方法執(zhí)行所需的操作壁顶,但沒有返回值。在這種情況下溜歪, returnValueType 是關(guān)鍵字 void若专。

    • 方法名:是方法的實際名稱。方法名和參數(shù)表共同構(gòu)成方法簽名蝴猪。(首字母小寫调衰,駝峰命名)

    • 參數(shù)類型:參數(shù)像是一個占位符膊爪。當(dāng)方法被調(diào)用時,傳遞值給參數(shù)嚎莉。這個值被稱為實參或變量米酬。參數(shù)列表是指方法的參數(shù)類型、順序和參數(shù)的個數(shù)趋箩。參數(shù)是可選的赃额,方法可以不包含任何參數(shù)。

      • 形式參數(shù):在方法被調(diào)用時用于接收外界輸入的數(shù)據(jù)叫确。
      • 實參:調(diào)用方法時實際傳給方法的數(shù)據(jù)跳芳。
    • 方法體:方法體包含具體的語句,定義該方法的功能竹勉。

    修飾符 返回值類型 方法名(參數(shù)類型 參數(shù)名){
        ...
        方法體
        ...
        return 返回值;
    }
    
  • 調(diào)用方法:對象名.方法名(實參列表)

  • Java 支持兩種調(diào)用方法的方式飞盆,根據(jù)方法是否返回值來選擇,當(dāng)方法返回一個值的時候次乓,方法調(diào)用通常被當(dāng)做一個值吓歇。例如:

    int larger = max(30,40);
    
  • 如果方法返回值是 void ,方法調(diào)用一定是一條語句票腰。

    System.out.println("Hello,World!");
    
  • 示例:

    package github.method;
    
    public class Demo02 {
        public static void main(String[] args) {
            int max = max(10, 20);
            System.out.println(max);
        }
        // 比大小
        public static int max(int num1,int num2){
            int result = 0;
            if(num1==num2){
                System.out.println("num1==num2");
                return 0;   // 終止方法
            }
            if(num1>num2){
                result = num1;
            } else {
                result = num2;
            }
            return result;
        }
    }
    

    值傳遞 (Java)和引用傳遞

    • 方法可以修改 傳遞引用所對應(yīng)的 變量值城看,而 不能修改傳遞值調(diào)用 所對應(yīng)的變量值,這句話相當(dāng)重要杏慰,這是按值調(diào)用與引用調(diào)用的根本區(qū)別析命,以下為分析:
    • 按值調(diào)用 (call by value) 表示方法接受的時調(diào)用者 提供的值
    package github.method;
    
    public class Demo03 {
        private static int x = 10;
    
        public static void updateValue(int value) {
            value = 3 * value;
            System.out.println("value的值:" + value);
        }
    
        public static void main(String[] args) {
            System.out.println("調(diào)用前的值:" + x);
            updateValue(x);
            System.out.println("調(diào)用后的值:" + x);
        }
    }
    

分析:

  1. value 被初始化逃默,為 x 值的一個拷貝(也就是10)

  2. value 被乘以 3 后等于30鹃愤,但注意此時 x 的值仍為10!

  3. 這個方法結(jié)束后完域,參數(shù)變量 value 不再使用软吐,被回收。

結(jié)論:當(dāng)傳遞方法參數(shù)類型為基本數(shù)據(jù)類型(數(shù)字以及布爾值)時吟税,一個方法是不可能修改一個基本數(shù)據(jù)類型的參數(shù)凹耙。

  • 按引用調(diào)用 (call by reference)

  • 按引用調(diào)用,則表示方法接收的是 調(diào)用者提供的變量地址 (如果是 C 語言肠仪,就是指針肖抱,Java 并沒有指針的概念)

  • 當(dāng)然 Java 中除了 基本數(shù)據(jù)類型,還有 引用數(shù)據(jù)類型异旧,也就是 對象引用意述,那么對于這種數(shù)據(jù)類型又是怎么樣的情況呢?我們還是一樣先來看一個例子:

    • 先聲明一個 User 對象類型:
    package github.method;
    
    public class User {
        private String name;
        private int age;
        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    • 執(zhí)行 class
    package github.method;
    
    public class Test02 {
        public static void updateUser(User student) {
            student.setName("Liu");
            student.setAge(22);
        }
    
        public static void main(String[] args) {
            User user = new User("USER", 20);
            System.out.println("調(diào)用user前的值:" + user.getName() + "," + user.getAge());
            updateUser(user);
            System.out.println("調(diào)用user后的值:" + user.getName() + "," + user.getAge());
        }
    }
    
    

    分析一下這個過程:

    分析:

    1. student 變量被初始化為 user 值的拷貝,這里是一個對象的引用荤崇。
    2. 調(diào)用 student 變量的 set 方法作用在這個引用對象上拌屏,user 和 student 同時引用的 User 對象內(nèi)部值 被修改。
    3. 方法結(jié)束后术荤,student 變量不再使用倚喂,被釋放,而 user 還是沒有變瓣戚,依然指向User 對象端圈。

    結(jié)論:顯然,User 的值被改變了子库,但是這是將最開始所對應(yīng)得值改變了舱权,把 User 的本身屬性改變了,才會進(jìn)行值得變化刚照,雖然看似是按引用傳遞值,但是實際上是將值改變了喧兄。

    • 下面通過一個反例來說明:
    package github.method;
    
    /**
     * java 中的按值調(diào)用
     */
    public class Test03 {
        /**
         * 交換兩個對象
         *
         * @param x
         * @param y
         */
        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", 26);
            User stu = new User("stu", 18);
            System.out.println("調(diào)用前user的值:" + user.getName() + "," + user.getAge());
            System.out.println("調(diào)用前stu的值:" + stu.getName() + "," + stu.getAge());
            swap(user, stu);
            System.out.println("調(diào)用后user的值:" + user.getName() + "," + user.getAge());
            System.out.println("調(diào)用后stu的值:" + stu.getName() + "," + stu.getAge());
        }
    }
    
  • 通過程序發(fā)現(xiàn):user 和 stu 的值并沒有發(fā)生變化无畔,也就是方法并沒有改變存儲在變量 user 和 stu 中的對象引用。swap 方法的參數(shù) x 和 y 被初始化為兩個對象引用的拷貝吠冤,這個方法交換的是這兩個拷貝的值而已浑彰,最終,所做的事都是白費力氣罷了拯辙。在方法結(jié)束后 x郭变,y 將被丟棄,而原來的變量 user 和 stu 仍然引用這個方法調(diào)用之前所引用的對象涯保。

  • 這個過程也充分說明了诉濒,Java 程序設(shè)計語言對 對象 采用的不是引用調(diào)用,實際上是 對象引用進(jìn)行的是值傳遞夕春,當(dāng)然在這里我們可以簡單理解為這就是按值調(diào)用和引用調(diào)用的區(qū)別未荒,而且必須明白即使 Java 函數(shù)在傳遞引用數(shù)據(jù)類型時,也只是拷貝了引用的值罷了及志,之所以能修改引用數(shù)據(jù)是因為它們同時指向了一個對象片排,但這仍然是按值調(diào)用而不是引用調(diào)用。

    總結(jié)

    • 一個方法不能修改一個基本數(shù)據(jù)類型的參數(shù)(數(shù)值型和布爾型)速侈。

    • 一個方法可以修改一個引用所指向的對象狀態(tài)率寡,但這仍然是按值調(diào)用而非引用調(diào)用。

    • 上面兩種傳遞都進(jìn)行了值拷貝的過程倚搬。

3. 方法重載

  • 重載就是在一個類中冶共,有相同的函數(shù)名稱,但形參不同的函數(shù)。

  • 方法的重載的規(guī)則

    • 方法名稱必須相同比默。
    • 參數(shù)列表必須不同(個數(shù)不同幻捏、或類型不同、參數(shù)排列順序不同等)
    • 方法的返回類型可以相同也可以不相同命咐。
    • 僅僅返回類型不同篡九,不足以成為方法的重載。
  • 實現(xiàn)理論:

    • 方法名稱相同時醋奠,編譯器會根據(jù)調(diào)用方法的參數(shù)個數(shù)榛臼、參數(shù)類型等去逐個匹配,以選擇對應(yīng)的方法窜司,如果匹配失敗沛善,則編譯器報錯。
    package github.method;
    
    public class Demo02 {
        public static void main(String[] args) {
            int max = max(10, 20);
            System.out.println(max);
            double max2 = max(10.0, 20.0);
            System.out.println(max2);
        }
    
        // 比大小
        public static int max(int num1, int num2) {
            int result = 0;
            if (num1 == num2) {
                System.out.println("num1==num2");
                return 0;   // 終止方法
            }
            if (num1 > num2) {
                result = num1;
            } else {
                result = num2;
            }
            return result;
        }
    
        // 比大小   方法重載塞祈,參數(shù)類型不同
        public static double max(double num1, double num2) {
            double result = 0;
            if (num1 == num2) {
                System.out.println("num1==num2");
                return 0;   // 終止方法
            }
            if (num1 > num2) {
                result = num1;
            } else {
                result = num2;
            }
            return result;
        }
    }
    
    package github.method;
    
    public class Demo01 {
        // main方法
        public static void main(String[] args) {
            int sum = add(1, 2);
            System.out.println(sum);
            int sum2 = add(1, 2, 3);
            System.out.println(sum2);
        }
        // 加法
        public static int add(int a,int b){
            return a+b;
        }
        // 方法重載金刁,參數(shù)個數(shù)不同
        public static int add(int a,int b,int c){
            return a+b+c;
        }
    }
    

4. 命令行傳參

package github.method;

public class Demo03 {
    public static void main(String[] args) {
        // args.length 數(shù)組長度
        for(int i=0;i < args.length;i++){
            System.out.println("args[" + i + "]:" + args[i]);
        }
    }
}

5. 可變參數(shù)

  • JDK 1.5 開始,Java 支持傳遞同類型的可變參數(shù)給一個方法议薪。
  • 在方法聲明中尤蛮,在指定參數(shù)類型后加一個省略號(...)。
  • 一個方法中只能指定一個可變參數(shù)斯议,它必須是方法的最后一個參數(shù)产捞。任何普通的參數(shù)必須在它之前聲明。
package github.method;

public class Demo04 {
    public static void main(String[] args) {
        Demo04 demo04 = new Demo04();    // 另一種調(diào)用方式:對象
        demo04.test(1,2,3,4,5);
    }
    public void test(int... i){
        System.out.println(i[0]);
        System.out.println(i[1]);
        System.out.println(i[2]);
        System.out.println(i[3]);
        System.out.println(i[4]);
    }
}
package github.method;

public class Demo05 {
    public static void main(String[] args) {
        // 調(diào)用可變參數(shù)的方法
        printMax(34,3,3,2,56.5);
        printMax(new double[]{1,2,3});
    }
    public static void printMax(double... numbers){
        // 判斷是否有參數(shù)傳入
        if(numbers.length==0){
            System.out.println("沒有數(shù)據(jù)哼御!");
            return;
        }
        double result = numbers[0];
        // 排序
        for(int i=1;i<numbers.length;i++){
            if(numbers[i] > result){
                result = numbers[i];
            }
        }
        System.out.println("The max Value is " + result);
    }
}

6. 遞歸

  • A 方法調(diào)用 B 方法坯临,我們很容易理解!

  • 遞歸就是:A 方法調(diào)用 A 方法恋昼!就是自己調(diào)用自己看靠。

  • 利用遞歸可以用簡單的程序來解決一些復(fù)雜的問題。它通常把一個大型復(fù)雜的問題層層轉(zhuǎn)化為一個與原問題相似的規(guī)模較小的問題來求解液肌,遞歸策略只需少量的程序就可描述岀解題過程所需要的多次重復(fù)計算衷笋,大大地減少了程序的代碼量。遞歸的能力在于用有限的語句來定義對象的無限集合矩屁。

  • 遞歸結(jié)構(gòu)包括兩個部分:

    • 遞歸頭:什么時候不調(diào)用自身方法辟宗。如果沒有頭,將陷入死循環(huán)吝秕;
    • 遞歸體:什么時候需要調(diào)用自身方法泊脐。
    package github.method;
    import java.util.Scanner;
    
    public class Demo05 {
        // 5! 5*4*3*2*1
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("請輸入一個數(shù):");
            int number = scanner.nextInt();
            int test = test(number);
            System.out.println(number + "的階乘:" + test);
            scanner.close();
        }
        public static int test(int n){
            if(n==1){
                return 1;
            }else{
                return n*test(n-1);
            }
        }
    }
    
  • 寫一個計算器,要求實現(xiàn)加減乘除功能烁峭,井且能夠循環(huán)接收新的數(shù)據(jù)容客,通過用戶交互實現(xiàn)秕铛。

    package github.method;
    
    import java.util.Scanner;
    
    public class Demo06 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            double sum = 0;
            while (true) {
                System.out.println("請輸入第一個整數(shù):");
                double a = scanner.nextDouble();
                System.out.println("請輸入第二個整數(shù):");
                double b = scanner.nextDouble();
                System.out.println("請輸入要運算的字符(+:表示加法,-:表示減法,*:表示乘法,/:表示除法)");
                String temp = scanner.next();
                switch (temp) {
                    case "+":
                        sum = a + b;
                        System.out.println("結(jié)果是:" + sum);
                        continue;
                    case "-":
                        sum = a - b;
                        System.out.println("結(jié)果是:" + sum);
                        continue;
                    case "*":
                        sum = a * b;
                        System.out.println("結(jié)果是:" + sum);
                        continue;
                    case "/":
                        sum = a / b;
                        System.out.println("結(jié)果是:" + sum);
                        continue;
                    default:
                        System.out.println("請輸入正確的運算符號!缩挑!");
                }
            }
        }
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末但两,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子供置,更是在濱河造成了極大的恐慌谨湘,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥丧,死亡現(xiàn)場離奇詭異紧阔,居然都是意外死亡侍匙,警方通過查閱死者的電腦和手機述么,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來速蕊,“玉大人物遇,你說我怎么就攤上這事乖仇。” “怎么了询兴?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵乃沙,是天一觀的道長。 經(jīng)常有香客問我蕉朵,道長崔涂,這世上最難降的妖魔是什么阳掐? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任始衅,我火速辦了婚禮,結(jié)果婚禮上缭保,老公的妹妹穿的比我還像新娘汛闸。我一直安慰自己,他們只是感情好艺骂,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布诸老。 她就那樣靜靜地躺著,像睡著了一般钳恕。 火紅的嫁衣襯著肌膚如雪别伏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天忧额,我揣著相機與錄音厘肮,去河邊找鬼。 笑死睦番,一個胖子當(dāng)著我的面吹牛类茂,可吹牛的內(nèi)容都是我干的耍属。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼巩检,長吁一口氣:“原來是場噩夢啊……” “哼厚骗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兢哭,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤领舰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厦瓢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體提揍,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年煮仇,在試婚紗的時候發(fā)現(xiàn)自己被綠了劳跃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡浙垫,死狀恐怖刨仑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夹姥,我是刑警寧澤杉武,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站辙售,受9級特大地震影響轻抱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旦部,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一祈搜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧士八,春花似錦容燕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝗茁,卻和暖如春醋虏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哮翘。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工颈嚼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人忍坷。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓粘舟,卻偏偏與公主長得像熔脂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柑肴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容