前言

本文参考:


异常

概念

异常,顾名思义,出毛病了,在Java代码中也代表着这段代码出毛病了

异常其实并没有什么可怕的,放轻松,按照对应的情况进行处理即可

分类

异常 - 图1

简而言之就是这样的一张图 Throwable是顶头Boss,然后分为了异常Exception和错误Error 其中异常我还列举了一些非常常见的异常。 我们一般称呼异常,一般说的都是Exception


Error

Error是不能处理的,好比人的绝症,一旦得上就要等死。

Exception

Exception是可以处理的,我们通常说的异常就是这个,可以处理的异常。

Exception分类中有两种比较重要的子类:

  • RuntimeException:一般由于程序员的代码逻辑错误出现的异常,是运行时异常,平时处理的最多的错误。
  • IOException:只要发生IO操作就会出现IO异常,非常正常。

受检查异常和不受检查异常

  • 受检查异常:编译器能够检查出来,要求必须处理
  • 不受检查异常:编译器一般检查不出来,不要求处理

不受检查异常包括ErrorRuntimeException,前者编译器处理不了,后者是程序员该管的事 不受检查异常不是说不应该处理,而是不应该编译器处理

受检查异常一般在写代码的时候,编译器就给检测出来了,比如IO异常,不处理编译不通过


异常处理机制

异常处理就两个词:抛出,捕获

抛出

简而言之就是甩锅,把异常甩给上一级,让上一级去处理,自己不去管了。

捕获

简而言之就是处理,这个叫真正的处理,不甩锅了。

抛出和捕获的五个关键字

Java中处理异常全靠这五个关键字:

  • try
  • catch
  • finally
  • throw
  • throws

五个关键字分为两组:

  1. try - catch - finally
  2. throw - throws

throw 和 throws

thorw用在方法里,作用是抛出一个异常对象,这个异常对象要么捕获要么标识,必须去处理。 throws用在类上,作用是标识异常,提醒调用者去处理异常

try 和 catch 和 finally

try-catch-finally是一套组合拳 try用于发现可能出现的异常, catch提出对应的异常出现的策略 finally是最后的收尾,不管程序如何,最后一定会执行finally代码块,我们常常用于关闭资源,比如IO 注意了,就算是try或者catch代码块中有return,也得先把数据存下,然后等finally执行完之后再返回

  1. package com.howling;
  2. public class Throw {
  3. public static void main(String[] args) {
  4. try {
  5. exception();
  6. } catch (Exception e) {
  7. System.out.println("异常处理策略");//异常处理策略
  8. } finally {
  9. System.out.println("程序一定会执行");//一定会执行
  10. }
  11. }
  12. public static void exception() throws RuntimeException,Exception{
  13. throwException();
  14. }
  15. public static void throwException(){
  16. throw new RuntimeException();
  17. }
  18. }

catch的注意事项:如果有多个异常:

  1. 可以分别进行处理:分别处理
  2. 一次捕获,一次处理:处理这些异常的父类

final finally finalize三者的区别

答案是没什么关联。前两者应该没有什么问题,但是finalize说一下:

finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。

这个方法在gc启动,该对象被回收的时候被调用。


finally必须要执行

假如finally也有返回结果

    public static int test() {
        try {
            int i = 1/0;
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return 2;    //返回2
        }
    }

一些常用的方法

Throwable中定义了比较有用的方法

  • getMessage():获取异常的描述信息
  • printStackTrace():打印异常,利于追踪
package com.howling;

public class Throw {
    public static void main(String[] args) {
        try {
            exception();
        } catch (Exception e) {
            System.out.println(e.getMessage());//null
            e.printStackTrace();//java.lang.RuntimeException
        }
    }

    public static void exception() throws RuntimeException,Exception{
        throwException();
    }

    public static void throwException(){
        throw new RuntimeException();
    }

}

自定义异常

只需两步:

  1. 新建类
  2. 继承异常
package com.howling;

public class CustomizeException extends Exception{
    public CustomizeException() {
    }

    public CustomizeException(String message) {
        super(message);
    }

    public CustomizeException(String message, Throwable cause) {
        super(message, cause);
    }

    public CustomizeException(Throwable cause) {
        super(cause);
    }

    public CustomizeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

可以看到有很多构造器的重载,但是一般来说前两个就够用了

package com.howling;

public class Throw {
    public static void main(String[] args) {
        try {
            throwException();
        } catch (CustomizeException e) {
            e.printStackTrace();//com.howling.CustomizeException: 自定义异常
        }
    }

    public static void exception() throws RuntimeException,Exception{
        throwException();
    }

    public static void throwException() throws CustomizeException {
        throw new CustomizeException("自定义异常");
    }

}