Java超|メソッドと引数の使い方

メソッドに値を渡せば、悟空オブジェクトの状態を自由に設定できる。引数は、必殺技に込めるエネルギーのように、処理へ具体的な情報を届けるしくみです。

ここまでで、メソッドはクラスの中に機能をまとめるためのしくみだと確認してきました。

たとえば、戦士の情報を表示する、戦闘前に案内メッセージを出す、自分の状態を確認する、といった処理をひとつのまとまりとして定義できました。

ただ、メソッドの便利さは「同じ処理をまとめる」だけではありません。

メソッドは、呼び出すときに値を渡して、その値に応じて動きを変えることもできます。
このしくみが引数です。

ドラゴンボールの世界観でたとえるなら、悟空に「情報を設定して」と命じるだけでなく、「名前を悟空にして」「戦闘力を9000にして」「流派の印を亀にして」「流派名を亀仙流にして」というように、具体的な情報を渡して動かすイメージです。

メソッドが引数を受け取れるようになると、クラスの機能はぐっと柔軟になります。

この記事では、メソッドに値を渡す引数のしくみを、サイヤ人戦士に情報を渡して設定する流れとして、やさしく整理していきます。

引数はメソッドに値を渡すためのしくみ

メソッドを学び始めたばかりのころは、次のように何も受け取らないメソッドをよく見ます。

void show()
{
    System.out.println("戦士の名前は" + name + "です。");
    System.out.println("戦闘力は" + power + "です。");
    System.out.println("流派の印は「" + styleMark + "」です。");
    System.out.println("流派名は" + styleName + "です。");
}

この show は、今そのオブジェクトの中に入っている name、power、styleMark、styleName を表示するメソッドです。

これは大切な基本ですが、この形だけでは、呼び出す側から値を渡して、その値に応じて処理を変えることはできません。

そこで使うのが引数です。

引数があるメソッドは、呼び出し元から値を受け取れます。

たとえば、戦士の名前を設定する、戦闘力を設定する、流派の印を設定する、流派名を設定する、といった処理では、どんな名前にするのか、戦闘力をいくつにするのか、どの流派にするのかを外から渡したくなります。

そのときに引数が活躍します。

ドラゴンボールで考える引数の感覚

ドラゴンボールの世界観で考えると、引数は「技や命令に添えて渡す具体的な情報」です。

たとえば、悟空オブジェクトに向かって次のように伝える場面を想像してください。

指示渡す情報
名前を設定して悟空
戦闘力を設定して9000
流派の印を設定して亀
流派名を設定して亀仙流

このときの 悟空、9000、亀、亀仙流 のような具体的な情報が、メソッドに渡す値です。

そして、その値を受け取って処理するための入り口が引数です。

つまり引数は、メソッドに外から情報を持ち込むための入り口と考えると分かりやすいです。

図:引数はメソッドへ値を渡す入口

この図が示していること

この図は、呼び出し側から渡した値が、メソッドの引数に入っていく流れを示しています。

goku.setName("悟空"); の 悟空 は、setName メソッドへ渡される値です。
goku.setPower(9000); の 9000 は、setPower メソッドへ渡される値です。

このように、引数を使うと、呼び出し側からメソッドへ具体的な情報を届けられます。

この図から分かることは、メソッドは固定された動きだけでなく、外から受け取った値に応じてオブジェクトの状態を変えられるということです。

引数つきのメソッドを定義する

実際に、引数を持つメソッドの形を見てみましょう。

たとえば、戦士の名前を設定する setName というメソッドを考えます。

void setName(String n)
{
    name = n;
    System.out.println("戦士の名前を" + name + "にしました。");
}

このメソッドの () の中にある String n が引数です。

意味としては、次のようになります。

部分意味
String文字列を受け取る
n受け取った値を入れる変数
name = n;受け取った値をフィールド name に代入する

つまり、このメソッドは外から文字列を1つ受け取り、その値を name に入れる処理をしています。

戦闘力を設定するなら、次のような形になります。

void setPower(int p)
{
    power = p;
    System.out.println("戦闘力を" + power + "にしました。");
}

