考虑以下Scala代码(类似的代码示例适用于Java)
val a = try "hello" catch {
case e:Exception => throw new Exception("from catch")
} finally println("done")
最后在返回"hello"
后执行。但是什么时候它会被执行?它运行吗?
返回之后但在分配给a
之前? (看起来像那样)
它是否在与赋值相同的线程中执行?
答案 0 :(得分:1)
除了
System.exit()的
如果JVM由于某种原因崩溃(例如你的try块中的无限循环),则finally块将不会运行。
就线程本身而言,只有在使用 stop()方法停止时(或 suspend()而不使用 resume())将不执行finally块。对 interrupt()的调用仍然会导致finally块被执行。
还值得注意的是,由于finally块中的任何return语句都会覆盖try / catch块中的任何返回或异常抛出,如果发生这种情况,程序行为很快就会变得不稳定并且难以调试。没有什么值得采取预防措施(因为它只发生在非常罕见的情况下),但值得注意,以便在发生时能够识别它。
答案 1 :(得分:1)
try
块是一个表达式。 finally
作为该表达式的评估的一部分运行。在赋值发生之前评估赋值右侧的表达式。由此我们得出结论,finally
块作为评估的一部分,在作业发生之前运行。
是的,它在同一个线程中运行。我没有具体的参考,除了知道如果它没有这将是一个非常不幸的语言功能(并且反正很难实现)。
您使用"返回"令人困惑。什么都没有"返回&#34 ;;正在评估表达式,并将其结果值分配给某个东西。
关于表达式本身的详细信息,请参阅Scala language specification,第6.22节:
尝试表达......
try { b } finally e
...评估块
b
。如果 评估b
不会导致抛出异常,表达式e
被评估。如果在评估
e
期间抛出异常,则 对抛出的异常中止try表达式的评估。 如果在评估e
期间未引发任何异常,则b
的结果为。{1}} 作为try表达式的结果返回。如果是例外 在评估b
期间抛出,还评估了finally块e
。如果在评估e
期间抛出另一个异常e
, 对抛出的异常中止try表达式的评估。 如果在评估e
期间没有抛出异常,则原始b
的评估完成后,e
中抛出的异常将被重新抛出。 块b
应符合预期的try类型 表达。最终表达式e
应符合类型Unit
。尝试表达式:
try { b } catch e1 finally e2
是
的简写try { try { b } catch e1 } finally e2
可在该部分找到更多细节。