【问题标题】:What does two consecutive blocks of code {}{} do? [duplicate]两个连续的代码块 {}{} 有什么作用? [复制]
【发布时间】:2012-02-17 14:24:09
【问题描述】:

可能重复:
Anonymous code blocks in Java

我刚刚遇到以下情况。

if ( test ) {
    {
        // statements 1
    }
    {
        // statements 2
    }
}

这是我第一次看到这个。它是如何工作的?

【问题讨论】:

    标签: java


    【解决方案1】:

    这只是为了隐藏局部变量而编写两个不同的代码块。

    来自问题“Anonymous code blocks in Java”的回答:

    块限制变量范围。

    public void foo()
    {
        {
            int i = 10;
        }
        System.out.println(i); // Won't compile.
    }
    

    不过,在实践中,如果您发现自己使用了这样的代码块,那么 这可能表明您想将该块重构为 方法。

    【讨论】:

    • 不开玩笑。这是在学术环境或认证测试中出现的这些“巧妙的 Java 技巧”之一,但专业的 Java 开发人员可能永远不会使用。
    • 少数种情况下确实很有用,可以确保相邻的代码块实际上是独立的,避免剪切和粘贴错误,并避免重新编译时不必要的更改-排序块。
    • 当然,你可以用它来做一些很奇怪的事情,但我认为它不适合你在第一次构建应用程序时故意开始使用的任何设计模式。正如 Sapan 所说...如果您在代码中看到这一点,这是一个很好的迹象,表明是时候重构和清理垃圾了。
    • 我喜欢简单地使用这些块来构建代码。属于一起的行放在一个块中。将其分解为方法是矫枉过正的,并且会降低可读性。就我而言,这只是可读性的问题。
    • 不喜欢使用这个的人能解释一下原因吗?只是想让变量的范围清晰并由编译器强制执行并不能强烈反对将流程分解为另一种方法。我无缘无故地读了很多“blecch”,AFAICT,除了“我觉得很有趣”。
    【解决方案2】:

    这可以(稍微)有用的两个示例 - 在单元测试和 GUI 中,这两者都经常涉及重复代码:

    它在 GUI 构建中很有用,在这种情况下,很容易剪切和粘贴与一个组件相关的行而忘记为新组件更新它们,从而导致难以发现的错误,例如:

        JButton button1 = new JButton("OK");
        button1.setEnabled(false);
        button1.setAlignmentX(-1);
    
        JButton button2 = new JButton("Apply");
        button1.setEnabled(false);
        button1.setAlignmentX(-1);
    

    糟糕,我刚刚配置了两次button1。如果你把每个按钮放在它自己的块中,那么这个错误就会被编译器发现。同样,您可以在单独的方法中创建每个按钮,但这可能会让人很难看到发生了什么(特别是考虑到 Java 中缺少关键字参数):

    JButton button_ok = makeButton("OK", false, -1);
    JButton button_apply = makeButton("Apply", true, 1);
    // what exactly is being set here?
    
    ...
    
    // much later:
    private static JButton makeButton(String name, boolean enabled,
            int alignment)
    {
        JButton button = new JButton(name);
        button.setEnabled(enabled);
        button.setAlignmentX(alignment);
        return button;
    }
    

    ...您最终可能会使用多种方法,每种方法处理不同的参数变化,并且每种方法可能只使用两次。

    【讨论】:

    • 这样的错误非常烦人。可以看到大括号在这里暂时有用。在重构和整理过程中也很有用,但通常最好在最终代码中删除。如果您希望真正引起争议并在街区内继续或打破,它们也可能有用。
    • 如果您正在生成代码并且不想在特定脚本中包含两次相同的节点时不希望意外地声明变量两次,它也很有用。我们的测试自动化团队遇到了类似的错误。
    • 对于这种情况,使用构建器可能是一个更好的解决方案 - 它会为您提供更好的可读性并消除您试图防止的错误类别,
    【解决方案3】:

    这两个块是独立的。因此,您在第一个块中可能拥有的任何变量都无法在第二个块中访问 - 或在第一个块之外的任何地方。它被称为代码隔离作用域

    【讨论】:

      【解决方案4】:

      {} 引入了一个作用域,在该作用域内声明的变量只存在于该作用域。例如:

      if ( test ) {
      
          int i = 0;
      
      
          float i = 0;
      }
      

      将无法编译,因为 i 已在同一范围内声明了两次。

      if ( test ) {
          {
              int i = 0;
          }
      
          {    
              float i = 0;
          }
      }
      

      可以正常编译,因为 i 没有在同一范围内声明两次。

      【讨论】:

        【解决方案5】:

        什么都没有。他们声明代码块。通常你不会使用它们。唯一的区别是,如果您在第一个变量中声明了一个变量 - 在第二个变量中将无法访问它。

        【讨论】:

          【解决方案6】:

          这两个块是顺序执行的。每个块都为局部变量定义了一个新的范围。所以你可以有

           int i;
          

          在两个区块中。

          【讨论】:

            【解决方案7】:

            那些是匿名块。它们用于限制范围。不仅在 java 中,在 C# 和 C 等其他语言中也是如此。

            【讨论】:

              猜你喜欢
              • 2018-01-14
              • 2013-07-29
              • 2011-10-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-06-27
              相关资源
              最近更新 更多