この int p は、int 型の値を受け取る引数です。

setPower(9000) のように呼び出すと、9000 が p に入り、その値が power に代入されます。

流派の印を設定するなら、次のように書けます。

void setStyleMark(String mark)
{
    styleMark = mark;
    System.out.println("流派の印を「" + styleMark + "」にしました。");
}

流派名を設定するなら、次のように書けます。

void setStyleName(String style)
{
    styleName = style;
    System.out.println("流派名を" + styleName + "にしました。");
}

このように、引数を使うと、呼び出し側から受け取った値をフィールドへ設定できます。

引数は呼び出されたときに値が入る変数

引数で大事なのは、引数がメソッドの呼び出し時に値を受け取る変数だということです。

たとえば、次のメソッドを見てください。

void setPower(int p)
{
    power = p;
    System.out.println("戦闘力を" + power + "にしました。");
}

この p は、最初から値を持っているわけではありません。

次のようにメソッドを呼び出したときに、値が入ります。

goku.setPower(9000);

このとき、9000 が p に渡されます。

そして、メソッドの中で次の処理が実行されます。

power = p;

その結果、フィールド power に 9000 が入ります。

つまり引数は、呼び出し元から届いた値を、一時的に受け取るための変数です。

ドラゴンボールでたとえるなら、setPower という技に 9000 というエネルギー値を込めて発動し、その値を悟空オブジェクトの戦闘力として設定するようなイメージです。

仮引数と実引数

引数の説明では、仮引数と実引数という言葉が出てきます。

最初は少し似ていて分かりにくいですが、役割ははっきり違います。

仮引数

仮引数は、メソッドの定義側に書かれている、値を受け取るための変数です。

void setPower(int p)

この中の int p が仮引数です。

実引数

実引数は、メソッドを呼び出すときに実際に渡す値です。

goku.setPower(9000);

この中の 9000 が実引数です。

用語意味例
仮引数メソッド定義側で値を受け取る変数p
実引数呼び出し側から実際に渡す値9000

ドラゴンボールでたとえるなら、仮引数は「受け取るための器」、実引数は「実際に渡される中身」です。

setPower(int p) の p は、戦闘力を受け取るための器です。
goku.setPower(9000) の 9000 は、実際に渡される戦闘力です。

実際のプログラムで確認する

ここでは、引数を持つメソッドを使ったプログラムを見ていきます。

ファイル名:Sample4.java

class Saiyan
{
    String name;
    int power;
    String styleMark;
    String styleName;

    void setName(String n)
    {
        name = n;
        System.out.println("戦士の名前を" + name + "にしました。");
    }

    void setPower(int p)
    {
        power = p;
        System.out.println("戦闘力を" + power + "にしました。");
    }

    void setStyleMark(String mark)
    {
        styleMark = mark;
        System.out.println("流派の印を「" + styleMark + "」にしました。");
    }

    void setStyleName(String style)
    {
        styleName = style;
        System.out.println("流派名を" + styleName + "にしました。");
    }

    void show()
    {
        System.out.println("戦士の名前は" + name + "です。");
        System.out.println("戦闘力は" + power + "です。");
        System.out.println("流派の印は「" + styleMark + "」です。");
        System.out.println("流派名は" + styleName + "です。");
    }
}

class Sample4
{
    public static void main(String[] args)
    {
        Saiyan goku = new Saiyan();

        goku.setName("悟空");
        goku.setPower(9000);
        goku.setStyleMark("亀");
        goku.setStyleName("亀仙流");
    }
}

このプログラムでは、Saiyan クラスに5つのメソッドがあります。

メソッド引数役割
setNameString n戦士の名前を設定する
setPowerint p戦闘力を設定する
setStyleMarkString mark流派の印を設定する
setStyleNameString style流派名を設定する
showなし戦士の情報を表示する

setName、setPower、setStyleMark、setStyleName は引数を持つメソッドです。
show は引数を持たないメソッドです。

setName の動きを見る

setName メソッドを見てみます。

