【问题标题】:Double {{ }} syntax question in java [duplicate]java中的双{{}}语法问题[重复]
【发布时间】:2011-07-29 10:38:57
【问题描述】:

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

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

【问题讨论】:

标签: java swing syntax


【解决方案1】:

两个问题

  • 泄漏引用:由于这些是匿名内部类,它们保留对周围对象的引用,这将阻止它们被收集。这可能会导致难以发现内存泄漏。

  • 匿名类型:对于任何依赖于确切类的东西,这可能会导致问题。例如,序列化和 equals 的某些实现可能无法按预期工作。

如果您知道上述不会有问题,那么使用此语法没有任何问题。

【讨论】:

    【解决方案2】:

    你似乎在这里问(至少)两个不同的事情。双括号习惯用法是众所周知的,并且经常用作创建匿名内部类的简写,用初始化块替换显式构造函数。通常这会使代码更具可读性,所以我会说没关系。

    OTOH,因为(非静态)初始化程序块是该语言相对较新的添加,但一些开发人员可能不熟悉它们,这可能会造成混淆。当然,与几乎所有技术一样,如果过度使用,它可能会产生比它解决的问题更多的问题。

    【讨论】:

      【解决方案3】:

      Double Brace Initialization 实际上没有错误;我经常将它用于地图和列表。

      这可能取决于您的受众是谁——您团队中的其他人是否了解您在这里所做的事情?请记住,总有一天,有人将不得不阅读这段代码。

      【讨论】:

        【解决方案4】:

        你所做的被称为:“初始化块”。

        来自doc:

        Java 编译器复制初始化程序 阻塞到每个构造函数中。 因此,可以使用这种方法 在之间共享一段代码 多个构造函数

        例子:

        class A { 
            private String field1;
        
            {
                field1 = "example field";
                field2 = getstaticResult();
            }
        
        }
        

        但在我看来,我们不应该经常使用它,尤其是在你的情况下,使用它是非常不寻常的。

        【讨论】:

          【解决方案5】:

          像大多数此类问题一样,很遗憾我必须说“这取决于”。当你这样做时,你实际上是在创建一个新的匿名类,因此在内存和 CPU 方面的性能影响非常小,但在大多数情况下,我会说它微不足道,可以忽略不计。如果这样做会使您的代码更具可读性,并且如果它是您团队其他成员正在使用的样式,我会建议您使用它。

          【讨论】:

          • 另外,你说:“这些都是在类中静态创建的”。这不是真的,因为初始化器不是静态的,而是在匿名类实例上调用的。
          猜你喜欢
          • 1970-01-01
          • 2012-08-11
          • 2013-03-21
          • 2019-04-04
          • 2023-03-14
          • 2021-08-09
          • 1970-01-01
          • 2011-06-04
          • 2013-05-31
          相关资源
          最近更新 更多