Java异常:你是异常的失落

Java异常


Java异常1. 什么是异常2. 异常的分类3. 论叔侄之间的亲密关系4. 异常处理5. finally语句6. 一些注意事项7. 复习题

1. 什么是异常

在Java中,异常是一种对象,表示阻止正常运行的程序执行的错误或者情况。

更通俗来说就是经常让我们程序崩溃的东西,比如刚刚我的代码就挂了

image.png
  • 异常都有有哪些类型,都一定会弄死我的小可爱么

  • 我该怎么抢救一下 小可爱


2. 异常的分类

  1. Throwable类是所有异常类的父类,所有的异常都是它的后代。(Throwable:我 ,是你爸爸,或者爷爷)

  2. Error类:system error,描述的是系统内部错误,比如虚拟机炸了啊(VirtualMachineError)什么的。

    死亡率:百分之百

  3. Exception类:由程序和外部环境引起的错误,可以被程序捕获和处理。也就是说,这种异常!可以抢救一下! 小可爱:我觉得我还可以抢救一下

族谱

Java异常:你是异常的失落_第1张图片
throwable.jpg

3. 论叔侄之间的亲密关系

上回说到,ErrorException 是一对亲兄弟,都有着好几个儿子。其中Exception 的儿子RuntimeException 就格外喜欢他的叔叔Error,天天想着溜到他们家,就是这个样子

Java异常:你是异常的失落_第2张图片
shushu.png

上天也被他们之间的 爱情 感动到了,于是为了让他们近亲结婚 ,免去了婚检,从此ErrorRuntimeRxception 被划分为免检异常 ,其他异常为必检异常 。 这种关系是不正常的,所以免检异常是在程序中必须纠正的逻辑错误 。 PS:前面我发的那个截图就属于免检异常。

  • 免检异常:Java语言不强制要求编写代码捕获或声明免检异常。可能在程序的任何一个地方出现。
  • 必检异常:编译器强行要求程序员检查并通过try-catch语句处理,或者在方法头进行声明。

4. 异常处理

假如我们在工作中遇到问题该怎么处理?一般来说有两种情况,第一种就是自己觉得能解决就自己处理了,当自己解决不了,那就上报给上级找个大腿来解决。对Java来说同样是如此。

  1. 声明异常

    当一个方法可能会抛出必检异常,则必须在方法中头中声明。throws后面可跟多个异常。如下所示: public void method() throws IOException

    何时需要声明异常?

    当方法中需要抛出异常或者说该方法调用的子方法有抛出异常,但是没有对该异常进行捕获处理

  2. 抛出异常

    a. 检测到错误的程序可以创建一个合适的异常类型示例并抛出它。示例:

    IOException ex = new IOException(); throw ex;

    或者是:

    throw new IOException();

    注意声明异常和抛出异常关键字的区别

    b. 抛出链式异常,同原始异常一起抛出一个新异常(带有附加信息),称为链式异常。

  try{
          p1();
      }
      catch(Exception ex){
          throw new Exception(ex);  //在捕获到异常后,带着这个异常抛出一个新异常
                                    //若输出异常信息,会先显示该方法抛出的异常,再显示p1产生的异常
      }
  1. 捕获异常

    在使用中,将可能产生异常的语句放到try里面,若产生异常则会跳过剩下的语句,执行相应的catch部分的语句。

    注意:捕获多个异常时,若父类的catch块在子类之前,则会导致编译错误。如下面,若ex1是ex2的父类则会出错。

  try {
      statements;  //可能产生异常的语句放入try里面
  }
  catch (Exception1 ex1){
      handle for ex1;  //对第一个异常进行处理
  }
  catch (Exception2 ex2){
      handle for ex2;  //对第二个异常进行处理
  }
  1. “上级”(调用者)对必检异常的处理:

    若方法中声明了一个必检异常,则调用者必须在try-catch语句中执行,或者在调用者方法头中声明异常(即再把异常交给它的上级)。例如:若p2()可能会抛出一个必检异常(以IOException为例),方法p1()调用p2,则应该如下处理:

    //捕获p2 的异常
      void p1(){
          try{
              p2();
          }
          catch(IOException ex){
              ...
          }
      }
      //抛出p2的异常
      void p1() throws IOException(){
          p2();
          ...
      }

5. finally语句

若希望无论是否出现异常,都执行某些代码,则使用finally。(例如各种连接的关闭)

  1. 使用finally时可以省略catch块
  1. 即使在到达finally前有return语句,依旧会执行finally的代码

6. 一些注意事项

  1. 捕获异常时,尽量不要捕获通用异常,如catch(Exception e),应该捕获特定异常。否则可能会捕获到意想不到的异常,而且也会令他人不易理解自己的代码。

  2. 对于捕获到的异常不要忽略

  3. 记住“Throw early catch late”(早点抛出异常延迟抓取异常)原则,这个原则就是说,应该在异常出现时就将其抛出,抓取应该在能够获取足够信息的时候。简单来说,底层的方法应该更多的抛出异常,异常应该更多的在顶层代码中抓取处理。

  4. 异常处理会花费较大的时间和资源,不要用异常处理来做简单的逻辑测试。如非必要,勿用异常


7. 复习题

  1. throw、throws区别

  2. 必检异常和免检异常区别

  3. NoClassDefFoundError 和 ClassNoFoundException区别

欢迎关注灵魂画手的公众号!赔我板栗

你可能感兴趣的:(Java异常:你是异常的失落)