「こんにちは、アミーゴ! 独自のメソッドを使用してタスクを解決することを楽しんでいただけたこと、またメソッドを作成することがいかに便利であるかを理解していただけたことを願っています。次に、すべての中で最も興味深いトピックについて話しましょう。」

「ディエゴ、興味をそそられました…新しい話題ですか?」

「すべてのトピックは、あなたにとって新しいものです、私の若いロボット! そして、これも例外ではありません。ただし、再びメソッドに関するものですが。おそらく、このようなメソッドから、引数をメソッドに渡すことができることにすでに気づいているでしょう。メソッドの内部に入ると System.out.println()、それらをパラメータと呼びます。」

「括弧内に書くのがパラメータ?」

「はい、その通りです。そして実際、パラメーターはメソッドの作成と使用から得られる利点を大幅に高めます。」

「それらの使用についてあなたが言っていることは理解できますが、私はすでにそれを行っていることがわかりました。パラメーターを使用してメソッドを宣言するにはどうすればよいでしょうか?」

「実際には非常に簡単です。

public static void name(parameters)
{
  method body
}

「ここでname、 はメソッドの一意の名前で、method bodyメソッドを構成するコマンドを表します。 はparameters、カンマで区切られたメソッド パラメータのプレースホルダーです。」

「うーん…分かるような気がする…というか分からないかもしれない…」

「次のことを確実に理解できるように、このテンプレートについてさらに詳しく説明します。

public static void name(Type1 name1, Type2 name2, Type3 name3)
{
  method body
}

ここではいくつかの例を示します。

コード 説明
public static void print(String str)
{
}
メソッドprintはパラメータを使用して宣言されます。
String str
public static void print(String str, int count)
{
}
このprintメソッドは 2 つのパラメーターを使用して宣言されます。
String str
int count
public static void write(int x, int y)
{
}
このwriteメソッドは 2 つのパラメーターを使用して宣言されます。
int x
int y

「ああ...これで明らかです。メソッドにパラメータを持たせたくない場合は、括弧を空のままにします。」

「その通りです。基本的に、パラメーターはメソッド内の特別な変数です。パラメーターを使用すると、メソッドが呼び出されたときにさまざまな値をメソッドに渡すことができます。値を渡す必要がない場合は、括弧を空のままにします。

「たとえば、指定されたテキスト行を指定された回数だけ表示するメソッドを書いてみましょう。これを行う方法について何か考えはありますか?」

「そうですね...画面に文字列を複数回表示するコードの書き方はよくわかったような気がします...」

「表示する文字列はどうやって指定するんですか?また、表示する行数はどうやって指定するんですか?わかりますか?」

「状況が明らかになり始めています...おそらくメソッド パラメーターの助けによるものでしょうか?」

「その通りです。テキスト行を表す文字列パラメータと、表示される行数を表す数値パラメータです。これを行うコードは次のようになります。

コード 説明
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}

printLines次のパラメータを使用してメソッドを宣言しました。
String textint count

メソッドは文字列のtext count時間を表示します。さまざまなパラメータを使用



してメソッドを呼び出します。printLines

「メソッドが呼び出されるたびに、そのパラメータには渡された値が割り当てられ、その後初めてメソッド内でコマンドの実行が開始されます。

引数

「パラメーターを持つメソッドの呼び出しには特に注意してください。メソッドに渡される値は、通常、メソッドに渡されるときに引数と呼ばれます。

例をもう一度見てみましょう。

コード 説明
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}

printLines次のパラメータを使用してメソッドを宣言しました。
String textint count

メソッドは文字列のtext count回数を表示します。 次の引数を


使用してメソッドを呼び出します。printLines
text = "Hi"; count = 10;
text = "Bye"; count = 20;

printLinesメソッドが初めて呼び出されたとき、そのパラメーターには次の値が割り当てられました。

String text = "Hi", int count = 10

printLinesメソッドが 2 回目に呼び出されたとき、そのパラメータには異なる値が割り当てられました。

String text = "Bye", int count = 20

「パラメータは、メソッドの呼び出し時に特定の値が割り当てられる変数以上でもそれ以下でもありません。値"Hi""Bye"10、 および20それ自体は引数と呼ばれます。」

「違いを覚えて、これらの概念を混同しないように努めます。」

メソッド呼び出し時の変数名が競合する

「メソッドを呼び出すとき、変数を引数として使用できます。

「なるほど、それは当然ですね!」

「それは理にかなっていますが、潜在的にいくつかの問題を引き起こす可能性があります。もう一度例に戻りましょう。ただし、今回は引数を別の変数に移動します。

コード 説明
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Hi";
     String n = 10;
     printLines(str, n);
   }
}

printLines次のパラメータを使用してメソッドを宣言しました。
String textint count

メソッドは文字列のtext count回数を表示します。 次の引数を



使用してメソッドを呼び出します。printLines
text = str;
count = n;

「うーん...難しいところはありません。変数がありますstr。その値は、textメソッドが呼び出されるときにパラメータに割り当てられます。変数があります。その値は、メソッドが呼び出されるときにパラメータnに割り当てられます。」count「これまでのところ、すべてが明らかです。」

「よしよし。では、mainメソッド内の変数の名前を変更しましょう。

コード 説明
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String text = "Hi";
     String count = 10;
     printLines(text, count);
   }
}

printLines次のパラメータを使用してメソッドを宣言しました。
String textint count

メソッドは文字列のtext count回数を表示します。 次の引数を



