1

次のコードでは、getEntriesNotWorkingメソッドはコンパイル時エラーを報告します。

public class DoubleBracketInitializerTest {

    class Container {}

    class Entry {
        Container container;
        public Entry(Container container) {
            this.container = container;
        }
    }

    class DetailedContainer extends Container {

        List<Entry> getEntriesNotWorking() {
            return new ArrayList<Entry>() {{
                add(new Entry(this)); // compile-time error mentioned below
            }};
        }

        List<Entry> getEntriesWorking() {
            return Arrays.asList(new Entry(this));
        }

    }

}

エラー:

コンストラクタ DoubleBracketInitializerTest.Entry(new ArrayList(){}) は未定義です

getEntriesWorking()メソッドが正しくコンパイルされている間。DetailedContaileraは のサブクラスであるため、コンストラクターは明らかにそこにありContailerます。

コードを無効にするこれら2つの方法の違いは何ですか? このクラス階層で二重括弧初期化子を機能させるにはどうすればよいですか?

4

5 に答える 5

5

重中括弧の初期化:

return new ArrayList<Entry>() {{
            add(new Entry(this)); // compile-time error mentioned below
        }};

ArrayList<Entry>この場合のサブクラスである匿名の内部クラスを作成します。したがって、this参照はではArrayList<Entry>なくのサブクラスのインスタンスを参照しますDetailedContainer。クラスの現在のインスタンスのthis参照を取得するには、次を使用しますDetailedContainerDetailedContainer.this

return new ArrayList<Entry>() {{
            add(new Entry(DetailedContainer.this));  
        }};

もちろん、固定サイズのリストが必要ない場合は、次を直接使用できます。

return new ArrayList<Entry>(Arrays.asList(new Entry(this)));

匿名クラスの代わりに。その方がはるかに理解しやすいです。


以下も参照してください。

于 2013-10-17T09:23:02.850 に答える
3

問題は、内new ArrayList<Entry>() { ... }に. 手がかりは、探しているコンストラクター シグネチャを示すエラー メッセージにあります。thisArrayList<Entry>

この種の初期化を本当に使用したい場合は、次のことが必要です。

add(new Entry(DetailedContainer.this));

... の囲みインスタンスを参照しますDetailedContainer

また、本当に必要でない限り、内部クラスを避けることを強くお勧めします。トップレベルのクラスしかない場合、または本当に必要な場合はネストされた静的クラスがある場合、人生はずっと単純になります。

また、この種の匿名サブクラスの構築も避けたいと思いArrayListます。配列リストを作成してアイテムを追加するだけでなく、IMO よりもはるかに面倒です。または、次のようにGuavaを使用します。

return Lists.newArrayList(new Entry(this));

全体的にシンプルに!

于 2013-10-17T09:23:09.157 に答える
1
return new ArrayList<Entry>() {{
                add(new Entry(this)); // compile-time error mentioned below
            }};

匿名クラスの実装を作成しているようですので、匿名クラス内のこのキーワードは ArrayList 型のオブジェクトを参照します。そのため、利用可能な引数として ArrayList を含む Entry クラスのコンストラクターがないため、コンパイル エラーが発生します。

于 2013-10-17T09:52:21.717 に答える
0
return new ArrayList<Entry>() {{
      add(new Entry(this)); // compile-time error mentioned below
}};

代わりに次のことを試してください。

ArrayList<Entry> list = new ArrayList<Entry>();
list.add(new Entry(this));
return list;
于 2013-10-17T09:24:55.250 に答える