引数を受け取るメソッド

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

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

  • 引数は () の中に 型 + 名前 で宣言、複数なら int a, int b のように型を毎回書きます
  • Java は 値渡し、メソッド内で引数を書き換えても呼び出し元には影響しません
  • 最小例は public static int square(int n) { return n * n; }

引数を受け取るメソッド とは

メソッドの () に値を渡して、外から計算の材料を渡せるようにする「引数」を学ぼう。square(int n) で n の 2 乗を返すメソッドを書く。

引数 ─ 外から値を渡す仕組み

前のレッスンで Solution.helloWorld() のような 引数なしメソッド を書きました。引数なしメソッドはいつ呼んでも同じ結果しか返せません。helloWorld() は何度呼んでも "Hello, Java!" を返すだけです。これだけだと、メソッドはちょっと長いコピペマシンにしかなりません。

ここで登場するのが 引数 (argument / parameter) です。() の中に「外から渡してもらう値」の入れ物を宣言しておくと、呼び出すたびに違う値を渡せます。たとえば square(3) と書けば 9 が返り、square(7) と書けば 49 が返る、というふうに「呼び出すたびに違う答えを計算するメソッド」が書けるようになります。これがメソッドを再利用するうえでの本当の威力です。

引数のことを日本語で「ひきすう」と読みます。英語では呼び出し側から渡す値そのものを argument、メソッド側で受け取る変数を parameter と区別します。Java の入門段階では「両方ひっくるめて引数」と覚えてしまって大丈夫です。

引数の宣言は「型 + 名前」

Java で引数を受け取るメソッドは、() の中に 型 + 名前 を書きます。String だろうと int だろうと、まず型を宣言してから変数名を続ける、というのが Java の鉄則です。

Java

public class Solution { public static int square(int n) { return n * n; } }

ここで int n の部分が引数の宣言です。「int 型の値を 1 つ受け取り、メソッドの中ではそれを n という名前で扱う」という意味になります。中身では n * n を計算して return で返しているので、square(3) と呼べば 3 * 3 = 9 が返ります。

引数を複数取りたいときは、, (カンマ) で区切って並べます。たとえば 2 つの数を足すメソッドはこんな形になります。

Java

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

int a, int b のように、それぞれの引数で 型を毎回書く のがポイントです。int a, b のように省略はできません。JavaScriptPython だと「型は書かない」「コンマで区切って名前だけ並べる」のが普通なので、ここで戸惑う人が多いところです。

言語引数の書き方型省略
Javaint a, int b不可 (毎回必要)
C / C++int a, int b不可
JavaScripta, b(型自体なし)
Pythona, b(型ヒントは任意)
TypeScripta: number, b: number推論で省略可

Java は静的型付け言語なので、コンパイラ がメソッドを見たときに「どんな型の値を受け取るのか」を完全に把握できる必要があります。だから「型を省略する」「型を後から書く」という書き方はそもそも許されません。最初は面倒に感じますが、後で必ず読みやすさと安全さで返ってくるルールです。

値渡し ─ 渡されるのはコピー

Java のメソッドに引数を渡すときの仕組みを、もう少しだけ深掘りしておきます。Java の引数の渡し方は 値渡し (pass by value) と呼ばれています。これは「呼び出し側の変数の 値のコピー がメソッド内の引数に入る」という意味です。

言葉だけだとピンと来ないので、コードで確かめましょう。

Java

public class Solution { public static int square(int n) { n = n + 1; // ここで n を書き換えてみる return n * n; } }

上のように、メソッドの中で nn + 1 に上書きしたとしても、呼び出し側の変数はまったく影響を受けません。なぜなら、square(x) と呼んだときに渡っているのは x そのものではなく、x の値のコピーだからです。メソッド内の n は呼び出し側の x とは別の入れ物として扱われます。

「コピーが渡される」と聞くと無駄に感じるかもしれませんが、実は安全装置として効いています。メソッドの内部で引数をいじっても、呼び出し側の変数が勝手に書き換わらないので、square のような数学的な関数を安心して使えるのです。

値の流れを図にすると、こんなイメージになります。

diagram (will load when visible)

評価の流れを箇条書きで言い換えると、次のとおりです。

