戻り値を返す

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

このレッスンで分かること

  • return 値; でメソッドを抜け、宣言した型と一致する値を呼び出し元へ返します
  • 早期 return (ガード節) でネストを浅く保てる、voidreturn; だけ書ける
  • 最小例は if (n < 0) return -n; return n; (絶対値)

戻り値を返す とは

メソッドから値を返す return 文の使い方を学ぶ。早期 return、void での return、戻り値の型整合性まで一気に押さえよう。

メソッドから値を返す ─ return 文の世界

前のレッスンでメソッドの「呼び出し方」を学びました。今度はその逆、メソッドから値を「返す」側を学びます。Java のメソッドは大きく分けて、計算結果を呼び出し元に渡すタイプ (戻り値あり) と、何かを実行するだけで値は返さないタイプ (void) の 2 種類があります。どちらも return キーワードと密接に関係しています。

return はメソッドの中で実行されると、そこで処理を打ち切って呼び出し元に値を返します。if の中だろうが for ループの中だろうが、return が実行されればその場でメソッドは終わります。break と似ていますが、break がループを抜けるだけなのに対し、return はメソッドそのものを抜ける、というイメージで覚えると区別しやすいです。

たとえば足し算をするメソッドはこんな形になります。戻り値の型 int と、その型に合う値を return するセットが揃ってはじめて Java のコンパイラは満足します。

Java

public class Calculator { public static int add(int a, int b) { return a + b; } }

ここで重要なのは「int を返すと宣言したから int の値を return しなければならない」というルールです。return し忘れたり、別の型を返そうとすると、Java はコンパイル段階で容赦なくエラーを出してくれます。これは型の安全性を売りにする言語ならではの厳しさです。

return の基本ルール

return 文に関するルールを整理します。次のとおりです。

  • 戻り値の型が int String boolean のように指定されているメソッドは、必ず どこかで return を実行する
  • return で渡す値は、宣言された戻り値の型と一致 (もしくは互換) でなければならない
  • return が実行された瞬間、メソッドの残りの処理はすべてスキップされる
  • 戻り値の型が void のメソッドは return 値; を書けない (return; 単独はあり、後述)
戻り値の型return の書き方
intreturn 整数値;return 42;
Stringreturn "文字列";return "ok";
booleanreturn true / false;return n > 0;
voidreturn; (値なし) または省略return;
戻り値ありreturn 忘れは missing return statement

たとえば次のコードは、return の後ろの System.out.println には永遠に到達しません。コンパイラはこれを察知して「unreachable statement (到達不能なコード)」というエラーを出します。

Java

