(个人学习笔记,内容总结自韩顺平0基础学java)
Java语言中,将程序执行中发生的不正常情况称为“异常”。(但开发过程中的语法错误和逻辑错误不是异常)
在大型商业软件/网站中,有时候会出现一些不算致命的异常,从而导致整个系统崩溃。为了避免这种情况,java的设计者提供了一种叫做异常处理机制的办法来解决该问题,从而保证了程序的健壮性
异常事件类型
Error
Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重问题。比如 StackOverflowError(栈溢出)和 OOM(out of memory) ,Error是严重错误,程序会崩溃
Exception
其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。异常有:空指针访问,试图读取不存在的文件,网络连接中断等等,Exception分为两大类:运行时异常 和 编译时异常
运行时异常
编译器不要求强制处理的异常,一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。但是对于运行时异常可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
(java.lang.RuntimeException类及它的子类都是运行时异常)
编译时异常
是编译器要求必须处理的异常
五大常见运行时异常
1.NullPointerException空指针异常
在程序使用在需要对象的地方使用null时,抛出该异常
如:
String a = null;
System.out.println(a.length());
则会报出空指针异常
2.ArithmeticException数学运算异常
当出现异常的运算条件时,抛出该异常。例如:一个数除以 0 时,抛出一个数学运算异常
3.ArrayIndexOutOfBoundsException数组下标越界异常
用 超出数组长度 或 为负数 的索引访问数组时抛出的异常。
4.ClassCastException类型转换异常
当试图将对象强制转换为不是实例的子类时,抛出该异常。
例如:有B、C两个类继承C类,此时
A b = new B();//正确
B b1 = (B)b;//正确
C c = (C)b;//抛出异常
5.NumberFormatException数字格式不正确异常
当应用程序试图将字符串转成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常
异常处理机制
try-catch操作
介绍
如果程序员认为一段代码可能出现异常/问题,可以使用try-catch异常处理机制来解决,从而保证程序的健壮性。
try-catch快捷键:ctrl + alt + t(选中代码后)
格式:
try {
(可能有异常的代码)
}catch (Exception e) {
//当异常发生时:
//1.系统将异常封装成Exception类的对象e,传递给catch
//2.此时catch里就有了对象e,可以在catch代码块内由程序员自己处理
}finally{
//不管try代码块是否有异常发生,始终要执行finally
(所以通常将释放资源的代码放在finally)
}
使用细节
*1.try中出现异常后的代码不会运行,但是异常前的代码则会运行。
2.出现异常后,程序直接进入catch块中
3.如果没有异常,catch不会执行
*4.如果希望不管发生异常与否,都执行某段代码(如关闭连接,释放资源等)则使用finally代码
5.如果try代码块可能有多个异常,则可以使用多个catch分别捕获不同的异常,响应处理。但是注意!子类异常要写在前面(父类Exception写在最后面),否捕获子类异常的代码就会变成无效代码
6.也可以使用try-finally的组合,用于在代码崩溃后仍去执行一些代码
7.如果try-catch-finally代码块在一个方法中,try发生异常后,catch能返回一个值,finally也可以返回一个值,则只返回finally的值(因为finally必须被执行)(但是catch确实被执行了!!!)
8.如果try异常,catch可以返回值,finally不返回值但是对catch中返回的值进行了操作。则在finally操作后,catch返回原值(catch中要返回的值被使用临时变量保存了起来,然后在让值在finally中进行操作,最后返回的任是保存的临时变量)
throws操作
介绍
throw是将异常抛出,给方法的调用方法来处理的操作,其他类可以用try-catch操作来解决该异常。
如果一个类中有异常,则这个类默认使用throws方法逐层throws,直到throws到JVM中报错并终止运行
格式:
public void xxx() throws 某个/多个异常 {}
使用细节
1.编译异常必须处理(用t-c-f或throws)
2.对于运行时异常,程序中如果没有处理,默认就是throws处理
*3.子类重写父类的方法的时候,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的一致,要么为父类抛出的异常类型的子类型
4.在throws过程中,如果有方法try-catch,就相当于异常处理了,可以不需要throws
5.运行异常不会要求程序员必须处理,因为java有默认处理机制。所以throws一个运行异常也可以不用去处理
自定义异常
在一些情况下,可以自定义一个异常类来在程序进行不期望的运行时来抛出一个异常。
示例
class XxxException extends RuntimeException {
//构造器(这个构造器可以将构造时输入的字符串在输出异常时一起提示出来)
public XxxException(String message) {
super(message);
}
}
此时便有了xxxException异常类,可以在其他类中调用:
public class Xxx {
public static void main(String[] args) {
int a = 1;
if (a == 1) throw XxxException("抛出一个Xxx异常");
}
}
此时运行,就会抛出一个自定义异常。
注意事项
1.一般情况下,我们自定义异常是继承RuntimeException
2.即把自定义异常做成运行时异常,于是我们就可以使用默认的处理机制
throw和throws的区别
throws在方法声明的后面,用于方法。让方法进行throws操作,是一种异常处理机制。后面跟的是要抛出的异常类型。
throw则是手动生成一个异常对象的关键字,位于方法体中。后面跟的是异常对象,所以需要new。