  • 呼び出し側で int x = 3;
  • square(x) を呼ぶ瞬間に x の値 3 がコピーされて引数 n に入る
  • メソッド内で n をいじっても x は不変
  • return で戻り値 9 だけが呼び出し側に渡る

引数の名前は呼び出し側と無関係

初学者がよく混乱するのは、引数の名前と呼び出し側の変数名は別物 だということです。極端な例を見てみましょう。

Java

public class Solution { public static int square(int n) { return n * n; } } // 呼び出し側 int number = 5; int result = Solution.square(number); // 25

呼び出し側では変数の名前が number、メソッド側では n ですが、まったく問題なく動きます。メソッドが受け取るのは値だけで、変数の名前自体は渡っていきません。

逆に、メソッド側でも呼び出し側でも同じ名前 x を使ったとしても、それは「たまたま同じ綴り」というだけで、Java 内部では別の入れ物として扱われます。「変数名を揃えると同じ箱になる」みたいなことは起きないので、安心して好きな名前を付けてかまいません。

名前付けのコツとして、メソッド側の引数名は そのメソッドの中で意味が通じる名前 にしましょう。square(int n) は「numbern」と読めて中身を表しているので OK です。逆に square(int year) と書くと「年? 何の?」となって混乱します。引数名は小さなドキュメントです。

動きを追ってみる

書いた square メソッドを square(3) square(-4) square(0) で呼んだときの動きを、頭の中で順番に追いかけてみます。Java の評価ルールでは、return の右側の式が先に計算され、その結果が呼び出し側に返ります。

  • square(3)n3 がコピー → n * n3 * 39 が返る
  • square(-4)n-4 がコピー → n * n(-4) * (-4)16 が返る (マイナス × マイナス = プラス)
  • square(0)n0 がコピー → n * n0 * 00 が返る

Java* 演算子は数学の掛け算と同じで、負の数同士をかけると正の数になります。だから square(-4)-16 ではなく 16 です。テストケースで負の数を入れる意図は、ここを取りこぼさないかを確かめるためです。

よくある間違い

引数まわりで初学者がよくつまずく落とし穴を 3 つ整理しておきます。

  • 引数の型を省略するpublic static int square(n) のように int を書き忘れると、Java は「n の型がわからない」と怒ります。引数は 必ず型から書く、と覚えましょう。同じ理由で int a, b ではなく int a, int b のように毎回型を書きます
  • 引数の数を間違えて呼び出す — メソッド側が square(int n) のように 1 個の引数を期待しているのに、呼び出し側で Solution.square() (引数なし) や Solution.square(3, 4) (引数 2 個) と書くと、method square in class Solution cannot be applied to given types のようなエラーが出ます。引数の 個数と型 が完全に一致していないとコンパイルは通りません
  • 変数名が衝突すると思い込む — 呼び出し側に int n = 5; という変数があると、「メソッド側の n と被るからダメなんじゃない?」と心配する人がいます。実際には別物として扱われるので、まったく問題ありません。むしろ呼び出し側でもメソッド側でも、その場で自然な名前を使うほうが読みやすいコードになります

もうひとつ、地味だけどよくあるのが return の型と戻り値の型が合わない」 ミスです。public static int square(int n) と書いているのに return "九"; のように String を返すと、当然ながらコンパイルエラーになります。メソッドの宣言で約束した型を、最後まで守るのが Java 流です。

コンパイラのエラーメッセージは、最初は呪文に見えても、しばらく付き合うと「int のところに String 入れたな?」「引数の数が合ってないな?」とパッと見抜けるようになります。エラーは敵ではなく、コードを直すためのヒント集だと思って読みましょう。

この章のポイント

ここまでの要点 引数は 型 + 名前, で並べる、型省略は不可。Java は値渡しでコピーが渡るので呼び出し元は不変。引数名と呼び出し元の変数名は独立。

やってみよう

それでは課題に挑戦します。Solution.square(int n) を完成させましょう。手順は次のとおりです。

  1. 右のエディタを開いて、public static int square(int n) の本体に return n * n; と書く
  2. 「実行」ボタンを押して、square(3)9square(-4)16square(0)0 などのテストが全部緑になることを確認する
  3. 動いたら、引数の名前を n から valuex に変えて、それでもテストが通ることを試してみる

余裕があれば、次のような派生問題にも挑戦してみてください。

  • 引数 int n を 2 個に増やして、int multiply(int a, int b) を作って a * b を返す
  • int ndouble に変えて、double square(double n) で小数の 2 乗を返す
  • 自分で int cube(int n) を作って、n の 3 乗 (n * n * n) を返してみる

引数の仕組みは、これから書く すべてのメソッド の土台です。「() の中に外から値を流し込めるんだ」という感覚をここでしっかり掴んでおくと、次に学ぶ複数引数のメソッドや、String 引数、配列引数も同じ発想で読み解けるようになります。

よくある質問

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 標準を固めるのが効率的です。

次のレッスン

次は 戻り値を返す で、メソッドの () に値を渡して、外から計算の材料を渡せるようにする「引数」を学ぼう を学びます。

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

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

理解度チェック (30 秒)

Q. 引数 とは何か、1 文で説明してください。

この章のポイント

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

関連レッスン

要件

  1. クラス名は Solution、メソッド名は square にすること
  2. 引数は int n の 1 つだけ、戻り値の型は int にすること
  3. 戻り値は n の 2 乗 (n * n) であること。負の数を渡されてもプラスの値を返すこと

入出力例

test-cases.txt

square(3)9 square(-4)16 square(0)0 square(1)1 square(10)100 square(-7)49

ヒント

main.java
main.java
学習モード

メモ

引数を受け取るメソッド

⌘S で保存