public static int answer() { return 42; System.out.println("never reached"); // コンパイルエラー }

エラーメッセージ「unreachable statement」が出たら、ほぼ 100% returnbreak の後ろにコードを書いてしまっています。return 文より下にコードは書けない、と最初から頭に入れておくと安心です。

早期 return ─ ネストを浅くする魔法

条件が複雑になってくると、if の入れ子 (ネスト) がどんどん深くなって読みづらくなります。そんなときに効くのが 早期 return (early return) という書き方です。条件を満たさない場合に先に return で打ち切ってしまえば、その後ろは「条件を満たした場合だけ」を考えればよくなり、コードが見やすくなります。

まずはネストが深い書き方を見てみましょう。

Java

public static String judgeAge(int age) { if (age >= 0) { if (age < 18) { return "未成年"; } else { return "成人"; } } else { return "年齢エラー"; } }

これを早期 return で書き直すと次のとおりです。「ありえないケース」を先に弾く構造になり、本筋がスッと読めるようになります。

Java

public static String judgeAge(int age) { if (age < 0) return "年齢エラー"; if (age < 18) return "未成年"; return "成人"; }

早期 return は「ガード節 (guard clause)」とも呼ばれる定番テクニックです。引数のバリデーション、null チェック、特殊ケースの処理など、メソッドの先頭で先に弾くと、後ろの処理が「正常系だけ」を扱う形にすっきりまとまります。

void メソッドでの return

戻り値を持たないメソッド (void) でも return; を書くことができます。値を返すわけではなく「ここで処理を打ち切る」という意味のシグナルです。引数チェックで「不正な値だったら何もせず帰る」みたいな書き方によく使います。

Java

public static void greet(String name) { if (name == null) { return; // 何もせずに抜ける } System.out.println("Hello, " + name); }

ここで return name; のように値を渡してしまうと、void メソッドは値を返せないので incompatible types: unexpected return value というエラーになります。「voidreturn は値なし」と覚えてください。

return のフローを図で見る

return 文がどのタイミングでメソッドを抜けるのか、フローチャートで確認しましょう。下の図は、絶対値を計算するメソッド abs の流れを描いたものです。負の数なら符号を反転して返し、それ以外 (0 以上) はそのまま返す、というロジックです。

diagram (will load when visible)

図のとおり、return はどちらの分岐に入っても 必ず 実行されます。どんな入力が来ても 1 本のパスで return にたどり着くことが重要です。途中で return し忘れるルートが 1 本でもあると、コンパイラは「missing return statement」と教えてくれます。

戻り値の型と return 値の型の整合性

もう一度しつこいくらいに強調します。戻り値の型と return の値の型は一致していなければなりませんJava は静的型付け言語なので、ここのチェックが非常に厳格です。

Java

public static int half(int n) { return n / 2.0; // double を int で返そうとしている → コンパイルエラー }

n / 2.0double 型になります。戻り値の型は int なので、そのままでは返せません。明示的に (int) でキャストするか、戻り値の型を double に変えるかの 2 択です。

Java

public static int half(int n) { return (int) (n / 2.0); // int にキャストして返す }

incompatible types: possible lossy conversion」というエラーは「ロス (情報の欠落) が起きる可能性のある型変換を勝手にやれない」という Java の警告です。意図して型を絞り込みたいときは (int) のような明示的キャストで、Java に「分かっててやってるから許して」と伝える必要があります。

よくある間違い

戻り値まわりで初心者がよくハマる落とし穴は次のとおりです。

  • return 文を書かない — 戻り値の型を Stringint と書いたのに、メソッド本体のどこにも return がないパターン。エディタのエラー欄に「missing return statement」と出たら、まず全ての分岐に return が届いているか確認しましょう。ifreturn して elsereturn しないと、それだけで未到達の分岐ができてしまいます
  • return の後にコードを書く (dead code)return 0; の次の行に System.out.println("...") のような処理を書いてしまうやつ。デバッグ用の println を消し忘れる事故が多いです。return の後に書いてあるコードは絶対に動きません
  • 戻り値型と return 値の型不一致int を返すと書いたのに "123" のような String を返してしまうケース。逆に String を返すメソッドで return 0; と書いてしまうのもよくあります。エラー「incompatible types」「cannot return a value of type X」が目印

もうひとつ、地味に多いのが「void メソッドで return value; と書いてしまう」「逆に値を返すメソッドで return; だけ書いてしまう」というパターン。エラー文には「incompatible types: unexpected return value」「missing return value」と書かれます。型と return の形が揃っているか毎回確認するクセを付けましょう。

この章のポイント

ここまでの要点 return は値を返してメソッドを抜ける、宣言した型と一致が必須。早期 return でネスト浅く、voidreturn; のみ。unreachable statement missing return statement incompatible types が三大エラー。

やってみよう

今回の課題は 絶対値を返す abs メソッド です。Solution.abs(int n) を完成させ、n の絶対値を返してください。手順は次のとおりです。

  1. public static int abs(int n) の本体を書く
  2. if (n < 0) return -n; で負の数を反転して返す
  3. return n; で残りを返す (= n >= 0 のケース)
  4. abs(-5) == 5abs(7) == 7abs(0) == 0 がテストで pass するか確認

Math.abs(n) を使えば 1 行で書けてしまいますが、今回はあえて return の書き分けを練習する場として手で書いてみましょう。書き終わったら「実行」ボタンを押してテストが緑になることを確認してください。

戻り値と return を自由に操れるようになると、メソッドはぐっと表現力豊かになります。次のレッスンからは複数の引数を受け取るメソッドや、引数なし戻り値なしの void メソッドにも踏み込んでいきましょう。

よくある質問

Q. Java と他言語の文法はどう違いますか?

A. Java は静的型付けで、変数宣言時に型を明示します(int x = 0;)。中括弧でブロックを表し、文末にセミコロンが必要です。Python の動的型付けや JavaScript の柔軟さに慣れていると最初は窮屈ですが、コンパイル時にバグが発見できる安全性がメリットです。

Q. コードが動かないときに最初に見るべき場所は?

A. コンパイルエラーは行番号とエラー種別(cannot find symbol、incompatible types など)が表示されます。実行時例外はスタックトレースの最初の at ... が原因行です。IDE(IntelliJ / VS Code)の警告も丁寧に潰すと、半分のバグは未然に防げます。

Q. Java の習得後に学ぶべき技術は何ですか?

A. 基本構文を抑えたら java-intermediate(コレクション / ジェネリクス / Stream / 例外)に進み、Spring Boot や Web 開発に展開するのが王道です。クラウド時代は Kotlin / Scala への展開も視野に入りますが、まずは Java 標準を固めるのが効率的です。

次のレッスン

次は 複数の引数を取るメソッド で、メソッドから値を返す return 文の使い方を学ぶ を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 戻り値 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 戻り値 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. クラス名は Solution、メソッド名は abs、引数は int n 1 つ、戻り値の型は int
  2. if 文で n が負かどうかを判定し、return で結果を返すこと
  3. Math.abs などの標準ライブラリは使わず、return の書き分けで実装すること

入出力例

test-cases.txt

abs(-5)5 abs(7)7 abs(0)0 abs(-100)100 abs(-1)1

ヒント

main.java
main.java
学習モード

メモ

戻り値を返す

⌘S で保存