JavaSE學習筆記(四)——Java中的方法

一、  Java中的方法

   需求:求整數10和整數3的乘積,然後在求整數2000和整數300的乘積。

public class MethodTest01 {

 

       public  static void main(String[] args){

             

              int  i = 10;

              int  j = 3;

              int  k = i * j;

              System.out.println("i  * j = " + k);

             

              int  l = 2000;

              int  m = 300;

              int  n = l * m;

              System.out.println("l * m ="  + n);

       }

}

 

   功能已經實現,但是存在的問題是,兩段代碼完成的功能相同,數據的類型也相同。只是具體的數據不同。並且代碼重複使用了兩次,雖然實現了功能,但缺點是相同功能的代碼不能實現重用。所以在Java中可以使用方法來實現相同功能的代碼塊重複利用。

1.1           方法的定義

   方法就是一段代碼片段,可以完成特定的功能,並且可以重複利用。定義方法的語法格式如下。

[方法修飾列表] 返回值類型 方法名(方法形式參數列表){

方法體;

}

 

   方法修飾符:可以是publicprotectedprivateabstractstaticfinalsynchronized。注意:其中publicprotectedprivate不能同時存在,只能是其中之一。

   方法的返回值類型:可以是Java語言中的任何一種數據類型(基本數據類型和引用數據類型)。如果該方法執行結束之後,沒有任何返回值,那麼定義方法的時返回值類型爲void。如果存在返回值,使用 return語句。Return語句後面不能再執行語句,因爲不可能會執行到,編譯不能通過。

   方法名:合法的標識符。

   方法參數列表:定義方法時可以有參數,也可以沒有參數,如果有多個參數,參數之間要使用逗號進行分隔。

   定義一個方法實現上面的需求。

public class MethodTest02 {

 

       public  static void main(String[] args){

         // 調用static修飾的靜態方法需要使用類名.的方式

              //  直接調用方法並傳入需要乘積的參數

              MethodTest02.method(10,  3);

              MethodTest02.method(2000,  300);

       }

       //  static修飾的方法是靜態方法

       public  static void method(int i,int j){

              int  product = i * j;

              System.out.println("i  * j = " + product);

       }

}

 

   定義方法。

public class MethodTest03 {

 

       public  static void main(String[] args){

              //  調用方法,靜態方法直接使用類名.的方式進行調用

              MethodTest03.method01();

         // 調用方法時同時傳遞參數給方法

              MethodTest03.method02("張三");

         // 調用有返回值的方法

              int  product = MethodTest03.method03(20, 30);

         System.out.println("product = " + product);

       }

       //  定義方法

// public 公共的,外面的類可以調用

// static 方法是靜態的

// void 沒有返回值

// method01 方法名

// 方法沒有參數

       public  static void method01(){

              System.out.println("Hello  Java");

       }

       //  方法帶有一個String類型的參數

     // 參數name是局部變量,作用域在方法體內

       public  static void method02(String name){

              System.out.println(name);

       }

       //  方法有兩個int類型的參數

     // 方法有返回值,返回值類型爲int類型

       public  static int method03(int i,int j){

              int  product = i * j;

         // 方法有返回值,必須有return語句,並且返回值的類型與方法定義的類型

         // 相同,否則編譯不能通過

              return  product;

         // return 語句後面不能存在其他語句,否則編譯不能通過

              //  System.out.println("product = " + product);

       }

}

1.2           方法的調用

   靜態方法的調用原則。在同一個類中,調用靜態方法可以使用類名.的方式進行調用,也可以直接使用方法名進行調用。

public class MethodTest04 {

 

       public  static void main(String[] args){

              //  在同一個類中,可以直接使用方法名調用靜態方法

              method02();

         // 也可以使用類名的方式調用靜態方法

              MethodTest04.method02();

         // 不在同一個類中的靜態方法必須使用類名.的方式進價調用

         A.method03();

       }

      

       public  void method01(){

              method02();

              MethodTest04.method02();

       }

      

       public  static void method02(){

              System.out.println("Hello  Java");

       }

}

 

class A{

     // A類中定義的靜態方法

