Java Academy · レッスン

適切なネスト方法の選択

結合度、アクセス要件、可読性に基づいて、ネストクラスの種類を選択します。

レッスン 4/414 ステップ

「適切なネスト方法の選択」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

適切なネスト方法の選択

Javaには、トップレベル、staticなネスト、内部(非static)、ローカル/匿名という4つのネスト方法があります。適切な方法は、結合の強さ、アクセス要件、再利用の範囲によって決まります。

判断の流れ

選択するときは、次の質問を確認してください:

  1. クラスは外側のクラス内部でのみ使用しますか。→ ネストを検討します
  2. 外側のインスタンスが必要ですか。→ 内部クラス、不要なら→ staticなネストクラス
  3. 1つのメソッド内でのみ使用しますか。→ ローカルクラスまたは匿名クラス
  4. 単一のメソッドを実装しますか。→ ラムダ式

トップレベルクラス

コードベース全体で広く使用する型、主要なドメイン概念を表す型、または多くのクラスからインポートされる型には、トップレベルクラスを使用します。

// Top-level: used across many packages
public class Product {
    // ...
}

public interface Repository<T, ID> {
    Optional<T> findById(ID id);
    void save(T entity);
}

// These belong in separate .java files and are widely imported

staticなネストクラス

次の場合はstaticなネストクラスを使用します。クラスが外側のクラスのコンテキストでのみ意味を持ち、外側のインスタンスを必要とせず、外部からアクセスできるようにする場合です。

class Graph {
    // Edge only makes sense in the context of a Graph
    public static class Edge {
        public final int from, to, weight;
        public Edge(int from, int to, int weight) {
            this.from = from; this.to = to; this.weight = weight;
        }
    }

    private List<Edge> edges = new ArrayList<>();

    public void addEdge(int from, int to, int weight) {
        edges.add(new Edge(from, to, weight));
    }
}

内部クラス(非static)

次の場合は内部クラスを使用します。クラスが外側のインスタンスと強く概念的に結び付き、そのprivateメンバーにアクセスする必要がある場合です。Iteratorや、密接に結合したヘルパーオブジェクトなどが該当します。

class DataStore<T> {
    private final List<T> data;

    DataStore(List<T> data) { this.data = data; }

    // Must access data — inner class makes sense
    class Snapshot {
        private final List<T> copy;

        Snapshot() { this.copy = List.copyOf(data); } // accesses outer

        T get(int idx) { return copy.get(idx); }
        int size()     { return copy.size(); }
    }

    Snapshot snapshot() { return new Snapshot(); }
}

ローカルクラス

次の場合はローカルクラスを使用します。クラスが1つのメソッドでのみ必要で、複数のメソッドや状態を持つ程度に複雑であり、スコープを最小限に保ちたい場合です。

static int countWords(String text, boolean caseSensitive) {
    class WordCounter {
        Map<String, Integer> counts = new HashMap<>();

        void count(String word) {
            String key = caseSensitive ? word : word.toLowerCase();
            counts.merge(key, 1, Integer::sum);
        }

        int uniqueCount() { return counts.size(); }
    }

    WordCounter wc = new WordCounter();
    for (String w : text.split("\\s+")) wc.count(w);
    return wc.uniqueCount();
}
System.out.println(countWords("the cat sat on the mat", false)); // 5

匿名クラスとラムダ式

複数のメソッドが必要な場合や、抽象クラスを拡張する場合は匿名クラスを使用します。SAMインターフェースにはラムダ式を使用します。

// Lambda: clean for SAM
list.sort((a, b) -> a.compareTo(b));

// Anonymous: multi-method, or extending abstract class
java.util.TimerTask task = new java.util.TimerTask() {
    @Override public void run() { System.out.println("Tick!"); }
};
// TimerTask is abstract class — can't use lambda directly

まとめ表

クイックリファレンス:

  • Top-level:広く再利用する型、パブリックAPIの型
  • Static nested:論理的にグループ化され、外側のインスタンスが不要
  • Inner:外側のインスタンスと強く結び付き、privateアクセスが必要
  • Local:メソッド内にスコープが限定され、クラスにする程度の複雑さがある
  • Anonymous:一度だけ使用する実装、短期間だけ使用するもの
  • Lambda:SAMインターフェース向けで、状態を持たず簡潔

実践:HTTPクライアントの設計

現実的なHTTPクライアントの設計にネスト方法を適用します。

class HttpClient {
    // Static nested: request config has no outer reference
    public static class RequestConfig {
        public final int timeoutMs;
        public final String userAgent;
        RequestConfig(int timeout, String ua) { this.timeoutMs = timeout; this.userAgent = ua; }
    }

    // Static nested: response is standalone data carrier
    public static class Response {
        public final int statusCode;
        public final String body;
        Response(int code, String body) { this.statusCode = code; this.body = body; }
    }

    private final RequestConfig config;
    HttpClient(RequestConfig config) { this.config = config; }

    public Response get(String url) {
        // Implementation using this.config
        return new Response(200, "body");
    }
}

過度なネストを避ける

1段階を超えるネストは避けてください。深くネストされたクラスは、把握やテストが難しくなります。複雑になった場合は、トップレベルクラスまたはパッケージプライベートクラスとして切り出してください。

パッケージプライベートという選択肢

ネストする代わりに、クラスをパッケージプライベート(アクセス修飾子なし)にする方法を検討してください。パッケージ内からのみ見えるため、ネストクラスよりもテストや保守が容易です。

// In package com.example.order:

// Package-private: visible in package, no nesting
class OrderLine {  // no 'public' modifier
    final String sku;
    final int qty;
    OrderLine(String sku, int qty) { this.sku = sku; this.qty = qty; }
}

// Public class in same package can use OrderLine freely
public class Order {
    private List<OrderLine> lines = new ArrayList<>();
    // ...
}

代替手段としてのレコードとsealed

レコードやsealedインターフェースなどの最新のJava機能を使うと、複雑なネストパターンが不要になることがよくあります。

// Instead of nested inner class hierarchy:
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double b, double h) implements Shape {}

static double area(Shape s) {
    return switch (s) {
        case Circle c      -> Math.PI * c.r() * c.r();
        case Rectangle r   -> r.w() * r.h();
        case Triangle t    -> 0.5 * t.b() * t.h();
    };
}

クイックチェック

staticなネストクラスよりも、内部クラス(非static)が適しているのはどのような場合ですか。

まとめ:適切なネスト方法の選択

重要なポイント:

  • トップレベル:コードベース全体で広く使用するパブリックな型
  • staticなネスト:外側のクラスと論理的にグループ化され、外側のインスタンスが不要
  • 内部クラス:外側のインスタンスと強く結び付き、privateメンバーにアクセスする
  • ローカルクラス:メソッド内にスコープが限定され、複数のメソッドを持つ程度に複雑
  • 匿名クラス:一度だけ使用し、宣言とインスタンス化を組み合わせる
  • ラムダ式:SAMインターフェースに最適で、匿名クラスの置き換えを検討できる
無料で開始

AI チューターと学ぶ Java — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
104
レッスン
374

よくある質問

「適切なネスト方法の選択」レッスンは無料ですか?

はい。「適切なネスト方法の選択」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「適切なネスト方法の選択」で何を学びますか?

結合度、アクセス要件、可読性に基づいて、ネストクラスの種類を選択します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「適切なネスト方法の選択」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. static ネストクラス
  2. 内部クラスと外部クラスへのアクセス
  3. ローカルクラスと匿名クラス
  4. 適切なネスト方法の選択
← Java Academyに戻る