java中的双{{}}语法问题

时间:2011-04-04 19:37:16

标签: java swing syntax

  

可能重复:
  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);
    }};

这是一个糟糕的设计模式,以这种方式创建对象,而不是仅仅声明变量,然后在构造函数或其他东西中创建?

5 个答案:

答案 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的某些实现可能无法按预期工作。

如果您知道上述问题不会成为问题,那么使用此语法并没有错。