Javaダブルブレースの初期化

Javaダブルブレースの初期化

1. 概要

このクイックチュートリアルでは、creating and initializing objects in a single Java expressionに二重中括弧を使用する方法を示します。

また、この手法がアンチパターンと見なされる理由についても説明します。

2. 標準的なアプローチ

通常、次のように国のセットを初期化および設定します。

@Test
public void whenInitializeSetWithoutDoubleBraces_containsElements() {
    Set countries = new HashSet();
    countries.add("India");
    countries.add("USSR");
    countries.add("USA");

    assertTrue(countries.contains("India"));
}

上記の例からわかるように、次のことを行っています。

  1. HashSetのインスタンスを作成します

  2. HashSetに国を追加します

  3. 最後に、その国がHashSetに存在するかどうかを主張します

3. ダブルブレースの使用

ただし、実際には単一のステートメントで作成と初期化を組み合わせることができます。これは、二重中括弧を使用する場所です。

@Test
public void whenInitializeSetWithDoubleBraces_containsElements() {
    Set countries = new HashSet() {
        {
           add("India");
           add("USSR");
           add("USA");
        }
    };

    assertTrue(countries.contains("India"));
}

上記の例からわかるように、次のとおりです。

  1. HashSetを拡張する匿名内部クラスの作成

  2. addメソッドを呼び出して国名をHashSetに追加するインスタンス初期化ブロックを提供する

  3. 最後に、その国がHashSetに存在するかどうかを確認できます

4. 二重中括弧を使用する利点

二重括弧を使用することには、いくつかの簡単な利点があります。

  • ネイティブの作成および初期化方法と比較して、コードの行数が少ない

  • コードが読みやすい

  • 作成の初期化は同じ式で行われます

5. 二重中括弧を使用することのデメリット

ダブルブレースを使用する場合の欠点は次のとおりです。

  • あまり知られていない初期化の方法

  • 使用するたびに追加のクラスを作成します

  • Java 7で導入された機能である「ダイヤモンド演算子」の使用をサポートしていません

  • 拡張しようとしているクラスがfinalとマークされている場合は機能しません

  • 含まれるインスタンスへの非表示の参照を保持します。これにより、メモリリークが発生する可能性があります

二重中括弧の初期化がアンチパターンと見なされるのは、これらの欠点によるものです。

6. 代替案

6.1. ストリームファクトリメソッド

代わりに、新しいJava 8 Stream APIをうまく利用してSetを初期化できます。

@Test
public void whenInitializeUnmodifiableSetWithDoubleBrace_containsElements() {
    Set countries = Stream.of("India", "USSR", "USA")
      .collect(collectingAndThen(toSet(), Collections::unmodifiableSet));

    assertTrue(countries.contains("India"));
}

6.2. Java9コレクションのファクトリメソッド

また、Java 9は、以下を可能にする便利なファクトリメソッドのセットを提供します。

List list = List.of("India", "USSR", "USA");
Set set = Set.of("India", "USSR", "USA");

このin this article.についてもっと読むことができます

7. 結論

この簡潔なチュートリアルでは、二重ブレースの使用法とその長所と短所について説明しました。

これらの例の実装はGitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。