1、首先来看一张图:
2、概念
- Throwable:是所有异常的祖先,有两个重要的子类,Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
- Error : 是程序无法处理的错误,例如程序运行时JVM出现的问题,像 OutOfMemoryError(内存溢出),出现这种状况时,与程序无关,我们也无需试图去处理这些问题。
- Exception : 指程序可以处理的异常,分为下面两种类型:
1、运行时异常(RuntimeExceptio):如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)、ArithmeticException(除数为零)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
2、非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
这种情况大家使用mybatis框架肯定有所体会,有时sql写错了,程序运行就报错,必需是正确的SQL语句。
3、Java异常的处理机制
1、使用try-catch语句进行捕获
1.1、 当没有对异常进行捕获时,程序会中断执行,代码如下:
程序直接抛出异常,当然这个异常是JVM抛的,并且没有输出"程序继续执行!",证明程序并没有运行到这一步,也就是说产生异常之后,后面的语句都不会执行,效果如下:
1.2、使用try-catch对异常进行捕获,程序不会因为异常的产生而中断执行,代码如下:
程序输出结果中有"程序继续执行!"这段话,证明程序有执行到这一步,运行效果如下:
2、使用try-catch-finally,finally语句块中的代码无论try中是否有异常产生,都必须要执行,如下图:
程序运行结果如下:
由上图可知,产生异常之后的语句就不会被执行到,程序执行到catch语句,然后执行finally语句,如果我们有 必须要执行的代码,那就可以放到finally中,比如使用分页插件时,关闭分页插件的语句,以及在使用JDBC对数据 库进行操作时,关闭数据库连接的代码都可以放到finally中,避免出现异常导致资源浪费。
3、throws和throw关键字
出现异常处了使用try-catch捕获处理外,也可以选择抛出异常,让调用的方法去处理。
throws: 用来声明方法,表示此方法不处理异常,而是交给方法调用处进行处理。下图所示的异常是由test1函数产生的,但是由main函数进行处理
throw:使用throw关键字则可以人为的抛出一个异常,如下图:
4、自定义异常类
首先我们来看看JDK异常类的源码,以算术异常类ArithmeticException为例,可以看到就两个构造方法,一个有参,一个无参
接下来自定义一个异常类MyException,如下图示:
结果如下:
5、建议
1、 由于运行时异常(RuntimeException)的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许应用程序忽略运行时异常,也就是说可以不使用try-catch处理,如果出现异常,则由JVM处理,但是开发时为了程序可控最好使用try-catch处理。
2 、对于所有的可查异常,即非RuntimeException异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,它必须声明将抛出异常
3、对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常,简而言之,就是你不需要管!
4、从方法中抛出的任何异常都必须使用throws声明; 任何Java代码都可以抛出异常,如:自己编写的代码、来自Java开发环境包中代码,或者Java运行时系统。无论是谁,都可以通过Java的throw语句抛出异常
5、总体来说,Java规定:对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。
6、列举一些常见的异常类
RuntimeException子类:
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
其他的异常类
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
字段未找到异常:NoSuchFieldException
类型转换异常类:ClassCastException
字符串索引超出范围抛出的异常:StringIndexOutOfBoundsException
不允许访问某类异常:IllegalAccessException
找不到类异常:java.lang.ClassNotFoundException
InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常