这段代码如果把异常捕获部分的Exception
替换为Throwable
会有什么不同?
import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable
object Main {
@throws(classOf[Exception])
def prepare() = false
def main(args:Array[String]) {
var i = 0
while(i < 3) {
breakable {
try{
i+=1
if(!prepare()) break
println("do something here")
}catch {
//case e: Throwable => e.printStackTrace
case e: Exception => e.printStackTrace
}
println("done")
}
}
}
}
问题的关键在于scala里的break
是通过异常机制实现的流控,与java里完全不同。break
是抛出了一个BreakControl
的异常,也是从Throwable
接口继承下来的。所以当应用在捕获异常时,try代码块里有break
流控语句,需要注意对流控异常不要干预,如果这种情况下真要捕获Throwable
的话,正确的方式是:
try{
if (...) break
...
}catch {
case e0: ControlThrowable => throw e0 // 不要干预流控的异常
case e1: Throwable => e1.printStackTrace
}