Java / LESSON 07 / JV07

Java:メソッド

1学習の目的

2基礎解説

部分書き方意味
戻り値の型static int add(…)返す値の型
戻り値なしstatic void show(…)何も返さない
引数add(int a, int b)受け取る値
返すreturn a + b;結果を返す
✅ 覚えるべき重要ポイント
  1. メソッドは「戻り値の型 名前(引数) { … }」の形main から呼ぶメソッドには static を付ける(理由はJV08で分かる)。
  2. 戻り値がないなら void。画面に出力するだけのメソッドは void でよい。値を返すなら return が必須。
  3. 同じ名前で引数が違うメソッドを作れる(オーバーロード)。calc(int)calc(int, int) は別のメソッドとして扱われる。
  4. ⚠ 基本型は「値のコピー」、配列は「場所」が渡る。メソッド内で int を変えても呼び出し元は変わらないが、配列の中身を変えると呼び出し元も変わる
  5. 1つのメソッドは1つの仕事に絞る。「税込価格を計算する」「一覧を表示する」のように役割を明確にすると、名前も付けやすく再利用しやすくなる。

現場使用例:税込計算、入力値の検証、データの整形、共通処理の切り出し。同じコードを2回書きそうになったら、メソッドにする合図

public class Main {

    // 戻り値あり
    static int add(int a, int b) {
        return a + b;
    }

    // 戻り値なし(void)
    static void greet(String name) {
        System.out.println(name + "さん、こんにちは");
    }

    // オーバーロード(同名・引数違い)
    static int calc(int a)          { return a * 2; }
    static int calc(int a, int b)   { return a * b; }

    // 早期リターン(条件を満たしたらすぐ返す)
    static String judge(int n) {
        if (n < 0)  return "負";
        if (n == 0) return "ゼロ";
        return "正";
    }

    // 可変長引数(個数が決まっていない)
    static int sum(int... nums) {
        int total = 0;
        for (int n : nums) total += n;
        return total;
    }

    // ⚠ 配列を渡すと呼び出し元も変わる
    static void modify(int[] a) {
        a[0] = 999;
    }

    // 基本型は変わらない
    static void tryModify(int n) {
        n = 999;    // ローカルのコピーが変わるだけ
    }

    public static void main(String[] args) {
        System.out.println(add(3, 7));      // 10
        greet("山田");
        System.out.println(sum(1, 2, 3));   // 6

        int[] arr = {1, 2, 3};
        modify(arr);
        System.out.println(arr[0]);         // 999(変わる)

        int x = 1;
        tryModify(x);
        System.out.println(x);              // 1(変わらない)
    }
}

3基本ドリル(10問)

JV07-D01 2つの整数を受け取って合計を返すメソッド add を作り、add(3, 7) の結果を出力せよ。 コーディング★☆☆無料
期待される結果

出力 == 10

ヒント

static int add(int a, int b) { return a + b; } と書く。

模範解答
public class Main {
    static int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println(add(3, 7));
    }
}
解説

戻り値の型を先に書くのがJavaの形。int と宣言したら、必ず int を return する必要がある。

JV07-D02 何も返さないメソッドの戻り値の型はどれか。
A. null B. void C. none D. empty
選択★☆☆無料
期待される結果

解答 == B

ヒント

「空の」を意味する英単語。

模範解答
B
解説

void なら return を書かなくてよい。画面に出力するだけのメソッドはこの形になる。

JV07-D03 名前を受け取って「山田さん、こんにちは」と出力するvoid メソッド greet を作り、呼び出せ。 コーディング★☆☆無料
期待される結果

出力 == 山田さん、こんにちは

ヒント

static void greet(String name) { ... } と書く。return は不要。

模範解答
public class Main {
    static void greet(String name) {
        System.out.println(name + "さん、こんにちは");
    }

    public static void main(String[] args) {
        greet("山田");
    }
}
解説

void は「値を返さない」という意味。出力するだけなら、わざわざ値を返す必要はない。

