【问题标题】:Why do try/catch or synchronized in Java require a statement block? [closed]为什么 Java 中的 try/catch 或 synchronized 需要语句块? [关闭]
【发布时间】:2012-06-11 21:38:45
【问题描述】:

Java 允许某些关键字后跟语句或语句块。例如:

if (true)
    System.out.println("true");

do
    System.out.println("true");
while (true);

编译和

if(true) {
    System.out.println("true");
}

do {
   System.out.println("true");
} while (true);

forwhile 等关键字也是如此。

但是,某些关键字不允许这样做。 synchronized 需要一个块语句。 try ... catch ... finally 也一样,它需要在关键字之后至少有两个块语句。例如:

try {
    System.out.println("try");
} finally {
    System.out.println("finally");
}

synchronized(this) {
    System.out.println("synchronized");
}

有效,但以下内容无法编译:

try
    System.out.println("try");
finally
    System.out.println("finally");

synchronized (this)
    System.out.println("synchronized");

那么为什么Java中的一些关键字需要一个块语句,而另一些则允许一个块语句以及单个语句?这是语言设计的不一致,还是有一定的原因?

【问题讨论】:

  • 我怀疑单语句方法被不赞成和使用只是因为在 c 中可能有类似的东西。因为 c 没有同步或尝试他们可能选择了“更安全”的选项。
  • 因为这是语法; AFAIK 没有技术原因必须有一个块,因为它可以自动创建。
  • 这是我的猜测,FWIW:语言设计者希望保持与其他语言足够相似的语法以帮助学习。但是感觉在哪里添加了新的语言功能,他们会强制执行一些人认为更好的编码标准。或者,也许,对于不太常用的语言功能,他们追求更好的编码理念?
  • Scala 没有这样的限制;语法是组合式的,大括号被统一处理,这是我(显然是 OP)碰巧欣赏的语言设计原则。
  • 好吧,我不想开始讨论这是好是坏。我只是想知道这件事的根源,因为这对我来说似乎有些矛盾。

标签: java jls


【解决方案1】:

如果你试图允许省略括号,你会得到一个悬空的 else-like 歧义。虽然这可以通过与 dangling-else 类似的方式解决,但最好不要这样做。

考虑

try
try 
fn();
catch (GException exc)
g();
catch (HException exc)
h();
catch (IException exc)
i();

那是什么意思

try
    try 
        fn();
    catch (GException exc)
        g();
    catch (HException exc)
        h();
catch (IException exc)
    i();

try
    try 
        fn();
    catch (GException exc)
        g();
catch (HException exc)
    h();
catch (IException exc)
    i();

我相信 CLU,catch 块只有一个语句(可能是错误的)。

【讨论】:

  • if/else 块也有类似的问题。我认为鉴于这是一个常见问题,设计师希望避免这些问题。
  • 感谢汤姆的好榜样。但是,这并不能解释我关于同步表达式的问题。
【解决方案2】:

这只是语言的设计决策及其编译器机制。

我同意这个决定。不需要代码块可能会使代码更短,但它肯定会引起混乱并造成无法预料的后果。

【讨论】:

  • 我指的是编译器的设计,而不是没有它就可以工作。 Java 编译器就是不接受它。也许更好的措辞是“编译器设计决策”。
  • 当然这是语言的设计,但我很感兴趣为什么决定以这种方式实现它。
【解决方案3】:

即使使用允许这样做的语句,不使用 { } 也会存在问题,这可能会造成混淆。解决这个问题的方法是严格使用代码格式化程序。许多地方总是需要 { } 以避免出现问题。

例如

if (condition)
    if (condition2)
        statement
  else // which if
     statement

do
    statement
    while (condition) // is it do/while or an inner loop?
       statement
  while (condition2)
    statement

我相信您可以为某些语句而不是 C 中的其他语句执行此操作的原因。在 C 中,您可以在没有语句块的情况下使用 if/do/while/for。然而,Java 中已经添加了 try/catch 和 synchronized。这些只有 { } 块的原因有两个。

  • 这被认为是最佳实践
  • 只允许一个选项更简单。

鉴于 Java 是一种功能精简的语言,我怀疑后者与前者一样多或更多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 2012-12-31
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多