メソッドの全体像
メソッド(振る舞い)は、オブジェクトが「何ができるか」を表す動作の定義です。フィールド(状態)に対して、検証しながら安全に操作したり、結果を計算して返したりします。Java では「インスタンスメソッド(個体に紐づく)」「static メソッド(クラスに紐づく)」を使い分け、カプセル化(中身を隠す)と不変性(壊れない設計)を守ることで、読みやすく拡張しやすいコードになります。
メソッド定義の基本構文
シグネチャと可視性
public final class User {
private String name;
// 戻り値ありのメソッド
public String name() { // public: 外から呼べる
return name; // 戻り値型: String
}
// 引数あり・戻り値なし(副作用あり)
public void rename(String newName) {
if (newName == null || newName.isBlank()) return; // 検証(入力ガード)
this.name = newName.trim();
}
// 内部だけで使う共通処理
private static String normalize(String s) {
return s == null ? "" : s.trim().replaceAll("\\s+", " ");
}
}
Java- 可視性: public(外部公開)、private(内部限定)。公開最小が基本です。
- 戻り値: 計算結果や状態を返すなら値型、変更だけなら void。戻り値で失敗を表すより、例外か Optional の方が明確なことが多いです。
- 引数: 仕様を満たすために必要最小限。null 許容かどうかを決め、検証を入れます。
this とフィールド操作
public final class Point {
private int x, y;
public void move(int dx, int dy) {
this.x += dx; // this は「そのオブジェクト自身」
this.y += dy;
}
}
Java- this: フィールド名と引数名が同じでも、this.x で曖昧さが消えます。
インスタンスメソッドと static メソッド
インスタンスメソッド(個体の振る舞い)
オブジェクトの状態(フィールド)を使う動作はインスタンスメソッドにします。
public final class Rectangle {
private final int w, h;
public Rectangle(int w, int h) { this.w = w; this.h = h; }
public int area() { return w * h; } // 個体の状態を使う
}
Javastatic メソッド(共通のユーティリティ)
個体に依存しない計算は static にすると明確です。副作用のない純粋関数に寄せると再利用しやすくなります。
public final class MathUtil {
private MathUtil() {}
public static int clamp(int x, int min, int max) {
return Math.max(min, Math.min(max, x));
}
}
Java- 選び方: 個体の状態を使うならインスタンス、使わないなら static。混同しないことが可読性の鍵です。
カプセル化と検証(重要ポイントの深掘り)
「直接代入させない」代わりに「検証付きメソッド」を用意する
public final class BankAccount {
private int balance;
public BankAccount(int initial) {
if (initial < 0) throw new IllegalArgumentException("negative");
this.balance = initial;
}
public int balance() { return balance; }
public void deposit(int amount) {
if (amount <= 0) throw new IllegalArgumentException("amount>0");
balance += amount;
}
public boolean withdraw(int amount) {
if (amount <= 0 || amount > balance) return false; // 仕様に応じて例外か戻り値か
balance -= amount;
return true;
}
}
Java- 意図: フィールドを private にし、整合性を壊す変更を通さない。
- 指針: 入力の検証は入り口(メソッド)で。メソッドの契約(受け入れる値・失敗の扱い)を明文化します。
副作用と戻り値の設計
- 副作用のあるメソッド: void で「変える」。変更は必ず検証付き。
- 副作用のないメソッド: 値を返す「純粋関数」。テスト・再利用に強い。
public final class Price {
private final int value;
public Price(int value) { if (value < 0) throw new IllegalArgumentException(); this.value = value; }
// 副作用なし:新しい値を返す(不変を好む)
public Price addTax(double rate) {
int taxed = (int) Math.round(value * (1 + rate));
return new Price(taxed);
}
}
Javaオーバーロードとオーバーライド(多態性の入口)
オーバーロード(同名・引数違い)
状況に応じた呼び分けができる反面、曖昧さには注意します。
public final class Logger {
public void log(String msg) { System.out.println(msg); }
public void log(String fmt, Object... args) { System.out.printf(fmt + "%n", args); }
}
Java- 指針: 引数の最低数を必須にし、追加分を varargs にまとめると分かりやすい。
オーバーライド(親の振る舞いを型ごとに実装)
同じメソッド名でも、型ごとに「らしい」動作に切り替わります。
public abstract class Shape {
public abstract double area();
}
public final class Circle extends Shape {
private final double r;
public Circle(double r) { this.r = r; }
@Override public double area() { return Math.PI * r * r; }
}
public final class Rect extends Shape {
private final double w, h;
public Rect(int w, int h) { this.w = w; this.h = h; }
@Override public double area() { return w * h; }
}
Shape s = new Circle(10);
System.out.println(s.area()); // Circle版が呼ばれる
Java- @Override: 上書きの意図を明示して、ミスを防ぎます。
- 利点: 分岐を型へ追い出し、拡張は“型を増やす”で済む。
引数・戻り値の設計とエラー処理
null 許容と Optional
- 方針: 受け取る側・返す側のどちらが null を扱うかを決め、契約にする。
- Optional: 「値がない」可能性を型で表現し、null を避けられます。
import java.util.Optional;
public final class Repo {
public Optional<String> findName(String id) {
// 見つかったら Optional.of(name)、なければ Optional.empty()
return id.equals("U-1") ? Optional.of("Taro") : Optional.empty();
}
}
var name = new Repo().findName("U-2").orElse("(unknown)");
Java例外の使い分け
- 呼び手が回復可能なエラー: 戻り値で表すか、チェック例外(throws)で知らせる。
- 回復不能/契約違反: 非チェック例外(IllegalArgumentException など)で早期に失敗。
public final class FileLoader {
public String readUtf8(java.nio.file.Path p) throws java.io.IOException {
return java.nio.file.Files.readString(p, java.nio.charset.StandardCharsets.UTF_8);
}
}
Javaメソッドチェーンと Fluent API
可変なら this を返す、不変なら新インスタンスを返す
public final class MailBuilder {
private String to, subject, body;
public MailBuilder to(String v) { this.to = v; return this; }
public MailBuilder subject(String v) { this.subject = v; return this; }
public MailBuilder body(String v) { this.body = v; return this; }
public Mail build() { return new Mail(to, subject, body); }
}
var mail = new MailBuilder().to("a@b").subject("Hi").body("Hello").build();
Javapublic record Money(int amount, String currency) {
public Money add(int delta) { return new Money(amount + delta, currency); }
}
var m = new Money(100, "JPY").add(50);
Java- 指針: チェーン途中で副作用を混ぜない。変換の連鎖→最後に出力が読みやすい。
例題で身につける
例 1: 商品の価格計算(副作用なしの設計)
public final class Product {
private final String id;
private final int basePrice;
public Product(String id, int basePrice) {
if (id == null || id.isBlank()) throw new IllegalArgumentException("id");
if (basePrice < 0) throw new IllegalArgumentException("price>=0");
this.id = id;
this.basePrice = basePrice;
}
public int priceWithTax(double rate) {
return (int) Math.round(basePrice * (1 + rate));
}
public String id() { return id; }
}
Java「計算は返すだけ」にすると、テストが簡単で安全です。
例 2: 文字列ユーティリティ(static 純粋関数)
public final class Strings {
private Strings() {}
public static String normalize(String s) {
return s == null ? "" : s.trim().replaceAll("\\s+", " ");
}
public static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
}
Java個体に依存しない共通処理は static に集約。
例 3: 形の面積とラベル(オーバーライド)
public abstract class Shape {
public abstract double area();
public String label() { return "shape"; }
}
public final class Circle extends Shape {
private final double r;
public Circle(double r) { this.r = r; }
@Override public double area() { return Math.PI * r * r; }
@Override public String label() { return "circle"; }
}
Java「同じ呼び出しで型ごとに違う結果」が多態性の体験です。
よくあるつまずきと回避
「何でも public」にする
公開が広いほど依存が増え、変更が難しくなります。必要最低限だけ公開し、内部は private へ。
副作用だらけのメソッド
状態を変えるなら必ず検証を入れる。計算は返すだけに寄せると、テスト・並行性に強くなります。
オーバーロードの乱用
引数違いが多いと読み手が迷います。必須+varargs、メソッド名の分離、ビルダー導入で明確化します。
null を前提にする
契約を決め、Optional か早期正規化で「null 地獄」を回避します。
仕上げのアドバイス(重要部分のまとめ)
メソッドは「オブジェクトの振る舞い」。公開最小、入力検証、戻り値と例外の契約を明確にし、個体の状態を使う動作はインスタンス、共通計算は static に分ける。副作用は必要な場所だけ、不変に寄せると安全性が上がる。オーバーライドで分岐を型へ追い出し、チェーンは this 返し(可変)か新インスタンス返し(不変)で統一する——この型を守れば、読みやすく拡張しやすい振る舞い設計が身につきます。