void setName(String n)
{
    name = n;
    System.out.println("戦士の名前を" + name + "にしました。");
}

このメソッドは、String 型の値を1つ受け取ります。

main メソッドでは、次のように呼び出しています。

goku.setName("悟空");

このときの流れは、次のようになります。

順番内容
1実引数 悟空 が渡される
2仮引数 n に 悟空 が入る
3name = n; が実行される
4フィールド name に 悟空 が入る
5戦士の名前を悟空にしました。 と表示される

つまり、呼び出し側で渡した 悟空 が、メソッド側の n に入り、その値がフィールド name に代入されます。

setPower の動きを見る

次に setPower メソッドを見ます。

void setPower(int p)
{
    power = p;
    System.out.println("戦闘力を" + power + "にしました。");
}

このメソッドは、int 型の値を1つ受け取ります。

main メソッドでは、次のように呼び出しています。

goku.setPower(9000);

このときの流れは、次のようになります。

順番内容
1実引数 9000 が渡される
2仮引数 p に 9000 が入る
3power = p; が実行される
4フィールド power に 9000 が入る
5戦闘力を9000にしました。 と表示される

setName と setPower は、受け取る値の型は違いますが、考え方は同じです。

外から値を受け取り、その値をフィールドに設定しています。

setStyleMark と setStyleName の動きを見る

今回のプログラムでは、流派に関する情報も引数で設定します。

void setStyleMark(String mark)
{
    styleMark = mark;
    System.out.println("流派の印を「" + styleMark + "」にしました。");
}

void setStyleName(String style)
{
    styleName = style;
    System.out.println("流派名を" + styleName + "にしました。");
}

main メソッドでは、次のように呼び出しています。

goku.setStyleMark("亀");
goku.setStyleName("亀仙流");

このとき、setStyleMark には 亀 が渡されます。
そして、仮引数 mark に 亀 が入り、styleMark フィールドへ代入されます。

setStyleName には 亀仙流 が渡されます。
そして、仮引数 style に 亀仙流 が入り、styleName フィールドへ代入されます。

呼び出し実引数仮引数代入先フィールド
goku.setStyleMark("亀");亀markstyleMark
goku.setStyleName("亀仙流");亀仙流stylestyleName

このように、引数を使うと、流派の印と流派名のような情報も外から柔軟に設定できます。

流派情報を引数で扱う

この記事では、流派を表す情報として styleMark と styleName を使います。

styleMark は、流派を短く表す印です。
styleName は、流派の正式な名前です。

styleMarkstyleName
亀亀仙流
鶴鶴仙流
武武泰斗流
塔カリン流
魔ピッコロ魔族流
神神流(ナメック流)
惑惑星戦士流
界北の界王流

今回の Sample4.java では、悟空の流派を次のように設定しています。

フィールド設定値
styleMark亀
styleName亀仙流

styleMark だけなら、道着の胸に入っている印のように短く表せます。
styleName も持たせると、その印が何流なのかをプログラム上で分かりやすく扱えます。

実行結果から確認する

Sample4.java を実行すると、次のように表示されます。

戦士の名前を悟空にしました。
戦闘力を9000にしました。
流派の印を「亀」にしました。
流派名を亀仙流にしました。

この結果を見ると、呼び出し時に渡した値が、きちんとメソッドの中で使われていることが分かります。

ここで大切なのは、メソッドが固定された処理しかできないわけではないということです。

渡された値に応じて、処理の内容を変えられます。

たとえば、別の戦士を作るなら、同じメソッドでも次のように違う値を渡せます。

vegeta.setName("ベジータ");
vegeta.setPower(8500);
vegeta.setStyleMark("惑");
vegeta.setStyleName("惑星戦士流");

setName、setPower、setStyleMark、setStyleName というメソッドは同じでも、渡す値が変われば、設定される内容も変わります。

引数があると同じメソッドをいろいろな値で使える

引数なしのメソッドは、基本的に決まった形で動きます。

一方で、引数ありのメソッドは、呼び出すたびに違う値を受け取れます。

