菜鸟笔记
提升您的技术认知

java之异常

异常的层次结构

在Java程序语言设计中,所有的异常都是由类来表示,异常对象都是派生于Throwable类的一个实例(Throwable类继承Object类)。下面是Java异常层析结构的一个简单示意图:

异常也分为运行时异常与检查异常

运行时异常

写代码时不用特意对异常进行处理,在程序运行以后,系统自动检测然后报出异常

检查时异常

防患于未然的效果,在写代码时就对代码的异常进行处理 

异常定义

异常(exception):在程序运行过程中发生了不正常的现象,阻止了程序的运行。

通过if-else解决的异常特点

  • 代码臃肿,业务代码和处理异常代码混在一起
  • 可读性差
  • 程序员需要花费大量的精力来维护这个漏洞
  • 程序员很难堵住所有漏洞

异常三连 

基于if-else处理异常缺点太多,所以java中专门出了一格异常处理机制(异常三连)——try-catch-finally 。

异常三连写法

//1
try{——异常代码——}catch(异常类型1|异常类型2 e){——捕捉到异常后执行代码——}finally{——一定执行的代码——}
//2
try{——异常代码——}finally{——一定执行的代码——}//异常没捕获,其后代码无法继续执行
//3
try{——异常代码——}catch(异常类型1|异常类型2 e){——捕捉到异常后执行代码——}
//4
try{——异常代码——}catch(异常类型1|异常类型2 e){——捕捉到异常后执行的代码——}catch(异常类型3|异常类型4 e){——捕捉到异常后执行的代码——}finally{——一定执行的代码——}

try-catch原理

把可能出现的异常代码放入try代码块中,然后底层就会将异常封装成对象被catch后面的()中的异常对象接收,接受以后执行catch后面{}里的内容然后try-catch后面的代码该怎么执行就怎么执行。

try中出现异常以后其将异常跟catch后面的异常类型依次比较(按照代码的顺序进行比对),执行第一个与异常类型匹配的catch语句,一旦执行其中一条catch语句,后面的catch语句就会被忽略了在安排catch语句的执行顺序的时候一般会将特殊异常放在前面,一般异常放在后面(在JDK1.7以后异常的新处理方式可以并列,其用|号连接)。

关于try-catch

  • try中没有异常,catch中的代码不执行
  • try中有异常,catch进行捕获,如果catch中异常类型和你出的异常类型匹配的话就会走catch中的代码,如果catch中的异常类型和你出的异常类型不匹配的话,不走catch中代码,没有捕获成功,程序相当于遇到异常了进而中断,后续代码不执行

处理异常的方式

1.什么也不写,什么都不做

2.输出用户自定义异常信息(eg:对不起,你的代码有问题)

3.打印异常信息

//1.调用toString()方法,显示异常类名
System.out.println(e.toString());
//2.显示异常信息对应的字符串,如果没有就显示null
System.out.println(e.getMessage());
//3.打印全部异常信息,后续程序继续执行
e.printStackTrace();

 4.抛出异常

throw e;

什么情况下try-catch后面的代码不执行

  1. catch后面抛出异常——throw e;
  2. catch没有正常进行异常捕获
  3. 在try中遇到return

关于finally

理解

只要将必须执行的代码放入finally中,那么这个代码就会执行

try中有return时finally的执行顺序以及finally代码不执行情况

先执行finally里的代码后执行return,不过如果在try中执行了System.exit();(终止当前虚拟机),那么finally内的代码不会执行。

为什么代码放在finally中

关闭数据库资源,关闭IO流资源,关闭Socket资源等这些都是要做的事。

throw与throws

throw:出现异常的源头——制造异常

  • eg:throw new ArithmeticException();

 throws:在方法的声明处,告诉方法的调用者这个方法中可能会出现我所声明的这些异常(可以抛出多个异常),然后调用者对这个异常进行处理,要么自己处理,要么自己继续向上抛出——就像传球。

//eg:
public static void test(int a) throws TestAException, TestBException,
TestCException {——代码——}

throw和throws的区别

1.作用位置不同

  • throw:方法内部
  • throws:方法声明处

2.内容不同

  • throw:其+异常对象(运行/检查时异常)
  • throws:其加异常类型(可以多个-中间用,隔开)

3.作用不同

  • throw:异常出现的源头-制造异常
  • throws:用于异常的向上传递-抛出异常

自定义异常

注意:

  • 自定义的异常类必须继承其他异常类
  • 继承的异常类可以根据需求来写(运行异常、检查异常……)
//使自己定义的异常类继承运行时异常
public class MyException extends RuntimeException {
    static final long serialVersionUID = -7034897190745766939L;
    public MyException(){

    }
    public MyException(String msg){
        super(msg);
    }
}
class Test{
    public static void main(String[] args) {
        throw new MyException("运行出错了");
    }
}