双括号集合初始值设定项中的未定义构造函数错误

时间:2013-10-17 09:20:38

标签: java collections collection-initializer

在以下代码中,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()方法正在正确编译。构造函数显然在那里,因为DetailedContailerContailer的子类。

这两种方法有什么区别,使代码无效?如何使双括号初始化程序适用于此类层次结构?

5 个答案:

答案 0 :(得分:5)

双括号初始化

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

创建一个匿名内部类,在这种情况下,它是ArrayList<Entry>的子类。因此,this引用引用ArrayList<Entry>的子类的实例,而不是DetailedContainer。要获取this类当前实例的DetailedContainer引用,请使用DetailedContainer.this

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

当然,如果您不想要固定大小的列表,可以直接使用:

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

而不是匿名类。这更容易理解。


另见:

答案 1 :(得分:3)

问题是在new ArrayList<Entry>() { ... }内,thisArrayList<Entry>。线索在错误消息中,它指定了它正在寻找的构造函数签名。

如果你真的想要使用这种初始化,你需要:

add(new Entry(DetailedContainer.this));

...引用DetailedContainer的封闭实例。

除非你真的需要,我还强烈建议你避免内部课程。如果你只有顶级类,或者如果你真的需要嵌套静态类,那么生命就会简单得多。

我还避免使用这种匿名ArrayList子类构造 - 与仅仅创建数组列表并添加项目相比,它比IMO更麻烦。或者使用Guava,用:

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

全面简化!

答案 2 :(得分: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));
    }

}

答案 3 :(得分:1)

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

您似乎正在创建匿名类实现,因此匿名类中的此关键字引用ArrayList类型的对象。 因此,由于没有包含ArrayList的Entry类的构造函数作为参数可用,因此它提供了编译错误。

答案 4 :(得分: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;