Java进阶教程:异常处理

Java进阶教程:异常处理

前往不要以为懂try...catch..finally就懂异常了!

异常

什么是异常

  异常简单理解就是程序运行出现问题了,好比一个人生病了,既然时生病了,那对于我们个人来说,有些可以治愈,有些是绝症。对于可以治愈的病呢,我们可以采取一些补救措施来维持健康,比如吃药、打针、做手术等等,这些措施呢就是异常处理了。对于绝症呢,我们只能听天由命了,大概率情况下等待死亡。这两类病呢对应Java异常体系中的异常和错误,我们来看一下!

Java异常体系

  • Throwable:Java语言中所有错误和异常的超类,一切可以抛出的东西都是基于此。
    • Error:代指严重问题,大到程序无法处理,只能人工介入。
      • StackOverflowError
      • OutOfMemoryError
    • Exception
      • CheckedException:检查性异常,例如IO异常/SQL异常,特点不管你愿不愿意,都需要写try...catch进行处理。
      • UncheckedException:也称运行时异常,出现这种异常时由Java虚拟机接管,异常由系统一层一层向上抛,直到遇到处理代码。如果没有遇到,直到到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。

注意:层级关系表示继承。

   我们再举个简单例子来说明一下检查异常和运行时异常

  

注意:所有的运行时异常都继承自RuntimeException

 Java异常处理

  对于错误呢,我们无力回天,但是对于捕获到的异常可以进行处理,来做好补偿机制,以防止线程被中断

  这个处理呢是两层意思,第一种就是我们自己处理,第二种就是让调用者处理。对于自己处理,我们写好try...catch...就好,对于让调用者处理,我们把这个异常抛出就好。

    //自己处理,使用try...catch...
    public void handle() {
        try {
            File file = new File("./a.txt");
            if (file.exists()) {
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //抛出去,让调用者处理
    public void unhandle() throws IOException {
        File file = new File("./a.txt");
        if (file.exists()) {
            file.createNewFile();
        }
    }

  这里有一个坑,使用throw抛出异常时,对于运行时异常,你不必在方法后面声明throws RuntimeException,但是对于检查型异常,除了方法内throw,方法上也必须声明throw 待抛出的异常,如下:

    //运行时异常
    public void unChecked(){
        try{
            System.out.println(5/0);
        }catch (RuntimeException e){
            throw e;
        }
    }

    //检查型异常
    public void checked() throws IOException {
        try {
            FileInputStream fileInputStream = new FileInputStream(new File("./a.txt"));
            fileInputStream.close();
        } catch (Exception e) {
           throw e;
        }
    }

  到这里我们再来简单总结一下:

  • 异常处理有两种方案:
    • 自己处理:
      • 运行时异常可以不处理,也可以进行捕获处理
      • 检查型异常不处理编译不过  
    • 抛给调用者:
      • 运行时异常可以不处理,一旦发生默认抛出去
      • 检查型异常如果执意抛出,必须声明throws和调用throw方法

异常处理设计

  • 只有在必须使用异常的地方才使用异常,不要用异常去控制程序的流程。
  • 切忌使用空catch块。
  • 检查异常和非检查异常的选择
  • 注意catch块的顺序
  • 异常处理尽量放在高层进行
  • 在finally中释放资源

参考资料

原文地址:https://www.cnblogs.com/MrSaver/p/12455136.html