为什么Java中的try / catch或synchronized需要语句块?

时间:2012-06-11 21:38:45

标签: java jls

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中的某些关键字需要块语句,而其他关键字允许块语句和单个语句?这是语言设计的不一致,还是有某种原因?

3 个答案:

答案 0 :(得分:4)

如果你试图允许遗漏括号,你会得到一种悬而未决的模糊性。虽然这可以用与悬挂其他方式类似的方式解决,但最好不要这样做。

考虑

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块只是一个声明(可能是错误的)。

答案 1 :(得分:2)

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

我同意这个决定。不需要代码块可能会使代码更短,但这是一种引起混淆并产生无法预料的后果的可靠方法。

答案 2 :(得分:1)

即使使用允许存在混淆的语句,也不会使用{}。解决这个问题的方法是严格使用代码格式化程序。许多地方都要求{}始终避免出现问题。

e.g。

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是一种特色精益语言,我怀疑它的后者与前者相同或更多。