メソッドの種類特徴
引数なしのメソッド毎回ほぼ同じ形で動く
引数ありのメソッド渡された値に応じて動きを変えられる

ドラゴンボールで言えば、show は「今の自分の状態を表示する技」です。
setPower は「受け取った値で戦闘力を設定する技」です。

引数があることで、メソッドはもっと実用的になります。

たとえば setPower は1つだけでも、渡す値によって次のように使えます。

呼び出し結果
goku.setPower(9000);悟空の戦闘力を9000にする
vegeta.setPower(8500);ベジータの戦闘力を8500にする
gohan.setPower(7000);悟飯の戦闘力を7000にする

同じメソッドを使い回せるので、コードも整理しやすくなります。

図:実引数が仮引数に渡される流れ

以下の条件でイラストを作成してください。

カラーイラスト、16:9横長。白と青を基調にした学習教材風デザイン。ドラゴンボール風のアニメ調。背景は青く光るスカウター解析室。ホログラム画面、コードパネル、戦闘力メーターを配置する。

画面左にコードパネルを配置し、次のコードを大きく表示する。

「goku.setPower(9000);」

その下に「9000 = 実引数」と表示する。

画面中央に青い矢印を配置し、「値が渡される」と表示する。

画面右にメソッド定義カードを配置し、次のコードを表示する。

「void setPower(int p)」
「power = p;」

その横に「p = 仮引数」と表示する。

さらに右下に悟空オブジェクトカードを配置し、「power = 9000」と表示する。

悟空アイコンは小さな戦士アイコンとして表現する。ワインレッドの道着を着せ、右胸には「亀」の丸いマークを入れる。髪型と顔、特に目元は原作キャラクターに似すぎないよう、学習教材向けのオリジナル調にする。文字は読みやすく、背景やキャラクターと重ならないようにする。

この図が示していること

この図は、呼び出し側で渡した値が、メソッド側の仮引数に入る流れを示しています。

goku.setPower(9000); の 9000 が実引数です。
void setPower(int p) の p が仮引数です。

呼び出し時に 9000 が p に渡され、そのあと power = p; によって、オブジェクトの power フィールドに 9000 が設定されます。

この図から分かることは、引数は「呼び出し側の値をメソッドの中へ持ち込むための橋渡し」だということです。

型が合っていることも大切

引数では、渡す値の型が合っていることも大切です。

たとえば setPower は、次のように定義されています。

void setPower(int p)

つまり、このメソッドには int 型の値を渡す必要があります。

goku.setPower(9000);

9000 は int 型の値なので渡せます。

しかし、文字列を渡すことはできません。

goku.setPower("九千");

これは、setPower が int 型を受け取るメソッドだからです。

同じように setName は、次のように定義されています。

void setName(String n)

このメソッドには String 型の値を渡します。

goku.setName("悟空");

表で整理すると、次のようになります。

メソッド仮引数の型渡す値の例
setNameString悟空
setPowerint9000
setStyleMarkString亀
setStyleNameString亀仙流

引数は便利ですが、どんな型の値を受け取るのかは、メソッド定義で決まっています。

引数ありメソッドと引数なしメソッドの違い

Sample4.java には、引数ありのメソッドと引数なしのメソッドが両方あります。

引数あり

void setName(String n)
void setPower(int p)
void setStyleMark(String mark)
void setStyleName(String style)

引数なし

void show()

呼び出すときの形も違います。

引数ありの呼び出し

goku.setName("悟空");
goku.setPower(9000);
goku.setStyleMark("亀");
goku.setStyleName("亀仙流");

引数なしの呼び出し

goku.show();

引数ありのメソッドでは、() の中に値を書きます。

引数なしのメソッドでは、() の中は空です。

種類定義呼び出し
引数ありvoid setName(String n)goku.setName("悟空");
引数ありvoid setPower(int p)goku.setPower(9000);
引数ありvoid setStyleMark(String mark)goku.setStyleMark("亀");
引数ありvoid setStyleName(String style)goku.setStyleName("亀仙流");
引数なしvoid show()goku.show();

この違いが見えるようになると、コードを読むときに「このメソッドは外から値を受け取るのか」が分かりやすくなります。

