Java道|メソッドの戻り値と使い方

技を出して終わりじゃない。
メソッドから結果を受け取れると、Javaの処理はもっと自由に広がる。

メソッドの戻り値と使い方

これまで、メソッドには引数を渡せることを学んできました。

たとえば、隊士の名前や体力を設定するときは、呼び出し側からメソッドへ値を渡していました。

mizuki.setNameStamina("水月", 100);

このように、呼び出し元からメソッドへ情報を送ることで、オブジェクトの状態を設定できます。

ただ、メソッドのやり取りは、呼び出し元からメソッドへ送るだけではありません。
今度は逆に、メソッドの中で得られた結果を、呼び出し元へ返すこともできます。

この返ってくる値を戻り値といいます。

鬼滅の刃でたとえると、隊士に対して「今の名前を教えて」「現在の体力を報告して」とたずねる場面です。
隊士は自分の状態を確認し、その結果を呼び出し元へ返します。

つまり、引数が「こちらから隊士へ渡す情報」なら、戻り値は「隊士からこちらへ返ってくる報告」です。

戻り値はメソッドから呼び出し元へ返される情報

戻り値とは、メソッドの処理結果として呼び出し元へ返される値です。

引数は、次のような向きでした。

しくみ向き役割
引数呼び出し元 → メソッド値を渡す

一方、戻り値は逆向きです。

しくみ向き役割
戻り値メソッド → 呼び出し元値を返す

鬼滅の刃でたとえると、引数は「隊士に任務情報を渡すこと」です。
戻り値は「隊士から任務結果や現在の状態を報告してもらうこと」です。

この「行きは引数、帰りは戻り値」という感覚を持つと、メソッドの役割がかなり整理しやすくなります。

戻り値を持つメソッドは型を書く

戻り値を持つメソッドでは、メソッド名の前に返す値の型を書きます。

たとえば、隊士の名前を返すなら String 型です。

String getName()
{
    System.out.println("隊士の名前を調べました。");
    return name;
}

隊士の体力を返すなら int 型です。

int getStamina()
{
    System.out.println("体力を調べました。");
    return stamina;
}

このとき、String や int が戻り値の型です。

返したい情報戻り値の型メソッド例
隊士の名前StringgetName()
体力intgetStamina()

ここで大切なのは、返す値の種類に合わせて型を書くことです。

名前は文字列なので String。
体力は整数なので int。

このように、「何を返したいか」によって戻り値の型が決まります。

return は値を返す合図

戻り値を返すときに使うのが return です。

return name;

これは、name の値を呼び出し元へ返します、という意味です。

また、次のように書けば、stamina の値を返します。

return stamina;

鬼滅の刃でたとえると、隊士が自分の名簿や体力記録を確認し、「現在の名前はこちらです」「現在の体力はこちらです」と報告書を返すようなイメージです。

return には、もうひとつ大事な特徴があります。
return が実行されると、そのメソッドの処理はそこで終了します。

つまり return は、

役割内容
値を返すreturn の後ろに書いた値を呼び出し元へ返す
処理を終えるreturn が実行された時点でメソッドを終了する

という2つの意味を持っています。

最初は、return は「この値を返して、メソッドを終える合図」と覚えると分かりやすいです。

↓クリックすると拡大表示されます。

戻り値を持つメソッドを確認する

戻り値を持つメソッドを、鬼滅の刃風の隊士管理プログラムで見ていきましょう。

ファイル名:Sample6.java

class DemonSlayer
{
    String name;
    int stamina;

    String getName()
    {
        System.out.println("隊士の名前を調べました。");
        return name;
    }

    int getStamina()
    {
        System.out.println("体力を調べました。");
        return stamina;
    }

    void setNameStamina(String n, int s)
    {
        name = n;
        stamina = s;
        System.out.println("隊士の名前を" + name + "に体力を" + stamina + "にしました。");
    }

    void show()
    {
        System.out.println("隊士の名前は" + name + "です。");
        System.out.println("体力は" + stamina + "です。");
    }
}

