メソッド定義の全体像
メソッドは「処理に名前をつけて再利用できるようにする単位」です。入力(引数)を受け取り、必要なら結果(戻り値)を返します。Java では「戻り値の型」「メソッド名」「引数の並び」「本体(処理)」をセットで定義します。設計の肝は「単一責務(1メソッド=1つのはっきりした目的)」「明確な名前」「型の整合」です。
基本構文と各要素
最小の書式と動き
// 戻り値あり
static int add(int a, int b) {
return a + b;
}
// 戻り値なし(void)
static void greet(String name) {
System.out.println("Hello, " + name);
}
Java- 戻り値の型: 計算結果の型(返さないなら
void)。 - メソッド名: 動詞+目的語で「何をするか」が伝わる名前に。
- 引数リスト:
型 名をカンマで並べる。個数は0でも可。 - 本体:
{}内で処理を書く。戻り値ありならreturnが必須。
呼び出しとクラスの文脈
public class Demo {
public static void main(String[] args) {
int s = add(3, 8);
greet("Java"); // "Hello, Java"
System.out.println(s); // 11
}
static int add(int a, int b) { return a + b; }
static void greet(String name) { System.out.println("Hello, " + name); }
}
Javamain はエントリポイント。static メソッドは「インスタンスを作らずに」クラスから直接呼べます。
引数と戻り値(重要ポイントの深掘り)
値の受け渡しとイミュータブル/ミュータブル
- 値渡し: Java の引数はすべて「値渡し」。プリミティブは値そのもの、参照型は「参照の値」が渡る。
- 参照型の変更: 参照先オブジェクトの中身を変えると呼び出し側からも見える。参照そのものを別のインスタンスへ差し替えても、呼び出し元の変数は変わらない。
class Box { int v; }
static void bump(Box b) { b.v++; } // 中身の変更は反映される
static void reassign(Box b) { b = new Box(); b.v = 999; } // 参照の再代入は呼び出し元に影響しない
Box box = new Box();
bump(box); // box.v は増える
reassign(box); // box.v は変わらない
Java戻り値の設計
- 単一の意味: 1つのメソッドは1つの意味ある結果を返す。複数の結果が必要なら「結果オブジェクト」を作る。
- void の使いどころ: 出力や状態変更のみで「計算結果」がないとき。副作用に依存し過ぎない設計が望ましい。
static boolean isAdult(int age) { return age >= 18; }
static String label(int score) {
if (score >= 80) return "A";
if (score >= 70) return "B";
if (score >= 60) return "C";
return "D";
}
Javaメソッドのバリエーションと設計
オーバーロード(同名・引数違い)
同じ名前で「引数の型・個数・並び」が異なるメソッドを複数定義できます。意味が近い処理を一つの名前でまとめられます。
static int sum(int a, int b) { return a + b; }
static double sum(double a, double b) { return a + b; }
static int sum(int... nums) {
int s = 0;
for (int n : nums) s += n;
return s;
}
Java- 可変長引数(
int...): 0個以上の引数を受け取れる。配列として中で扱う。複雑な組み合わせが必要なら「配列/コレクションをそのまま受ける」方が明快。
アクセス修飾子と static/instance
public class Counter {
private int value; // インスタンスの状態
public void inc() { value++; } // インスタンスメソッド(this を使う)
public int get() { return value; }
public static int add(int a, int b) { return a + b; } // クラスメソッド
}
Java- public / private / package-private / protected: 外からの見え方を制御。原則は「最小公開(必要最小限だけ public)」。
- static: インスタンス不要。ユーティリティ・純粋関数に向く。インスタンスの状態(
this)には触れられない。 - インスタンスメソッド: 個別の状態を扱う。オブジェクト指向の中心。
例外・検証・契約(重要ポイントの深掘り)
前提の検証(早期リターン)
メソッドの入口で「不正な入力」を弾くと、以降のロジックがシンプルになります。
static int divide(int a, int b) {
if (b == 0) throw new IllegalArgumentException("b must not be 0");
return a / b;
}
Java- チェック例外 vs 実行時例外:
IOExceptionなどは宣言/捕捉が必要(チェック例外)。入力の不正はIllegalArgumentExceptionなど実行時例外が適切。 - 契約の明示: 引数の前提を Javadoc や名前で表現。「null を許容するか」「範囲はどうか」を決めて一貫性を保つ。
返り値の null と代替
- 返り値に
nullを返すなら呼び出し側のガードが必要。代替として「空オブジェクト」「Optional(API設計向け)」を検討。
static String findOrDefault(String[] arr, String key, String def) {
for (String s : arr) if (key.equals(s)) return s;
return def; // nullを返さずデフォルトで安全
}
Javaスコープ・ライフサイクルと副作用
変数のスコープ
- ローカル変数: メソッド内だけ有効。外から見えない。副作用の拡散を防ぐ。
- フィールド(インスタンス/クラス変数): メソッドをまたいで状態を保持。必要最小限にし、同期や一貫性に注意。
static void demo() {
int x = 10; // ローカル(このメソッド内だけ)
// System.out.println(y); // 他メソッドのローカルは見えない
}
Java副作用の管理
- 純粋関数を優先: 入力→出力が明確で、外部状態に依存しない/変更しない。
- I/O や状態変更: 目的が明確なメソッドに閉じ込める。名前に副作用を反映(例:save、update、print)。
実用例で身につける
例 1: 名前とスコアからラベル生成
public class Labeler {
public static void main(String[] args) {
System.out.println(makeLabel("sato", 75)); // sato:B
}
static String makeLabel(String name, int score) {
return name + ":" + grade(score);
}
static String grade(int score) {
if (score >= 80) return "A";
if (score >= 70) return "B";
if (score >= 60) return "C";
return "D";
}
}
Java例 2: 可変長引数で合計
public class VarargsSum {
public static void main(String[] args) {
System.out.println(sum(1,2,3)); // 6
System.out.println(sum()); // 0
System.out.println(sum(new int[]{4,5})); // オーバーロードで配列も
}
static int sum(int... nums) {
int s = 0;
for (int n : nums) s += n;
return s;
}
static int sum(int[] nums) { return sum(java.util.Arrays.stream(nums).toArray()); }
}
Java例 3: インスタンスメソッドで状態を管理
public class Counter {
private int value;
public void inc() { value++; }
public int get() { return value; }
public static void main(String[] args) {
Counter c = new Counter();
c.inc(); c.inc();
System.out.println(c.get()); // 2
}
}
Java設計の指針(重要部分のまとめ)
- メソッドは「単一責務」と「明快な名前」。引数と戻り値で意図を表現し、副作用は最小限に。
- 入口で前提を検証し、異常は早期に弾く。返り値の
nullは避け、代替や例外で契約を明確化。 - オーバーロードは「同じ意味の異バリエーション」に限定。可変長引数は便利だが乱用しない。
staticはユーティリティ・純粋関数、インスタンスメソッドは状態を扱う。公開範囲は最小に。- スコープを意識して、ローカル変数で処理を閉じる。読みやすさとテスト容易性が上がる。
