Javaメソッド


前の章では System.out.println() をよく使用しましたが、それは何でしょうか?

println()はメソッド(Method)、Systemはシステムクラス(Class)、outは標準出力オブジェクト(Object)です。この文の使用法は、システム クラス System 内の標準出力オブジェクト内のメソッド println() を呼び出すことです。

では、その方法とは何でしょうか?

Java メソッドは、一緒に機能を実行するステートメントのコレクションです。

  • メソッドは、ある種の問題を解決するためのステップの順序付けられた組み合わせです

  • メソッドはクラスまたはオブジェクトに含まれています

  • メソッドはプログラム内で作成され、他の場所で参照されます


メソッドの定義

通常、メソッドの定義には次の構文が含まれます:

修饰符 返回值类型 方法名 (参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}

メソッドにはメソッド ヘッダーとメソッド本体が含まれます。以下にメソッドのすべての部分を示します:

  • 修飾子: 修飾子はオプションであり、メソッドの呼び出し方法をコンパイラに指示します。このメソッドのアクセス タイプを定義します。

  • 戻り値の型: メソッドは値を返す場合があります。 returnValueType はメソッドの戻り値のデータ型です。一部のメソッドは必要な操作を実行しますが、値を返しません。この場合、returnValueType はキーワード void です。

  • メソッド名: はメソッドの実際の名前です。メソッド名とパラメータ リストが一緒になってメソッド シグネチャを形成します。

  • パラメータの種類: パラメータはプレースホルダーのようなものです。メソッドが呼び出されると、値がパラメータに渡されます。この値は実パラメータまたは実変数と呼ばれます。パラメータ リストは、メソッドのパラメータのタイプ、順序、および数を指します。パラメータはオプションであり、メソッドにパラメータを含めることはできません。

  • メソッド本体: メソッド本体には、メソッドの機能を定義する特定のステートメントが含まれます。

12-130Q1220955916.jpg

例:

public static int age(int birthday){...}

複数のパラメータを指定できます:

static float interest(float principal, int year){...}

注: 他の言語では、メソッドはプロシージャと関数を指します。 void 以外の戻り値を返すメソッドは関数と呼ばれ、void 戻り値を返すメソッドはプロシージャと呼ばれます。

次のメソッドには、2 つのパラメーター num1 と num2 が含まれており、これら 2 つのパラメーターの最大値を返します。

/** 返回两个整型变量数据的较大值 */
public static int max(int num1, int num2) {
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;

   return result; 
}

メソッド呼び出し

Java はメソッドを呼び出す 2 つの方法をサポートしており、メソッドが値を返すかどうかに応じて選択します。

プログラムがメソッドを呼び出すと、プログラムの制御は呼び出されたメソッドに渡されます。呼び出されたメソッドの return ステートメントが実行されるか、メソッド本体の閉じ括弧に到達すると、制御がプログラムに返されます。

メソッドが値を返す場合、通常、メソッド呼び出しは値として扱われます。例:

int larger = max(30, 40);

メソッドの戻り値が void の場合、メソッド呼び出しはステートメントである必要があります。たとえば、メソッド println は void を返します。次の呼び出しはステートメントです:

System.out.println("Welcome to Java!");

Example

次の例は、メソッドを定義する方法とそれを呼び出す方法を示しています:

public class TestMax {
   /** 主方法 */
   public static void main(String[] args) {
      int i = 5;
      int j = 2;
      int k = max(i, j);
      System.out.println("The maximum between " + i +
                    " and " + j + " is " + k);
   }

   /** 返回两个整数变量较大的值 */
   public static int max(int num1, int num2) {
      int result;
      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result; 
   }
}

上記の例のコンパイルと実行結果は次のとおりです:

The maximum between 5 and 2 is 5

このプログラムには main メソッドと max メソッドが含まれています。 Main メソッドは JVM によって呼び出されます。それ以外は、main メソッドは他のメソッドと変わりません。

main メソッドのヘッダーは変更されていません。この例では、修飾子 public と static があり、void 型の値を返し、メソッド名は main で、String[] 型のパラメーターを受け取ります。 String[] は、パラメータが文字列配列であることを示します。


voidキーワード

このセクションでは、voidメソッドを宣言して呼び出す方法について説明します。

次の例では、printGrade というメソッドを宣言し、それを呼び出して指定されたスコアを印刷します。

public class TestVoidMethod {

   public static void main(String[] args) {
      printGrade(78.5);
   }

   public static void printGrade(double score) {
      if (score >= 90.0) {
         System.out.println('A');
      }
      else if (score >= 80.0) {
         System.out.println('B');
      }
      else if (score >= 70.0) {
         System.out.println('C');
      }
      else if (score >= 60.0) {
         System.out.println('D');
      }
      else {
         System.out.println('F');
      }
   }
}