       public  static void method03(){

              System.out.println("A  method03()");

       }

}

 

   調用帶參數的靜態方法,需要傳遞相應類型的參數。通常情況下調用有返回值的方法就是要取得返回值,返回值變量的類型必須與方法返回值的類型相同。在方法中,return語句執行則方法結束,執行流程放回到方法調用處。

public class MethodTest05 {

 

       public  static void main(String[] args){

         // 調用有返回值的靜態方法

         int success = method01(true);

              //  返回值類型是方法的返回值類型

         // 參數的類型必須是方法定義的參數類型,並且順序相同

              int  product = method02(10,3);

              System.out.println("product:  " + product);

              //  不在同一個類中,必須採用類名.的方式調用靜態方法

              A.method03("張三");

       }

     // 靜態方法

     public static int method01(boolean b){

              /*

              if(b){

                     return  1;

              }else{

                     return  0;

              }

              */

             

              if(b){

                     return  1;

              }

             

              return  0;

       }

       //  靜態方法,返回值類型是int型,兩個參數。形式參數類型是int

       public  static int method02(int i,int j){

         // 返回值的類型必須是方法定義的返回值類型

              return  i / j;

         //  return語句執行,方法結束,所以不能有語句在return後面,編譯不能通過

              //  System.out.println(i / j);

       }

}

 

class A{

     // 定義的靜態方法

       public  static void method03(String name){

              System.out.println("name:  " + name);

       }

}

 

   如何終止方法的執行,採用的方式是如果符合某種條件,使用return語句終止方法的執行。

public class MethodTest06 {

 

       public  static void main(String[] args){

             

              method01(11);

              method01(8);

       }

       //  靜態方法,沒有返回值,一個形式參數,類型是int

       public  static void method01(int i){

         // 如果參數值大於10終止方法執行

              if(i  > 10){

            // return語句執行,方法結束

                     return;

              }

             

              for(;i  <= 10;i++){

            if(i == 5){

               // break只是結束終止循環

               break;

            }

                     System.out.println("i  = " + i);

              }

        

         System.out.println("break後要執行的語句");

       }

}

 

   return語句的使用方式。

public class MethodTest07 {

 

       public  static void main(String[] args){

              //  靜態方法調用

              method01();

              String  info = method02();

         System.out.println(info);

       }

      

       public  static void method01(){

              //  方法沒有返回值,如果使用returnreturn後面不能存在語句

              //return;

              //  編譯可以通過,雖然最後的語句不會輸出

              if(true){

                     return;

              }

             

              System.out.println("HelloWord");

       }

      

     public static String method02(){

              //  如果方法有返回值,必須存在return語句,後面的值類型必須和返回類型

         // 相同,並且return語句後面不能跟其他語句

            //return  "HelloWord";

         // 這種方式可以,

            /*

            if(true){

                   return "HelloWord";

            }else{

                   return  "OK";

            }

            */

            // 這種方式可以

            if(true){

                   return  "HelloWord";

            }

           

            return "OK";

            // 方法有返回值,return語句一定是最後一條語句,否則編譯不能通過

            //System.out.println("HelloWord");

       }

}

 

1.3           方法的重載

   需求:定義三個方法,分別是int類型、double類型和long類型實現乘積的方法,方法有返回值。

public class MethodTest08 {

 

       public  static void main(String[] args){

             

              int  product1 = productInt(10,20);

              System.out.println(product1);

              double  product2 = productDouble(10.11,93.23);

              System.out.println(product2);

              long product3 = productLong(10L,20L);

              System.out.println(product3);

              //  注意:類型從小容量到大容量,自動類型轉換

              productInt(10,20);

              productDouble(10,20);

              productLong(10,20);

       }

      

       public  static int productInt(int i1,int i2){

             

              return  i1 * i2;

       }

      

     public static double productDouble(double d1,double d2){

             

            return d1 * d2;

       }

     

     public static long productLong(long l1,long l2){

           

            return l1 * l2;

     }

}

 

   上面的代碼實現了功能,但是存在的問題是每個方法的方法名稱不同,相同的是求兩個數值類型的值的乘積。另外,還需要記憶多個方法名,並且代碼不是特別易讀。如果方法實現的功能相同,只是參數類型或者參數的數量不同,可以採用方法重載的方式,如下例子。

