为什么不能在try和catch块之间插入代码?

时间:2012-07-11 06:37:26

标签: java try-catch

我在面试中被问到一个问题如果我们在try和catch块之间放置finally块会发生什么情况我回答在这种情况下编译器会认为没有catch块并且它会直接执行finally块。 然后他问为什么不能在try和catch块之间放置代码?

你能帮帮我吗......

5 个答案:

答案 0 :(得分:11)

好的,首先是第一件事 - 编译器执行代码,它只是编译它,允许它由JVM运行。

从经验上讲,这没有多大意义,因为如果你有一些代码要放在try块之外但是在catch块之前,那么代码也可以放在try块中。问题是,如果您考虑它,它的行为就像在try块中一样。

假设这是有效的Java(这不编译):

try {
    throw new Exception();
}
System.out.println("Sup!");
catch(Exception e) { }

当抛出异常时,打印出Sup!的那一行仍会被跳过,因为JVM正在搜索跳转到相应的异常处理程序来处理Exception。因此,在某种程度上,代码的行为就像它在try {}块本身中一样,这就是为什么它在哪里并不重要,而且Java指定了这个(现在被证明是无用的)构造是非法的。

如果尝试之后的代码本身又抛出另一个异常怎么办?如果它是有效的代码,它的行为就像原始try块中的嵌套try ... catch块一样。当然,一旦事情开始变得复杂,try和catch块之间没有明确连接的方法可能会变得模糊,并且JVM最终不知道哪个catch / finally属于哪个try块(特别是因为处理程序不必在同一个函数中,甚至在同一个包中!)。

答案 1 :(得分:5)

嗯,轻率的回答是语言规范禁止它。

但让我们退后一步,以不同的方式思考 - 如果你可以做什么呢?

try {
  foo();
}
bar();
catch (Exception e) {
  baz();
}

这可能是什么语义?如果我们在foo()中捕获异常,是否baz()被调用?那么bar()呢?如果bar()抛出,那么我们是否会捕获异常?

如果bar()中的异常被捕获,foo()中的异常阻止bar()运行,则该构造等同于:

try {
  foo();
} catch (Exception e) {
  baz();
}
bar();

如果bar() 中的异常被捕获,foo()中的异常阻止bar()运行,则该构造等同于:

try {
  foo();
  bar();
} catch (Exception e) {
  baz();
}

如果bar()中的例外未被捕获,foo() 中的例外不会阻止bar()运行({{总是执行1}},然后构造等同于:

bar()

正如您所看到的,这种inter-try-catch构造的任何合理语义都已经可以表达,而不需要新的 - 而且相当混乱 - 构造。很难为这个尚未多余的构造设计含义。

顺便说一句,我们不能做的一个潜在原因:

try {
  foo();
} catch (Exception e) {
  baz();
} finally {
  bar();
}

可能是它没有反映实际的执行顺序 - 在 finally块之前运行的catch块。这允许catch块使用finally块稍后可能释放的资源(例如,从RPC对象或其他东西请求其他诊断信息)。也可以以其他方式工作?当然。这值得么?可能不是。

答案 2 :(得分:4)

嗯,这意味着这样的事情:

try
{
   somCode();
}
someMoreCode();
catch
{
}

这应该是什么意思? 这是不可能的,因为它没有语义,因此决定语言设计者在语法上不正确!

答案 3 :(得分:0)

答案 4 :(得分:0)

尝试捕捉...如果和其他.. 所以不需要在try和catch块之间添加代码