scala雾中风景(24): break与异常捕获

这段代码如果把异常捕获部分的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
}

scala雾中风景(24): break与异常捕获》上有1个想法

  1. 这个地方,有个坑:

    while(i < 3) {
    breakable {…}

    改成
    while(i < 3) {
    new Breaks().breakable {…}
    则Scala捕获不到break抛出的BreakControl异常,需要调用Breaks类的半生对象的breakable

发表评论

电子邮件地址不会被公开。 必填项已用*标注