public class MethodTest09 {

 

       public  static void main(String[] args){

             

              int  product1 = product(10,20);

              System.out.println(product1);

              double  product2 = product(10.11,93.23);

              System.out.println(product2);

              long  product3 = product(10L,20L);

              System.out.println(product3);

       }

      

       public  static int product(int i1,int i2){

             

              return  i1 * i2;

       }

      

     public static double product(double d1,double d2){

             

            return d1 * d2;

       }

     

     public static long product(long l1,long l2){

           

            return l1 * l2;

     }

}

 

   修改後,三個方法的方法名稱相同,參數類型不同,返回值類型不同,但是調用時只需要傳入不同類型的參數,不需要指定調用哪個方法,系統會根據參數的類型自動調用相應的方法並將結果返回。並且不需要記憶更多的方法名稱。

 

方法重載的條件。

1.方法重載只出現在同一個類中

2.方法名相同

3.方法的參數類型,個數,順序至少有一個不同

4.方法的返回類型可以不同(不依靠返回類型來區分重載)

5.方法的修飾符可以不同,因爲方法重載和修飾符沒有任何關係

public class MethodTest10 {

 

       public  static void main(String[] args){

             

       }

     // 方法重載必須在同一個類中

       //  參數類型不同,是方法重載

       public  static void m1(int i1,int i2){}

    public static void m1(double d1,double  d2){}

     // 參數數量不同,是方法重載

     public static void m2(int i1){}

     public static void m2(double d1,double d2){}

     // 參數順序不同,是方法重載

     public static void m3(int i1,double d1){}

     public static void m3(double d1,int i1){}

     // 參數類型相同,參數個數相同,不是方法重載,是方法重複

     //public static void m4(int a){}

     //public static void m4(int b){}

// 參數類型和個數相同,返回值類型不同,不是方法重載,

// 方法重載和返回值類型無關

     //public static int m5(int i){}

     //public static void m5(int i){}

     // 參數相同,訪問修飾符不同,不是方法重載,方法重載和訪問修飾符無關

     //private static void m6(){}

     //public static void m6(){}

}

 

   方法重載舉例。

public class MethodTest11 {

 

       public  static void main(String[] args){

              //  sun提供的方法重載例子

              System.out.println(10);

              System.out.println(23.2);

              System.out.println(true);

              System.out.println('A');

       }

}

 

1.4           類、方法、屬性(靜態變量)的關係

   在一個類中,從類和成員的角度可分爲靜態的和成員的部分。靜態的部分可分爲靜態變量、靜態方法和靜態內部類等等。成員的部分可以分爲成員變量、成員方法和成員內部類等等。注意:也就是說,在類體中只存在兩部分內容,一是屬性(成員的或靜態的),二是方法(成員方法或靜態方法)或內部類。那麼可以執行的代碼只能存在與方法中,包括成員方法或靜態方法,所以,存在與方法中的代碼是爲了實現一個特定的功能,就像一個工廠生產特定的產品,方法的參數類似於工廠需要的生成原料,而方法的返回值相當於工廠生產出的產品。

public class MethodTest12 {

 

       //  類體

      

       //  成員屬性

       int  i = 10;

      

       //  靜態變量

       static  String country = "中國";

      

       //  成員方法

       public  void method01(int i){

              //  方法體

              //  可以執行的代碼

              //  將參數做一些特殊的處理

              System.out.println(i);

       }

      

     // 靜態方法

       public  static int method02(int i1,int i2){

              //  方法體

              //  可以執行的代碼

              //  實現特定功能,並返回特定的結果

              return  i1 + i2;

       }

      

       public  static void main(String[] args){

              //  方法體

              //  可以執行的代碼

              //  程序的執行入口方法

       }

}

 

1.5           調用方法的執行流程

1.5.1       棧的概念

   當通過Java命令執行一個程序時,會啓動一個JVMJava虛擬機進程,並創建程序運行環境,會創建程序運行的棧內存,下面的圖做了簡單的說明。

          