show メソッドがある意味

Sample4.java では、main メソッドの中で show は呼び出していません。

しかし、Saiyan クラスの中には show が定義されています。

void show()
{
    System.out.println("戦士の名前は" + name + "です。");
    System.out.println("戦闘力は" + power + "です。");
    System.out.println("流派の印は「" + styleMark + "」です。");
    System.out.println("流派名は" + styleName + "です。");
}

このメソッドは、すでにオブジェクトの中に入っている name、power、styleMark、styleName を表示するためのものです。

役割としては、次のようになります。

メソッド役割
setName名前を設定する
setPower戦闘力を設定する
setStyleMark流派の印を設定する
setStyleName流派名を設定する
show設定された値を表示する

このように、クラスの中には複数の役割を持つメソッドを用意できます。

値を設定するメソッド。
値を表示するメソッド。
状態を確認するメソッド。

というように役割を分けることで、クラスの使い方が分かりやすくなります。

図:setName と setPower と流派設定の役割

この図が示していること

この図は、引数を使ってオブジェクトの状態を設定する流れを示しています。

goku.setName("悟空"); では、悟空 という値が setName の仮引数 n に渡され、name フィールドに設定されます。

goku.setPower(9000); では、9000 という値が setPower の仮引数 p に渡され、power フィールドに設定されます。

goku.setStyleMark("亀"); では、亀 という値が setStyleMark の仮引数 mark に渡され、styleMark フィールドに設定されます。

goku.setStyleName("亀仙流"); では、亀仙流 という値が setStyleName の仮引数 style に渡され、styleName フィールドに設定されます。

この図から分かることは、引数を使うと、呼び出し側から渡した値によって、オブジェクトの中の状態を変えられるということです。

引数を使うとメソッドはもっと便利になる

引数が使えるようになると、メソッドはただ決まった処理をするだけではなくなります。

そのときどきに必要な値を受け取りながら、同じしくみを何度も再利用できます。

たとえば setPower というメソッドは1つだけでも、渡す値によっていろいろな場面で使えます。

goku.setPower(9000);
vegeta.setPower(8500);
gohan.setPower(7000);

このように、同じメソッドでも渡す値が違えば、設定される内容も変わります。

ドラゴンボールで言えば、同じ「戦闘力を設定する技」でも、戦士ごとに違う数値を込められるようなものです。

流派も同じです。

goku.setStyleMark("亀");
goku.setStyleName("亀仙流");

vegeta.setStyleMark("惑");
vegeta.setStyleName("惑星戦士流");

gohan.setStyleMark("魔");
gohan.setStyleName("ピッコロ魔族流");

同じ setStyleMark や setStyleName を使っていても、渡す値によって、悟空、ベジータ、悟飯それぞれの流派情報を設定できます。

引数によって、メソッドは固定された動きではなく、外からの情報に応じて動ける機能になります。

いちばん大事な感覚

メソッドと引数の使い方で大切なのは、次の感覚です。

ポイント内容
引数呼び出し元からメソッドへ値を渡すしくみ
仮引数メソッド定義側で値を受け取る変数
実引数呼び出し側で実際に渡す値
型渡す値は仮引数の型に合わせる
便利さ同じメソッドを違う値で使い回せる

ドラゴンボールで言いかえるなら、悟空にただ「動け」と命じるだけでなく、名前、戦闘力、流派の印、流派名のような具体的な情報を渡して動かせるようになる、ということです。

goku.setName("悟空"); と呼び出せば、悟空 という値がメソッドに渡ります。
goku.setPower(9000); と呼び出せば、9000 という値がメソッドに渡ります。
goku.setStyleMark("亀"); と呼び出せば、亀 という値がメソッドに渡ります。
goku.setStyleName("亀仙流"); と呼び出せば、亀仙流 という値がメソッドに渡ります。

その値を受け取ったメソッドが、オブジェクトの状態を変えていきます。

この感覚がつかめると、メソッドは単なる処理のまとまりではなく、外から情報を受け取りながら働く機能として見えてきます。