1

In the following code the getEntriesNotWorking method reports a compile-time error:

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));
        }

    }

}

Error:

The constructor DoubleBracketInitializerTest.Entry(new ArrayList(){}) is undefined

While the getEntriesWorking() method is compiling correctly. The constructor is clearly there since a DetailedContailer is a subclass of Contailer.

What is the difference between those two methods, that makes the code invalid? How can I make the double bracket initializer work for this class hierarchy?

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>() { ... }this是一个ArrayList<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 回答
1

你可以这样做。

class DetailedContainer extends Container {

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

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

}
于 2013-10-17T09:26:30.157 回答
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 回答