1. ホーム

[解決済み】インスタンス変数のインスタンス化は宣言時に行うべきか、コンストラクタで行うべきか?

2022-04-01 15:51:51

質問

どちらのアプローチにも利点がありますか?

例1:

class A {
    B b = new B();
}

例2:

class A {
    B b;

    A() {
         b = new B();
    }
}

解決方法は?

  • インスタンス変数の初期化は、実際にはコンパイラによってコンストラクタに入れられるので、差はありません。
  • 最初のバリエーションはより読みやすい。
  • 最初のバリエーションでは例外処理を行うことができません。
  • さらに、コンパイラによってコンストラクタに入れられる初期化ブロックがあります。

    {
        a = new A();
    }
    
    

チェック サンの説明とアドバイス

から このチュートリアル :

しかし、フィールド宣言はどのメソッドにも属さないので、ステートメントのように実行することはできません。その代わり、Javaコンパイラはインスタンス・フィールドの初期化コードを自動的に生成し、それをクラスのコンストラクタに配置します。初期化コードはソースコードに現れる順番にコンストラクタに挿入されます。つまり、フィールド初期化子はそれ以前に宣言されたフィールドの初期値を使用することができます。

さらに、次のような場合もあります。 遅延初期化 フィールドを作成します。フィールドの初期化が高価な操作である場合、必要なときにすぐに初期化することができます。

ExpensiveObject o;

public ExpensiveObject getExpensiveObject() {
    if (o == null) {
        o = new ExpensiveObject();
    }
    return o;
}

そして、最終的には(Billさんの指摘通り)依存関係の管理のためには 避ける を使用することで new 演算子は、クラス内のどの場所でも使用できます。代わりに 依存性注入 つまり、他の誰か(他のクラスやフレームワーク)があなたのクラスのインスタンスを作成し、依存性を注入するようにすることが望ましいのです。