可能重复:
Efficiency of Java “Double Brace Initialization”?
Meaning of new Class(…){{…}} initialization idiom
假设我通过以下方式创建了一个JMenu Bar:
JMenuItem saveMenuItem = new JMenuItem("Save")
{{
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
String location = GUI.Custom.QuickDialogs.selectFile(false);
try
{
PrintWriter pw = new PrintWriter(new File(location));
String text = textArea.getText();
pw.println(text);
pw.flush();
pw.close();
}
catch(Exception ex)
{
textArea.append("Could not save this debug output");
}
}
});
}};
JMenu optionsMenu = new JMenu("Options")
{{
add(saveMenuItem);
setVisible(true);
}};
private JMenuBar menuBar = new JMenuBar()
{{
add(optionsMenu);
setVisible(true);
}};
这是一个糟糕的设计模式,以这种方式创建对象,而不是仅仅声明变量,然后在构造函数或其他东西中创建?
答案 0 :(得分:2)
你所做的是:“初始化块”。
来自doc:
Java编译器复制初始化程序 阻塞到每个构造函数中。 因此,可以使用这种方法 共享一段代码 多个构造函数
示例:
class A {
private String field1;
{
field1 = "example field";
field2 = getstaticResult();
}
}
但在我看来,我们不应经常使用它,特别是在你的情况下使用它是非常不寻常的。
答案 1 :(得分:1)
你似乎在这里问(至少)两件不同的事情。双括号习语是已知的,通常用作创建匿名内部类的简写,用初始化块替换显式构造函数。通常这会使代码更具可读性,所以我会说它没问题。
OTOH因为(非静态)初始化块是该语言的一个相对新近的添加,但是一些开发人员可能不熟悉它们,这可能会造成混淆。当然,与几乎所有技术一样,当过度使用时,它会产生比解决的问题更多的问题。
答案 2 :(得分:1)
Double Brace Initialization实际上没有错误;我经常将它用于地图和列表。
这可能取决于您的受众是谁 - 您团队中的其他人是否了解您在这里所做的事情?请记住,有一天,某人将不得不阅读此代码。
答案 3 :(得分:0)
像大多数这种性质的问题一样,不幸的是我必须说“这取决于”。当你这样做的时候,你实际上是在创建一个新的匿名类,所以在内存和CPU方面有一个非常轻微的性能损失,但在大多数情况下,我会说这是无足轻重的。如果以这种方式这样做会使你的代码更具可读性,如果它是团队其他成员正在使用的风格,我会说它会继续使用它。
答案 4 :(得分:0)
两个问题
泄漏引用:由于这些是匿名内部类,因此它们保留对周围对象的引用,这将阻止它们被收集。这可能导致很难发现内存泄漏。
匿名类型:对于任何依赖于确切类的东西,这可能会导致问题。例如,序列化和equals的某些实现可能无法按预期工作。
如果您知道上述问题不会成为问题,那么使用此语法并没有错。