使用してメソッドを呼び出します。printLines
text = text;
count = count;

「2つのことに注意してください

まず、異なるメソッドに同じ名前の変数があります。これらは異なる変数です (意図的に異なる色を使用して表しています)。すべては前の例と同じように機能します。メソッド内の変数のmain名前はstrとでしたn

2 番目:メソッドが呼び出されたときに魔法のようなことは何も起こりません。パラメータには引数値が割り当てられるだけです。数値、文字列、変数、式のいずれであっても。

「メイン メソッドの変数の名前を変更した後、何も変化はありません。これらは以前は別のメソッドの別の変数であったため、そのまま残ります。2 つのtext変数の間には魔法のような関係はありません。」

"今私は知っている。"

メソッドへの参照の受け渡し

「引数をメソッドに渡すことについて私が説明したことはすべて理解していただけたと思います。なぜそう言ったかというと、これからこのトピックについてもう少し詳しく説明するからです。よく聞いてください。」

「Java の一部の変数は値そのものではなく、参照つまり値が配置されているメモリ ブロックのアドレスを格納することはすでにご存知でしょう。これが文字列変数と配列変数の仕組みです。

「開発者が別の配列変数を配列変数に代入すると何が起こるでしょうか?」

「では、それらは同じアドレスを指しているのでしょうか?」

「正解です。2 つの変数はメモリ内の同じ領域を参照し始めます。

「そして、これらの変数の 1 つがメソッド パラメーターである場合はどうなるでしょうか?

コード 説明
class Solution
{
   public static void sum(int[] data)
   {
     int total = 0;
     for (int i = 0; i < data.length; i++)
       total = total + data[i];
     System.out.println(total);
   }
   
   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     sum(months);
   }
}


このsumメソッドは、渡された配列内の数値の合計を計算し、画面に表示します。

「まったく同じことが起こります。dataパラメータには、変数と同じメモリ領域への参照が含まれますmonths。メソッドが呼び出されると、単純な割り当てが行われます。data = months

「そして、両方の変数が整数を格納するメモリの同じ領域を参照するため、メソッドはsum配列から値を読み取るだけでなく、値を変更することもできます。」

「わかったようですが、もっと例が必要です!」

「そうですね、たとえば、2 次元配列に同じ値を埋める独自のメソッドを作成できます。次のようになります。

コード 説明
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


このfill メソッドは、渡された 2 次元配列内のすべてのセルを反復処理し、valueそれらに割り当てます。






二次元配列を作成します。
配列全体に数値を入力します8

同じ名前のメソッド

それでは、もう一度メソッド名の話に戻りましょう。

「名前について他に何が言えるか想像もつきません!」

「そうですね、Java 言語標準では、同じクラス内のすべてのメソッドが一意の名前を持つことが要求されます。

「では、同じクラス内で同じ名前の 2 つのメソッドを宣言することは不可能ですか?」

「さて、細心の注意を払ってください! クラス内のメソッドは確かに同じ名前を持つことができます! しかし、この場合、それらは異なるパラメータを持つ必要があります。言い換えれば、メソッドは同一であるかどうか比較され、名前だけでなく、パラメータのタイプ! タイプについて具体的に述べたことに注意してください。パラメータの名前は考慮されません。例:

コード 説明
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
これら 3 つの方法は異なる方法です。これらは同じクラス内で宣言できます。
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
これら 5 つの方法はそれぞれ異なるものとみなされます。これらは同じクラス内で宣言できます。
void sum(int x, int y) {
}
void sum(int data, int value) {
}
「これら 2 つのメソッドは同じとみなされます。つまり、同じクラスで宣言することはできません。」

「完全に混乱しています! なぜこれらすべてが必要なのですか? なぜ一部のメソッドは同じとみなされ、他のメソッドは異なるのですか? そして、メソッドの一意性を決定するときにパラメータ名が考慮されないのはなぜですか? なぜ一意性が必要なのでしょうか?全て?"

「問題は、コンパイラーがプログラムをコンパイルするときに、特定の場所でどのメソッドを呼び出すつもりであるかを正確に認識する必要があるということです。

「たとえば、 と書くと、コンパイラは賢いので、パラメータを使用してここでメソッドを呼び出すつもりであると簡単に結論付けます。しかし、 を書くと、コンパイラはパラメータを使用してメソッドを呼び出すことになります。コンパイラには何もわかりません」プログラマがメソッドを宣言するときにパラメータに付けた名前。」System.out.println("Hi")println()StringSystem.out.println(1.0)println()double

ああ、通じ始めているようです!

「メソッドが呼び出されるとき、コンパイラは引数の型がパラメータの型と一致していることを確認します。引数の名前にはまったく注意しません。Java では、パラメータ名はコンパイラがどのメソッドを呼び出すかを決定するのに役立ちません。」コンパイラではなく、プログラマがそれらを必要とします。

「それが、メソッドの一意性を判断する際にそれらが考慮されない理由なのではないでしょうか?」

"はい、その通りです。メソッドの名前とそのパラメーターの型は、メソッド シグネチャと呼ばれます。たとえば、sum (int, int)"

「したがって、各クラスには、一意の名前を持つメソッドではなく、一意のシグネチャを持つメソッドが必要です。」

「よくやった、アミーゴ! このレッスンを完璧にまとめてくれました。何か不明な点が残っても、パニックにならないでください。このトピックは、いくつかのタスクを終えると明らかになるでしょう。」