class Sample6
{
    public static void main(String[] args)
    {
        DemonSlayer mizuki = new DemonSlayer();

        mizuki.setNameStamina("水月", 100);

        String slayerName = mizuki.getName();
        int slayerStamina = mizuki.getStamina();

        System.out.println("調査結果");
        System.out.println("名前は" + slayerName + "体力は" + slayerStamina + "でした。");
    }
}

DemonSlayer クラスの役割

このプログラムでは、DemonSlayer クラスで隊士を表しています。

class DemonSlayer
{
    String name;
    int stamina;

name は隊士の名前を保存するフィールドです。
stamina は隊士の体力を保存するフィールドです。

鬼滅の刃でたとえると、DemonSlayer は隊士を登録するための設計図です。
その中に、名前や体力といった隊士の情報を持たせています。

フィールド意味
name隊士の名前
stamina隊士の体力

この2つの情報を設定したり、調べたりするために、いくつかのメソッドを用意しています。

setNameStamina は値を受け取るメソッド

まず、setNameStamina を見てみましょう。

void setNameStamina(String n, int s)
{
    name = n;
    stamina = s;
    System.out.println("隊士の名前を" + name + "に体力を" + stamina + "にしました。");
}

このメソッドは、名前と体力を受け取って、フィールドに保存します。

mizuki.setNameStamina("水月", 100);

この呼び出しでは、実引数として 水月 と 100 を渡しています。

実引数仮引数保存先
水月nname
100sstamina

このメソッドの戻り値の型は void です。

void setNameStamina(String n, int s)

void は、値を返さないという意味です。

つまり setNameStamina は、呼び出し元から値を受け取って、隊士の情報を設定するメソッドです。
結果を呼び出し元へ返すのではなく、フィールドの状態を書き換えることが役割です。

鬼滅の刃でたとえると、隊士名簿に「名前は水月、体力は100」と登録する処理です。

getName は名前を返すメソッド

次に getName を見てみましょう。

String getName()
{
    System.out.println("隊士の名前を調べました。");
    return name;
}

このメソッドは、String 型の値を返します。

String getName()

メソッド名の前に String があるので、このメソッドは文字列を返すメソッドです。

中では、次の処理をしています。

順番処理内容
1表示する隊士の名前を調べました。
2return name;name の値を呼び出し元へ返す

たとえば name に 水月 が入っていれば、getName は 水月 を返します。

main メソッドでは、次のように戻り値を受け取っています。

String slayerName = mizuki.getName();

この1行では、次の流れが起きています。

順番処理内容
1mizuki.getName() を呼ぶ名前を調べるメソッドを実行する
2return name; が実行されるname の値が返る
3slayerName に代入される返ってきた 水月 が入る

つまり、getName はただ表示するだけではありません。
name の値を呼び出し元へ返し、その値を変数 slayerName に入れて使えるようにしています。

getStamina は体力を返すメソッド

getStamina も同じ考え方です。

int getStamina()
{
    System.out.println("体力を調べました。");
    return stamina;
}

このメソッドは、int 型の値を返します。

int getStamina()

体力は整数なので、戻り値の型は int です。

中では、次のような流れで処理されます。

順番処理内容
1表示する体力を調べました。
2return stamina;stamina の値を呼び出し元へ返す

main メソッドでは、次のように受け取っています。

int slayerStamina = mizuki.getStamina();

この1行では、getStamina の戻り値が slayerStamina に入ります。

呼び出し戻り値代入先
mizuki.getName()name の値slayerName
mizuki.getStamina()stamina の値slayerStamina

このように、戻り値は変数に代入して使えます。

実行結果

Sample6.java を実行すると、次のような結果になります。

隊士の名前を水月に体力を100にしました。
隊士の名前を調べました。
体力を調べました。
調査結果
名前は水月体力は100でした。

この実行結果から、処理の流れが見えてきます。

最初に setNameStamina で名前と体力を設定しています。
次に getName で名前を調べ、その値を slayerName に入れています。
さらに getStamina で体力を調べ、その値を slayerStamina に入れています。
最後に、受け取った2つの値を使って調査結果を表示しています。

鬼滅の刃でたとえると、次のような流れです。

プログラムの処理鬼滅の刃でたとえると
setNameStamina("水月", 100)隊士名簿に名前と体力を登録する
getName()隊士の名前を確認して報告する
getStamina()隊士の体力を確認して報告する
表示処理報告書として結果を読み上げる

図:戻り値はメソッドから呼び出し元へ戻る

↓クリックすると拡大表示されます。

この図が示していること

この図では、mizuki.getName() を呼び出したあと、getName メソッドの中で return name; が実行され、name の値が呼び出し元へ戻る流れを表しています。

戻ってきた値は、slayerName に代入されます。

ここから分かるのは、戻り値はメソッドの中にある情報を呼び出し元へ持ち帰る仕組みだということです。
メソッドを呼ぶだけで終わるのではなく、結果を受け取って次の処理に使えるところが大切です。

戻り値は変数に入れて使える

戻り値の便利なところは、返ってきた値を呼び出し元で使えることです。

String slayerName = mizuki.getName();
int slayerStamina = mizuki.getStamina();

この2行では、戻り値をそれぞれ変数に入れています。

戻り値を返す処理返ってくる値受け取る変数
mizuki.getName()name の値slayerName
mizuki.getStamina()stamina の値slayerStamina

変数に入れることで、その値をあとから使えます。

たとえば、今回のプログラムでは表示に使っています。

System.out.println("名前は" + slayerName + "体力は" + slayerStamina + "でした。");

戻り値は、表示だけでなく、計算や条件分岐にも使えるようになります。

たとえば今後、体力が一定以上なら出撃できる、体力が少なければ休ませる、という判断にもつなげられます。

鬼滅の刃でたとえると、隊士から体力の報告を受け取り、その報告をもとに次の任務へ出すか、休ませるかを判断できるようになるイメージです。

図:戻り値は変数に入れて再利用できる

↓クリックすると拡大表示されます。

この図が示していること

この図では、mizuki.getStamina() によって返された stamina の値が、slayerStamina という変数に入る流れを示しています。

戻り値を変数に入れると、その場で表示して終わるだけではなく、あとから別の処理でも使えるようになります。

ここから分かるのは、戻り値は「結果を受け取るための仕組み」であり、受け取った値を再利用できるところに大きな意味があるということです。

戻り値を使わずに呼び出すこともできる

戻り値があるメソッドは、必ず変数に代入しなければならないわけではありません。

たとえば、次のように呼び出すこともできます。

mizuki.getStamina();

この場合、getStamina メソッドの中身は実行されます。

int getStamina()
{
    System.out.println("体力を調べました。");
    return stamina;
}

そのため、体力を調べました。という表示は行われます。

ただし、return stamina; によって返された値は、呼び出し元で受け取られていません。
つまり、戻り値は返ってきているけれど、使われずに終わっています。

呼び出し方戻り値の扱い
int slayerStamina = mizuki.getStamina();戻り値を変数に入れて使う
mizuki.getStamina();メソッドは実行されるが、戻り値は使わない

戻り値を使わない呼び出しもできますが、getName や getStamina のようなメソッドは、返ってきた値を使うために用意することが多いです。

鬼滅の刃でたとえると、隊士が体力を報告してくれたのに、その報告書を読まずに置いておくような状態です。
動きとしては間違いではありませんが、せっかくなら受け取った結果を活用したほうが便利です。

戻り値がないメソッドでは void を使う

戻り値を返さないメソッドでは、戻り値の型のところに void を書きます。

Sample6.java では、setNameStamina と show が void のメソッドです。

void setNameStamina(String n, int s)

void show()

void は、値を返さないという意味です。

メソッド戻り値主な役割
getName()あり名前を返す
getStamina()あり体力を返す
setNameStamina(String n, int s)なし名前と体力を設定する
show()なし名前と体力を表示する

setNameStamina は、名前と体力を設定することが目的です。
show は、現在の状態を表示することが目的です。

どちらも、呼び出し元へ値を返す必要がないので void を使っています。

void のメソッドでも return; は書ける

戻り値のない void メソッドでも、何も値を返さない return; を書くことはできます。

たとえば、次のような形です。

void setNameStamina(String n, int s)
{
    name = n;
    stamina = s;
    System.out.println("隊士の名前を" + name + "に体力を" + stamina + "にしました。");

    return;
}

この return; は、ここでメソッドを終了して呼び出し元へ戻ります、という意味です。

ただし、この例では return; がなくても、最後の } まで進めば自然にメソッドは終わります。
そのため、今回のような単純な処理では return; を省略しても問題ありません。

