引数を受け取るメソッド
このレッスンで分かること
- 引数は
()の中に型 + 名前で宣言、複数なら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 のように省略はできません。JavaScript や Python だと「型は書かない」「コンマで区切って名前だけ並べる」のが普通なので、ここで戸惑う人が多いところです。
| 言語 | 引数の書き方 | 型省略 |
|---|---|---|
| Java | int a, int b | 不可 (毎回必要) |
| C / C++ | int a, int b | 不可 |
| JavaScript | a, b | (型自体なし) |
| Python | a, b | (型ヒントは任意) |
| TypeScript | a: 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;
}
}上のように、メソッドの中で n を n + 1 に上書きしたとしても、呼び出し側の変数はまったく影響を受けません。なぜなら、square(x) と呼んだときに渡っているのは x そのものではなく、x の値のコピーだからです。メソッド内の n は呼び出し側の x とは別の入れ物として扱われます。
「コピーが渡される」と聞くと無駄に感じるかもしれませんが、実は安全装置として効いています。メソッドの内部で引数をいじっても、呼び出し側の変数が勝手に書き換わらないので、
squareのような数学的な関数を安心して使えるのです。
値の流れを図にすると、こんなイメージになります。
評価の流れを箇条書きで言い換えると、次のとおりです。
- 呼び出し側で
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)は「numberのn」と読めて中身を表しているので OK です。逆にsquare(int year)と書くと「年? 何の?」となって混乱します。引数名は小さなドキュメントです。
動きを追ってみる
書いた square メソッドを square(3) square(-4) square(0) で呼んだときの動きを、頭の中で順番に追いかけてみます。Java の評価ルールでは、return の右側の式が先に計算され、その結果が呼び出し側に返ります。
square(3)→nに3がコピー →n * nは3 * 3→9が返るsquare(-4)→nに-4がコピー →n * nは(-4) * (-4)→16が返る (マイナス × マイナス = プラス)square(0)→nに0がコピー →n * nは0 * 0→0が返る
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) を完成させましょう。手順は次のとおりです。
- 右のエディタを開いて、
public static int square(int n)の本体にreturn n * n;と書く - 「実行」ボタンを押して、
square(3)→9、square(-4)→16、square(0)→0などのテストが全部緑になることを確認する - 動いたら、引数の名前を
nからvalueやxに変えて、それでもテストが通ることを試してみる
余裕があれば、次のような派生問題にも挑戦してみてください。
- 引数
int nを 2 個に増やして、int multiply(int a, int b)を作ってa * bを返す int nをdoubleに変えて、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 つができることを確認しましょう。
- 引数 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 引数 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- クラス名は
Solution、メソッド名はsquareにすること - 引数は
int nの 1 つだけ、戻り値の型はintにすること - 戻り値は
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