上記例のコンパイル結果と実行結果は以下のとおりです。

C

ここでのprintGradeメソッドはvoid型のメソッドであり、値を返しません。

void メソッドの呼び出しはステートメントである必要があります。 したがって、main メソッドの 3 行目のステートメントとして呼び出されます。セミコロンで終わる他のステートメントと同様です。


パラメータを値で渡す

メソッドを呼び出すときは、パラメータリストで指定された順序でパラメータを指定する必要があります。

たとえば、次のメソッドはメッセージを n 回連続で出力します。

public static void nPrintln(String message, int n) {
  for (int i = 0; i < n; i++)
    System.out.println(message);
}

Example

次の例は、値渡しの効果を示しています。

このプログラムは、2 つの変数を交換するために使用されるメソッドを作成します。

public class TestPassByValue {

   public static void main(String[] args) {
      int num1 = 1;
      int num2 = 2;

      System.out.println("Before swap method, num1 is " +
                          num1 + " and num2 is " + num2);

      // 调用swap方法
      swap(num1, num2);
      System.out.println("After swap method, num1 is " +
                         num1 + " and num2 is " + num2);
   }
   /** 交换两个变量的方法 */
   public static void swap(int n1, int n2) {
      System.out.println("\tInside the swap method");
      System.out.println("\t\tBefore swapping n1 is " + n1
                           + " n2 is " + n2);
      // 交换 n1 与 n2的值
      int temp = n1;
      n1 = n2;
      n2 = temp;

      System.out.println("\t\tAfter swapping n1 is " + n1
                           + " n2 is " + n2);
   }
}

上記の例のコンパイル結果と実行結果は次のとおりです:

Before swap method, num1 is 1 and num2 is 2
        Inside the swap method
                Before swapping n1 is 1 n2 is 2
                After swapping n1 is 2 n2 is 1
After swap method, num1 is 1 and num2 is 2

2 つのパラメーターを渡して swap メソッドを呼び出します。興味深いことに、メソッドが呼び出された後、実際のパラメータの値は変化しません。


メソッドのオーバーロード

上記で使用されている max メソッドは、int 型のデータにのみ適用されます。しかし、2 つの浮動小数点型データの最大値を取得したい場合はどうすればよいでしょうか?

解決策は、次のコードに示すように、同じ名前でパラメータが異なる別のメソッドを作成することです:

public static double max(double num1, double num2) {
  if (num1 > num2)
    return num1;
  else
    return num2;
}

max メソッドを呼び出すときに int パラメータを渡すと、int パラメータの max メソッドが呼び出されます。

double パラメーターが渡された場合、double 型の max メソッド本体が呼び出されます。これはメソッドのオーバーロードと呼ばれます。

つまり、クラスの 2 つのメソッドは同じ名前を持ちますが、異なるパラメーター リストを持ちます。

Java コンパイラは、メソッド シグネチャに基づいてどのメソッドを呼び出す必要があるかを決定します。

メソッドのオーバーロードにより、プログラムがより明確になり、読みやすくなります。密接に関連したタスクを実行するメソッドは同じ名前を使用する必要があります。

オーバーロードされたメソッドには、異なるパラメーター リストが必要です。修飾子または戻り値の型のみに基づいてメソッドをオーバーロードすることはできません。


変数スコープ

変数のスコープとは、変数を参照できるプログラムの部分です。

メソッド内で定義された変数はローカル変数と呼ばれます。

ローカル変数のスコープは、その宣言から始まり、それを含むブロックの終わりで終わります。

ローカル変数は使用する前に宣言する必要があります。

メソッドのパラメータ範囲はメソッド全体をカバーします。パラメータは実際にはローカル変数です。

for ループの初期化部分で宣言された変数は、ループ全体でスコープを持ちます。

ただし、ループ本体内で宣言された変数の適用範囲は、その宣言からループ本体の最後までとなります。以下に示すような変数宣言が含まれています:

12-130Q1221013F0.jpg

メソッド内、ネストされていない別のブロック内で同じ名前のローカル変数を複数回宣言できますが、ネストされたブロック内でローカル変数を 2 回宣言することはできません。

コマンドラインパラメータの使用

メッセージを渡す前にプログラムを実行したい場合があります。これは、コマンド ライン引数を main() 関数に渡すことによって実現されます。

コマンドラインパラメータとは、プログラム実行時にプログラム名の直後に続く情報です。

次のプログラムは、すべてのコマンドラインパラメータを出力します:

public class CommandLine {

   public static void main(String args[]){ 
      for(int i=0; i<args.length; i++){
         System.out.println("args[" + i + "]: " +
                                           args[i]);
      }
   }
}

以下に示すように、このプログラムを実行します:

java CommandLine this is a command line 200 -100

実行結果は次のとおりです:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

コンストラクターメソッド

オブジェクトが作成されると、コンストラクター メソッド オブジェクトを初期化するために使用されます。コンストラクターは、それが属するクラスと同じ名前を持ちますが、コンストラクターには戻り値がありません。

コンストラクター メソッドは通常、クラスのインスタンス変数に初期値を割り当てたり、完全なオブジェクトを作成するために他の必要な手順を実行したりするために使用されます。

コンストラクターをカスタマイズするかどうかに関係なく、Java はすべてのメンバーを 0 に初期化するデフォルトのコンストラクターを自動的に提供するため、すべてのクラスにコンストラクターがあります。

独自のコンストラクターを定義すると、デフォルトのコンストラクターは無効になります。

以下はコンストラクター メソッドの使用例です:

// 一个简单的构造函数
class MyClass {
   int x;
   
   // 以下是构造函数
   MyClass() {
      x = 10;
   }
}

次のようにコンストラクター メソッドを呼び出してオブジェクトを初期化できます:

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass();
      MyClass t2 = new MyClass();
      System.out.println(t1.x + " " + t2.x);
   }
}

ほとんどの場合、パラメーターを含むコンストラクター メソッドが必要です。

以下はコンストラクター メソッドの使用例です:

// 一个简单的构造函数
class MyClass {
   int x;
   
   // 以下是构造函数
   MyClass(int i ) {
      x = i;
   }
}

次のようにコンストラクター メソッドを呼び出してオブジェクトを初期化できます:

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass( 10 );
      MyClass t2 = new MyClass( 20 );
      System.out.println(t1.x + " " + t2.x);
   }
}

実行結果は次のとおりです:

10 20

変数パラメーター

開始JDK 1.5 では、Java は同じタイプの変数パラメータをメソッドに渡すことをサポートします。

メソッドの可変パラメータの宣言は次のとおりです:

typeName... parameterName

メソッド宣言では、パラメータの型を指定した後に省略記号(...)を追加します。

メソッド内で指定できる変数パラメーターは 1 つだけであり、それはメソッドの最後のパラメーターである必要があります。通常のパラメータはその前に宣言する必要があります。

インスタンス

public class VarargsDemo {

   public static void main(String args[]) {
      // 调用可变参数的方法
	  printMax(34, 3, 3, 2, 56.5);
      printMax(new double[]{1, 2, 3});
   }

   public static void printMax( double... numbers) {
   if (numbers.length == 0) {
      System.out.println("No argument passed");
      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);
   }
}

上記の例のコンパイル結果と実行結果は次のとおりです:

The max value is 56.5
The max value is 3.0

finalize() メソッド

Java では、オブジェクトが破棄 (リサイクル) される前に呼び出されるこのようなメソッドを定義できます。このメソッドは、finalize() と呼ばれ、リサイクルされたオブジェクトをクリアするために使用されます。

たとえば、finalize() を使用すると、オブジェクトによって開かれたファイルが確実に閉じられるようにすることができます。

finalize() メソッドでは、オブジェクトが破棄されたときに実行される操作を指定する必要があります。

finalize() の一般的な形式は次のとおりです:

protected void finalize()
{
   // 在这里终结代码
}

protected キーワードは修飾子であり、これにより、finalize() メソッドがクラス外のコードによって呼び出されないようになります。

もちろん、Java メモリのリサイクルは JVM によって自動的に完了できます。手動で使用する場合は、上記の方法を使用できます。

public class FinalizationDemo {  
    public static void main(String[] args) {  
        Cake c1 = new Cake(1);  
        Cake c2 = new Cake(2);  
        Cake c3 = new Cake(3);  
          
        c2 = c3 = null;  
        System.gc(); //调用Java垃圾收集器
    }  
}  
  
class Cake extends Object {  
    private int id;  
    public Cake(int id) {  
        this.id = id;  
        System.out.println("Cake Object " + id + "is created");  
    }  
      
    protected void finalize() throws java.lang.Throwable {  
        super.finalize();  
        System.out.println("Cake Object " + id + "is disposed");  
    }  
}

上記のコードを実行すると、出力結果は次のようになります:

C:>java FinalizationDemo  
Cake Object 1is created  
Cake Object 2is created  
Cake Object 3is created  
Cake Object 3is disposed  
Cake Object 2is disposed