Java学习笔记Java学习笔记

Java的异常处理规则

2018-03-04  本文已影响17人  sortinnauto
  1. catchfinally不能没有try;
 void go(){
         Foo f = new Foo();   // 没有try
         f.foof();
         catch(FooException ex){}
}
  1. trycatch之间不能有程序;
  try{
      x.doStuff();
  }
  int y = 44;   //不能在这里放程序
  catch(Exception ex){}
  1. try一定要有catch或者finally;
  try{
      x.doStuff();
  }finally{         //这是合法的,但还是要注意第四条
    //清理
  }
  1. 只带有finallytry必须要声明异常。
  void go() throws FooException{
      try{
          x.doStuff();
      }finally{
        //  清理
     }
}

不想处理异常时,just duck it。(duck在此处有声明的意思)

当调用有危险的方法时,编译器通常会要求你对这件事有所表示。通常我们的方式是将这个有危险的方法调用放入try/catch块中。但是如果小小任性一下,我不愿意去用try/catch去调用此方法,捕获危险,那该怎么做呢?

还是那句话:

不想处理异常时,just duck it。

只需要在调用这一危险方法的方法上声明(duck)一下异常就可以了。也就是说,你在调用方法中不想try/catch,但是异常仍然还是存在,你不能坐视不管它带给调用方法的危险,所以调用方法只好throw这个危险方法可能会throw的异常,就想踢皮球一样,该潜在异常会被“踢”到调用方法的声明中去。以下为例:

 public void foo() throws ReallyBadException{
       //调用有危险的方法doLaundry()
       laundry.doLaundry();
       //这里并没有用try/catch块来处理doLaundry()这个方法,
       //这个存在异常的方法将异常“踢”给了调用方法foo()
 }

但是如果以此深究下去,它最终会把这脚烂球踢给谁呢?

分析一下原理:
方法抛出异常的时候,方法会从栈上立即被取出,而异常会再度丢给栈上的方法,也就是调用方。如果调用方是个ducker,则此ducker也会从栈被取出,异常再度抛给此时栈上方的方法。

看下面这个最简单的终极踢球例子:

public class Washer{
      Laundry laundry = new Laundry();
      
      public void foo() throws ReallyBadException{
        //调用有危险的方法doLaundry()
        laundry.doLaundry();
      }

      public static void main(String [] args) throws ReallyBadException{
           Washer washer = new Washer();
           washer.foo();
      }
}

方法们在栈中的顺序从顶至下依次为:doLaundry(),foo(), main()
方法的调用顺序是从栈顶开始,即


下面几句话帮助提升对异常处理的理解:

  • 如果遇到编译器的检查异常,就必须把有风险的程序代码包在try/catch块中。
    这句话是不对的,因为还有另一种方式,就是duck异常。
  • 只有编译器的检查异常才会被捕获。
    这句话是不对的,因为运行期间的异常也会被捕获。
  • 如果方法声明可以抛出编译器检查的异常,则必须把抛出异常的程序代码包在try/catch块中。
    这样做是不对的,其实只需要在方法中声明即可。这是另一种异常处理的方法。
上一篇 下一篇

猜你喜欢

热点阅读