wKiom1f6KROzvpUBAAAXSQm5JTs396.png-wh_50


1.1.1       程序的執行過程

   下面通過一個程序說明程序的執行過程。

public class MethodTest13 {

      

       public  static void main(String[] args){

              //  調用method01()方法

              method01(10);

       }

       //  method01()方法調用method02()方法

       public  static void method01(int i){

              method02(i);

       }

       //  method02()方法調用method03()方法

       public  static void method02(int i){

              method03(i);

       }

      

       public  static void method03(int i){

              System.out.println("i:  " + i);

       }

     // method04()方法沒有被調用

     public static void method04(int i){

              System.out.println(i);

       }

}

 

   main()方法調用method01()方法,method01()方法調用method02()方法,method02()方法調用method03()方法,在method03()方法中將參數輸出。下面通過一個圖說明程序的執行流程。

   注意:當方法被調用時,纔會在內存中爲方法分配空間。如果只是定義了方法,但是沒有被調用,不會爲方法在內存中分配空間。方法被調用時,Java虛擬機會爲方法在棧內存中爲方法分配空間。方法被調用時會發生壓棧操作,當方法執行結束後會發生彈棧操作。

一、   遞歸

   方法的遞歸調用就是方法自身調用自身。通常在樹形結構訪問時用到,如:目錄的遞歸檢索,又如權限管理中權限目錄數的訪問等等。下面的例子是遞歸的簡單演示。

public class RecursionTest01 {

      

       public  static void main(String[] args){

              //  調用method01()方法

              method01(10);

       }

       //  方法method01()

       public  static void method01(int i){

         // 方法自己調用自己,無限調用下去沒有返回

              method01(i);

       }

}

 

在上面的例子中,因爲遞歸沒有結束的條件,所以每調用一次method01()方法,就會在內存中開闢空間,產生壓棧操作,但沒有出棧操作,不會釋放內存,會導致棧內存溢出錯誤!所以遞歸程序必須要有結束條件。

   不使用遞歸計算1~n整數的和。

public class RecursionTest02 {

      

       public  static void main(String[] args){

             

              int  sum = method01(10);

              System.out.println(sum);

       }

      

       public  static int method01(int n){

              int  sum = 0;

             

              for(int  i = 1;i <= n;i++){

                     sum  += i;

              }

             

              return  sum;

       }

}

 

   使用遞歸實現1~n的求和。

public class RecursionTest03 {

      

       public  static void main(String[] args){

             

              int  sum = sum(5);

              System.out.println(sum);

       }

      

       public  static int sum(int n){

         // 如果參數n等於1,直接返回

              if(n  == 1){

                     return  1;

              }else{

            // 否則,將參數n減一作爲參數調用自身,返回的值與參數n的和就是

            // 最終的結果。

                     return  n + sum(n - 1);

              }

       }

}

 

   上面程序的執行流程:

         

wKioL1f6KbezubBhAAA24viyv7k521.png



練習:

1. 採用遞歸的方式求1~n的偶數的和。

public class RecursionTest04 {

      

       public  static void main(String[] args){

             

              int  sum = sum(5);

              System.out.println(sum);

       }

      

       public  static int sum(int n){

              if(n  % 2 != 0){

                     n  -= 1;

              }

              if(n  == 2){

                     return  2;

              }else{

                     return  n + sum(n - 2);

              }

       }

}

 

2. 採用遞歸的方式求n!

public class RecursionTest05 {

      

       public  static void main(String[] args){

             

              int  sum = product(5);

              System.out.println(sum);

       }

      

       public  static int product(int n){

              if(n  == 1){

                     return  1;

              }else{

                     return  n * product(n - 1);

              }

       }

}

 

3. 不採用遞歸的方式實現n!。

public class RecursionTest06 {

      

       public  static void main(String[] args){

             

              int  sum = product(5);

              System.out.println(sum);

       }

      

       public  static int product(int n){

              int  product = 1;

              for(int  i = 1;i <= n;i++){

                     product  *= i;

              }

             

              return  product;

       }

}

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章