美文网首页
Java异常

Java异常

作者: ThreeGold | 来源:发表于2018-04-17 16:44 被阅读0次

    Throwable类

    Throwable类是整个异常体系类的父级类,它实现了Serializable接口,它的父类是Object类,它的子类有Exception和Error,这2个子类下面都有很多子类。

    • Error是程序发生了重大错误,不能解决,只能避免,比如:内存泄漏

    • Exception:可对其进行处理的异常

    20160907101613.jpg

    受检异常和非受检异常

    • 受检异常(checkedException):程序必须处理该异常。除了RuntimeExcetion及其子类(运行时异常),其他的Exception及其子类都属于受检异常,这种异常的特点是java编译器会检查它,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

    • 非受检异常(uncheckedException):编译器不要求强制处置的异常。包括运行时异常(RuntimeException与其子类)和错误(Error)。

    QQ截图20180417153847.png

    运行时与非运行时异常

    Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。

    运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非受检异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

    运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

    非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,不过一般情况下不自定义检查异常。

    异常处理

    程序运行过程中可能会出现异常情况,比如被0除、对负数计算平方根等,还有可能会出现致命的错误,比如内存不足,磁盘损坏无法读取文件等,对于异常和错误情况的处理,统称为异常处理。

    Java异常处理主要通过5个关键字控制:try、catch、throw、throws和finally。try的意思是试试它所包含的代码段中是否会发生异常;而catch当有异常时抓住它,并进行相应的处理,使程序不受异常的影响而继续执行下去;throw是在程序中明确引发异常;throws的作用是如果一个方法可以引发异常,而它本身并不对该异常处理,那么它必须将这个异常抛给调用它的方法;finally是无论发不发生异常都要被执行的代码。

    关键字:throw,throws,try和catch的用法如下:

    1. throws出现在方法的声明中,表示该方法可能会抛出的异常,允许throws后面跟着多个异常类型

    2. throw出现在方法体中,用于抛出异常。当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw。

    3. try出现在方法体中,它自身是一个代码块,表示尝试执行代码块的语句。如果在执行过程中有某条语句抛出异常,那么代码块后面的语句将不被执行。一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

    4. catch出现在try代码块的后面,自身也是一个代码块,用于捕获异常try代码块中可能抛出的异常。catch关键字后面紧接着它能捕获的异常类型,所有异常类型的子类异常也能被捕获。

    常见的异常:

    • NullPointerException 空指针异常

    • ArrayIndexOutOfBoundsException 数组下标越界异常

    • StringIndexOutOfBoundsException 字符串下标越界异常

    • ClassCastException 类型转换异常

    • NumberFormatException 数字转换异常


    代码示例

    下面来看看代码,从代码中深刻理解Exception

    例1:

      Scanner scanner = new Scanner(System.in);
      // 下面可以引发InputMismatchException,为非受检异常
      int i = scanner.nextInt();//这里定义为int,如果键盘输入为string类型则会出现异常
      System.out.println(i);
    
      // 下面这个是受检异常,必须处理,否则编译不通过
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    

    例2:

      int i;
      Scanner scanner = new Scanner(System.in);
      try {// 放可能发生异常的代码块
        i = scanner.nextInt();
      } catch (InputMismatchException e) {
        System.out.println("捕获到了InputMismatchException");
      } catch (Exception e) {// 捕获异常,对异常的处理
        System.out.println("发生了异常");
        e.printStackTrace();
      } finally {// 始终要执行的代码
        System.out.println("无论有没有发生异常我是一定会执行的");
      }
      System.out.println("----程序结束");
    

    将上面的代码运行2次输出结果分别是:

    第一次输入123结果

    123
    
    无论有没有发生异常我是一定会执行的
    
    ----程序结束
    

    第二次输入asdf结果

    asdf
    
    捕获到了InputMismatchException
    
    无论有没有发生异常我是一定会执行的
    
    ----程序结束
    

    由这2次结果可以看出,finally不能是否发生异常都执行了;try后面可以跟着多个catch,但是最多只能执行一个catch。可以在try后面加任意数量的catch块,如果try中的代码发生异常,异常被抛给第一个catch快,如果抛出异常的数据类型与第一个catch类型匹配,它就在这里被捕获,如果不匹配,它会传入第二个catch块,以此类推知道最后一个catch块。

    例3:

      public static void main(String[] args) {
        int a = 10, b = -4;
        int result;
        try {
          result = div(a, b);
          System.out.println("result=" + result);
        } catch (Exception e) {
          System.out.println("捕获到了异常");
          System.out.println(e.getMessage());
        }
        System.out.println("---程序结束");
      }
    
      // 在方法后面用throws关键字 把异常抛出去,谁调用谁处理
      public static int div(int a, int b) throws Exception {
        if (b < 0) {
        // 使用throw抛出一个异常
          throw new Exception("被除数不能小于0");
        }
        if (b == 0) {
        // 使用throw抛出一个异常
          throw new Exception("被除数不能为0");
        }
        return a / b;
      }
    

    输出为:

    捕获到了异常
    
    被除数不能小于0
    
    ---程序结束
    

    这个例子是自定义什么条件下抛出异常,我们定义了被除数为0或者被除数小于0时抛出异常,并通过throws把异常抛出,谁调用这个方法,谁就处理这个异常或者继续抛出。


    扩展:错误和异常的区别(Error vs Exception)

    1)java.lang.Error:Throwable的子类,用于标记严重错误。合理的应用程序不应该去try/catch这种错误。绝大多数的错误都是非正常的,就根本不该出现的。

    2)java.lang.Exception: Throwable的子类,用于指示一种合理的程序想去catch的条件。即它仅仅是一种程序运行条件,而非严重错误,并且鼓励用户程序去catch它。

    扩展:错误和异常的区别(Error vs Exception)
    1)java.lang.Error: Throwable的子类,用于标记严重错误。合理的应用程序不应该去try/catch这种错误。绝大多数的错误都是非正常的,就根本不该出现的。
    2)java.lang.Exception: Throwable的子类,用于指示一种合理的程序想去catch的条件。即它仅仅是一种程序运行条件,而非严重错误,并且鼓励用户程序去catch它。


    声明自定义异常

    在java中可以自定义异常,编写自己自定义的异常时需要注意:

    • 所有异常都必须是Throwable的子类
    • 如果希望写一个受检异常类,则需要继承Exception类
    • 如果希望写一个运行时异常类,那么需要继承RuntimeException类

    请尊重作者劳动成果,转载请标明原文链接:https://www.jianshu.com/p/aaf0103604d8

    相关文章

      网友评论

          本文标题:Java异常

          本文链接:https://www.haomeiwen.com/subject/lakpkftx.html