書き方意味
return 値;値を返してメソッドを終える
return;値を返さずにメソッドを終える
void メソッドの最後まで進む値を返さずに自然に終わる

ここで注意したいのは、戻り値の型が int や String のメソッドでは、基本的にその型に合う値を return で返す必要があることです。

たとえば、int getStamina() なら int 型の値を返します。

return stamina;

String getName() なら String 型の値を返します。

return name;

型と返す値が対応しているかを見ることが大切です。

引数と戻り値は逆向きのやり取り

引数と戻り値は、メソッドを理解するうえでとても重要な組み合わせです。

しくみ向き役割
引数呼び出し元 → メソッドsetNameStamina("水月", 100)値を渡す
戻り値メソッド → 呼び出し元getName(), getStamina()値を返す

setNameStamina は、呼び出し元から 水月 と 100 を受け取ります。

mizuki.setNameStamina("水月", 100);

これは、呼び出し元からメソッドへ情報を送っています。

一方、getName と getStamina は、メソッドから呼び出し元へ値を返します。

String slayerName = mizuki.getName();
int slayerStamina = mizuki.getStamina();

これは、メソッドから呼び出し元へ情報が戻ってきています。

鬼滅の刃でたとえると、こうです。

Javaのしくみ鬼滅の刃でたとえると
引数司令部から隊士へ任務情報を渡す
戻り値隊士から司令部へ状態を報告する