JV07-D04 値を返すキーワードを補ってコードを完成させよ。 穴埋め★☆☆無料
コード
public class Main {
    static int twice(int n) {
        ____ n * 2;
    }

    public static void main(String[] args) {
        System.out.println(twice(21));
    }
}
期待される結果

出力 == 42

ヒント

「返す」を意味する6文字のキーワード。

模範解答
return
解説

return を書かないとコンパイルエラー。「int を返すと宣言したのに返していない」と指摘される。

JV07-D05 メソッド内で int の引数を変更すると、呼び出し元の変数はどうなるか。
A. 変わる B. 変わらない C. エラー D. 0になる
選択★☆☆無料
期待される結果

解答 == B

ヒント

基本型は値がコピーされて渡される。

模範解答
B
解説

基本型は値のコピーが渡されるので、メソッド内で変えても呼び出し元には影響しない。配列とは挙動が違う。

JV07-D06 オーバーロードを使い、同名メソッド calc を2つ作れ(引数1つなら2倍、引数2つなら掛け算)。calc(5) と calc(5, 3) の結果を2行出力すること。 コーディング★★☆広告解放
期待される結果

出力2行。10 / 15

ヒント

同じ名前でも引数の数が違えば別のメソッドとして定義できる。

模範解答
public class Main {
    static int calc(int a) {
        return a * 2;
    }

    static int calc(int a, int b) {
        return a * b;
    }

    public static void main(String[] args) {
        System.out.println(calc(5));
        System.out.println(calc(5, 3));
    }
}
解説

引数の数や型が違えば同じ名前を使えるSystem.out.println も、数値・文字列・真偽値を受け取れるオーバーロードの塊。

JV07-D07 個数が決まっていない引数を受け取るコードを完成させよ。 穴埋め★★☆広告解放
コード
public class Main {
    static int sum(int____ nums) {
        int total = 0;
        for (int n : nums) {
            total += n;
        }
        return total;
    }

    public static void main(String[] args) {
        System.out.println(sum(1, 2, 3, 4));
    }
}
期待される結果

出力 == 10

ヒント

可変長引数を表すピリオド3つ。

模範解答
...
解説

可変長引数は配列として扱われるsum(1,2) でも sum(1,2,3,4,5) でも同じメソッドで受けられる。

JV07-D08 メソッドに配列を渡して中身を変更すると、呼び出し元はどうなるか。
A. 変わらない B. 変わる C. エラー D. コピーが作られる
選択★★☆広告解放
期待される結果

解答 == B

ヒント

配列は「場所」が渡される(JV06の参照)。

模範解答
B
解説

配列は参照が渡るので、中身を変えると呼び出し元にも反映される。便利な反面、意図しない変更に注意が必要。

JV07-D09 早期リターンを使い、数値を判定するメソッド judge を作れ(負なら「負」、0なら「ゼロ」、正なら「正」)。-5、0、10 で試し、続けて出力すること。 コーディング★★☆広告解放
期待される結果

出力 == 負ゼロ正

ヒント

条件を満たしたらすぐ return する。else は不要。

模範解答
public class Main {
    static String judge(int n) {
        if (n < 0) {
            return "負";
        }
        if (n == 0) {
            return "ゼロ";
        }
        return "正";
    }

    public static void main(String[] args) {
        System.out.print(judge(-5));
        System.out.print(judge(0));
        System.out.println(judge(10));
    }
}
解説

return したらそこでメソッドが終わるので、else を書く必要がない。条件が増えてもインデントが深くならない。

JV07-D10 税込価格を計算するメソッド withTax を作れ(税率10%、四捨五入して long を返す)。128000円で試して出力すること。 コーディング★★☆広告解放
期待される結果

出力 == 140800

ヒント

Math.round の戻り値は long なので、メソッドの戻り値も long にする。

模範解答
public class Main {
    static long withTax(int price) {
        return Math.round(price * 1.1);
    }

    public static void main(String[] args) {
        System.out.println(withTax(128000));
    }
}
解説

計算式に名前を付けると意図が伝わるMath.round(price * 1.1) より withTax(price) のほうが、何をしているか一目で分かる。

