Java中的花括号本身是啥意思?

Posted

技术标签:

【中文标题】Java中的花括号本身是啥意思?【英文标题】:What do curly braces in Java mean by themselves?Java中的花括号本身是什么意思? 【发布时间】:2010-09-19 10:59:17 【问题描述】:

我有一些 Java 代码以两种方式使用花括号

// Curly braces attached to an 'if' statement:
if(node.getId() != null)

    node.getId().apply(this);


// Curly braces by themselves:

    List<PExp> copy = new ArrayList<PExp>(node.getArgs());
    for(PExp e : copy)
    
        e.apply(this);
    

outAMethodExp(node);

第一个 if 语句之后的独立花括号是什么意思?

【问题讨论】:

【参考方案1】:

它们构成了一个内部作用域。在这些大括号内声明的变量在它们之外是不可见的。这也适用于 C/C++。

【讨论】:

【参考方案2】:

我认为他们只是定义了一个未命名的范围级别。

【讨论】:

【参考方案3】:

他们定义了一个新的范围,这意味着在这个范围内声明的所有内容在大括号之外都是不可见的。

【讨论】:

【参考方案4】:

额外大括号的唯一目的是提供范围限制。 List&lt;PExp&gt; copy 将只存在于这些大括号中,并且在它们之外没有范围。

如果这是生成的代码,我假设代码生成器会这样做,因此它可以插入一些代码(例如这个),而不必担心它插入了多少次 List&lt;PExp&gt; copy 并且不必担心可能如果此 sn-p 多次插入同一方法,则重命名变量。

【讨论】:

在这种情况下,另一个“好处”是copy 可以在outAMethodExp() 返回之前被垃圾收集。如果这是一个长时间运行或内存密集型的调用,那可能会有所帮助。我将“好处”放在引号中,因为重构为单独的方法通常比利用这种语法更清晰、更清晰。 实际上,对变量进行作用域对垃圾回收有影响。在我所知道的所有现代 JVM 中,JIT 可以确定一个对象是否符合 GC 条件,无论是否存在大括号等范围构造。【参考方案5】:

实际上我猜有人忘记了 else 语句。

很少有充分的理由去创建额外的块作用域。在这种情况下,大多数情况下,与他们正在做一些聪明的事情相比,有人可能忘记输入他们的控制语句的可能性要大得多。

【讨论】:

我投票给你只是因为它可能发生,已经发生了,而奥卡姆正在坟墓里翻滚,因为你被否决了。 :) 由 SableCC 生成。我打赌 5 美元,他们不会忘记其他的 附加大括号有助于防止全局变量在较长的方法中蔓延到您身上保证新方法。 我在一所大学标记了java课程,并且可以看到这实际上通常是在代码中找到它的确切原因。在重构时,人们有时会剪切/粘贴然后看到错误数量的大括号,......只需添加一个......然后看看你最终得到了什么。出于这个原因,我赞成投票。并不总是一个 else 语句,而通常只是一个简单的错误。 我支持你,因为 -1 票意味着你甚至不应该参与。也许你不知道,但你付出了努力。我并不是要为每个人赢得奖杯,但“谢谢”正是我对那些试图提供帮助的人说的。 (+1 == 谢谢)。【参考方案6】:

带一个作用域,copy在它外面是不可见的,所以你以后可以声明另一个同名的变量。它可以在您退出该范围后立即由垃圾收集器收集。在这种情况下,copy 充当了一个临时变量,所以这是一个很好的例子。

【讨论】:

【参考方案7】:

有趣的是:大括号实际上启用了一类语句:声明。

这是非法的:if(a) int f;

但这是合法的:if(a) int f;

【讨论】:

正好这段代码没用,你将看不到大括号外的 f。要使用它,您需要在同一范围内声明和使用它。所以你需要不止一个语句,所以你需要大括号。 这就是我提到的编译器检查的重点。我发现“隐式范围”(我认为每个没有大括号的单行)和显式范围之间存在差异,这很有趣。很容易忘记编译器会有所作为。 if (userWantsTocInReport) new Toc(report; 怎么样?我并不是说这是理想的编写方式,但无论出于何种原因,人们都可以选择它。跨度> 【参考方案8】:

我赞同 matt b 写的内容,我将补充一点,我看到的匿名大括号的另一个用途是在匿名类中声明一个隐式构造函数。例如:

  List<String> names = new ArrayList<String>() 
    // I want to initialize this ArrayList instace in-line,
    // but I can't define a constructor for an anonymous class:
      
        add("Adam");
        add("Eve");
      

  ;

一些单元测试框架已经将这种语法提升到了另一个层次,它确实允许一些看起来完全无法编译的巧妙的东西工作。因为他们看起来不熟悉,我自己也不是那么大的粉丝,但如果你遇到这种用法,至少知道发生了什么是值得的。

【讨论】:

对不起,我看不懂这段代码。是“添加”一个类或一个函数。如果它是一个函数:它属于哪个类?在这种情况下,ArrayList 是否接受委托类型? "add" 是一个函数。花括号中的内容在构造函数之前被调用以执行一些初步初始化。您可以查看c2.com/cgi/wiki?DoubleBraceInitialization 了解更多信息。 从技术上讲,首先调用构造函数,然后在调用super(...) 之后立即调用实例初始化块。【参考方案9】:

我同意范围限制的答案,但会补充一件事。

有时您会在代码中看到类似的结构,这些人喜欢折叠部分代码并拥有可以自动折叠大括号的编辑器。他们使用它将代码折叠在逻辑部分中,这些部分不属于通常会被折叠的函数、类、循环等。

【讨论】:

【参考方案10】:

它也用于initialization blocks。

【讨论】:

可能值得一提的是,这仅适用于构造函数之外的静态类初始化。 OP 代码 sn-p 位于方法块中(仅可能的位置)。 一个初始化块用于静态类初始化,如果它以static开头,否则它是一个instance初始化块。【参考方案11】:

大括号对于缩小 switch/case 语句的范围也很有用。

switch(foo) 
  case BAR:
     int i = ...
     ...
  case BAZ:
     int i = ... // error, "i" already defined in scope

但你可以写

switch(foo) 
  case BAR:
     int i = ...
     ...
  
  case BAZ:
     int i = ... // OK
  

【讨论】:

以上是关于Java中的花括号本身是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

Python0:4是啥意思?

Scala方法调用中的花括号[重复]

python 一条语句后加个中括号是啥意思a=b[b==0]?

正则表达式在非常大的html文件中匹配java中的花括号[重复]

使用 Kotlin 的 RxJava 中的花括号和普通括号有啥区别

函数的 JavaScript 参数中的花括号