この2つを使えるようになると、メソッドは一方通行の処理ではなく、情報をやり取りする仕組みとして見えてきます。

戻り値を使うと処理を広げられる

戻り値を使えるようになると、メソッドの結果をあとで利用できます。

たとえば getStamina が 100 を返した場合、その値は次のようなことに使えます。

活用例内容
表示に使う体力は100でした。と表示する
計算に使う体力に回復量を足す
条件分岐に使う体力が少ないなら休ませる
別のメソッドに渡す取得した体力を別の処理で使う

今回の Sample6.java では、戻り値を表示に使っています。

System.out.println("名前は" + slayerName + "体力は" + slayerStamina + "でした。");

今はシンプルな表示だけですが、戻り値の本当の便利さは、受け取った結果を次の処理につなげられるところにあります。

鬼滅の刃でたとえると、隊士から返ってきた体力報告を見て、

体力判断
100任務に出せる
50注意して出撃
20休ませる

という判断につなげられるようなものです。

このように、戻り値はプログラムに「次の判断材料」を与えてくれます。

メソッドは処理するだけでなく結果を返せる

戻り値を学ぶと、メソッドの見え方が少し変わります。

戻り値を知らない段階では、メソッドは「処理を実行するもの」「画面に表示するもの」と見えやすいです。

しかし戻り値が分かると、メソッドは「結果を作って返す部品」として使えるようになります。

メソッドの見方内容
戻り値なし処理を実行して終わる
戻り値あり処理した結果を呼び出し元へ返す

getName や getStamina は、ただ表示するためだけのメソッドではありません。
名前や体力という情報を、呼び出し元で使える形にして返すメソッドです。

ここが戻り値の大切なところです。

いちばん大事な感覚

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

ポイント内容
戻り値メソッドから呼び出し元へ返される値
戻り値の型返す値の種類をメソッド名の前に書く
return値を返してメソッドを終了する
変数への代入戻り値は呼び出し元で受け取って使える
void値を返さないメソッドに使う
引数との違い引数は渡す、戻り値は返す

鬼滅の刃でたとえると、setNameStamina は隊士に名前と体力を登録するための命令です。
getName や getStamina は、隊士から名前や体力を報告してもらうための命令です。

こちらから値を渡すだけでなく、メソッドから結果を返してもらえるようになると、プログラムの組み立て方が一気に広がります。

メソッドは、ただ処理を実行するだけのものではありません。
必要な情報を受け取り、処理を行い、その結果を呼び出し元へ返すこともできる、Javaのとても大切な部品です。