4実践シナリオ(5問)

JV07-S01 【金額の整形メソッド】数値を「128,000円」の形式にして返すメソッド yen を作り、3つの金額(128000、3200、45000)で試して3行出力せよ。 コーディング★★☆広告解放
期待される結果

出力3行

ヒント

String.format("%,d", n) + "円" を返す。

模範解答
public class Main {
    static String yen(long n) {
        return String.format("%,d", n) + "円";
    }

    public static void main(String[] args) {
        System.out.println(yen(128000));
        System.out.println(yen(3200));
        System.out.println(yen(45000));
    }
}
解説

同じ整形を3回書かずに済む。書式を変えたくなったら、メソッドの中を1箇所直すだけで全体に反映される。

JV07-S02 【配列を受け取るメソッド】整数配列を受け取って合計を返すメソッド sum と、平均を返すメソッド average を作れ(配列 {80, 75, 91, 68} で試し、2行出力)。 コーディング★★☆広告解放
期待される結果

出力2行。314 / 78.5

ヒント

average は double を返す。sum メソッドを再利用できる。

模範解答
public class Main {
    static int sum(int[] nums) {
        int total = 0;
        for (int n : nums) {
            total += n;
        }
        return total;
    }

    static double average(int[] nums) {
        return sum(nums) / (double) nums.length;
    }

    public static void main(String[] args) {
        int[] scores = {80, 75, 91, 68};

        System.out.println(sum(scores));
        System.out.println(average(scores));
    }
}
解説

メソッドの中から別のメソッドを呼べる。average が sum を再利用しているので、合計の計算方法を変えても1箇所直すだけで済む。

JV07-S03 【参照の違いを確かめる】配列を変更するメソッドと、int を変更するメソッドを作り、呼び出し元への影響の違いを確認せよ(2行出力)。 コーディング★★☆広告解放
期待される結果

出力2行。999 / 1

ヒント

配列は参照が渡るので変わる。int は値のコピーなので変わらない。

模範解答
public class Main {
    static void modifyArray(int[] a) {
        a[0] = 999;
    }

    static void modifyInt(int n) {
        n = 999;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        modifyArray(arr);
        System.out.println(arr[0]);

        int x = 1;
        modifyInt(x);
        System.out.println(x);
    }
}
解説

同じ「変更する」操作でも結果が違う。配列を渡すメソッドを書くときは、呼び出し元のデータを壊していないかを常に意識する。

JV07-S04 【検証メソッド】商品名を検証するメソッド validate を作れ(空なら「未入力です」、20文字超なら「長すぎます」、それ以外は「OK」を返す)。3通りで試し3行出力すること。 コーディング★★★広告解放
期待される結果

出力3行。OK / 未入力です / 長すぎます

ヒント

trim() してから length() で判定する。21文字は "あ".repeat(21) で作れる。

模範解答
public class Main {
    static String validate(String name) {
        String trimmed = name.trim();

        if (trimmed.isEmpty()) {
            return "未入力です";
        }
        if (trimmed.length() > 20) {
            return "長すぎます";
        }
        return "OK";
    }

    public static void main(String[] args) {
        System.out.println(validate("ノートPC"));
        System.out.println(validate("   "));
        System.out.println(validate("あ".repeat(21)));
    }
}
解説

検証ロジックをメソッドに閉じ込めると、複数の画面から同じ検証を呼べる。ルールが変わっても1箇所直すだけで済む。

JV07-S05 【可変長引数】商品をいくつでも受け取り、合計と件数を返すメソッドを作れ(可変長引数を使い、「3件・176,700円」の形式で出力)。 コーディング★★★広告解放
期待される結果

出力 == 3件・176,700円

ヒント

int... prices で受け取る。件数は prices.length。

模範解答
public class Main {
    static String summarize(int... prices) {
        int total = 0;
        for (int p : prices) {
            total += p;
        }
        return prices.length + "件・" + String.format("%,d", total) + "円";
    }

    public static void main(String[] args) {
        System.out.println(summarize(128000, 3200, 45500));
    }
}
解説

引数の個数を気にせず呼べる。配列を作って渡す手間が省けるので、呼び出し側のコードが簡潔になる。

5仕上げ課題

JV07-FINAL 【メソッドで整理した注文処理】JV06の在庫レポートを、メソッドに分割して書き直せ。

作るメソッド(すべて static)
String yen(long n) … 「128,000円」の形式に整形
int stockValue(int price, int stock) … 在庫金額を返す
String stockLabel(int stock) … 0なら「品切れ」、10未満なら「残りわずか」、それ以外は「在庫あり」
int sum(int[] nums) … 配列の合計
String maxName(String[] names, int[] values) … 値が最大の名前を返す

データ
String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
int[] prices = {128000, 3200, 45000, 8500};
int[] stocks = {5, 42, 0, 18};

処理:各商品を「1. ノートPC:640,000円(残りわずか)」の形式で出力し、最後に総額と最高額の商品名を表示

期待される出力(6行)
1. ノートPC:640,000円(残りわずか)
2. マウス:134,400円(在庫あり)
3. モニター:0円(品切れ)
4. キーボード:153,000円(在庫あり)
---
在庫総額:927,400円(最高:ノートPC)
総合★★★広告解放
期待される結果

出力6行が完全一致

ヒント

在庫金額を配列に貯めてから、sum と maxName に渡す。stockLabel は早期リターンで書くと読みやすい。yen は long を受け取るようにすると汎用性が高い。

模範解答
public class Main {

    static String yen(long n) {
        return String.format("%,d", n) + "円";
    }

    static int stockValue(int price, int stock) {
        return price * stock;
    }

    static String stockLabel(int stock) {
        if (stock == 0) {
            return "品切れ";
        }
        if (stock < 10) {
            return "残りわずか";
        }
        return "在庫あり";
    }

    static int sum(int[] nums) {
        int total = 0;
        for (int n : nums) {
            total += n;
        }
        return total;
    }

    static String maxName(String[] names, int[] values) {
        int maxIndex = 0;
        for (int i = 1; i < values.length; i++) {
            if (values[i] > values[maxIndex]) {
                maxIndex = i;
            }
        }
        return names[maxIndex];
    }

    public static void main(String[] args) {
        String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
        int[] prices = {128000, 3200, 45000, 8500};
        int[] stocks = {5, 42, 0, 18};

        int[] values = new int[names.length];

        for (int i = 0; i < names.length; i++) {
            values[i] = stockValue(prices[i], stocks[i]);

            System.out.println((i + 1) + ". " + names[i] + ":"
                    + yen(values[i]) + "(" + stockLabel(stocks[i]) + ")");
        }

        System.out.println("---");
        System.out.println("在庫総額:" + yen(sum(values))
                + "(最高:" + maxName(names, values) + ")");
    }
}
解説

JV06と同じ結果を出力しているが、main の中身は劇的に短くなった。集計の計算も金額の整形も判定も、すべてメソッドに移したからだ。main を読めば「何をしているか」が分かり、詳細を知りたければ各メソッドを見ればよい——この構造が、プログラムを理解しやすくする。

メソッド名にも意味がある。stockLabel(stocks[i]) という呼び出しを見れば、中身を知らなくても「在庫のラベルを返すのだろう」と推測できる。もしこれが check(stocks[i]) という名前だったら、何を確認しているのか分からない。良い名前は、コメントの代わりになる。

maxName(names, values) の作りにも注目してほしい。最大値そのものではなく「最大値の添字」を記録している。こうすることで、値の配列と名前の配列の両方から、対応する要素を取り出せる。

ただし、このメソッドには弱点がある。names と values の長さが違ったら破綻するし、順序がずれていても気づけない。「名前と在庫金額は必ずセット」という関係を、引数を2つ渡すことでしか表現できていないのだ。

次章では、いよいよクラスを学ぶ。商品を1つのオブジェクトにまとめれば、この問題は根本から解決する。