1. 异常的概念
Java中的异常是指Java程序在运行时可能出现的错误或非正常情况
2. 异常体系图
Throwable是所有异常类的父类,它有两个直接子类(1)Error类,错误类:java虚拟机无法解决的严重问题,如:jvm系统内部错误、资源耗尽等;(2)Exception类,异常类:表示程序本身可以处理的错误。Exception包含的子类如:RuntimeException运行时异常,编译时异常。
2.1 编译时异常
除了RuntimeException类以外,其他子类都是编译异常,java编译器会对编译时异常进行检查。出现这种异常必须处理,否则程序无法通过编译。(javac.exe)
2.2 运行时异常
RuntimeException类及其子类都是运行时类,运行时异常在程序运行时由java虚拟机自动进行捕获处理。
3. 常见异常
3.1 运行时异常
(1)ArithmeticException:算术异常,如10/0;
(2)ArrayIndexOutOfBoundsException:索引越界,如:若args初始长度为0,args.length==3;
(3)ClassCastException:类型转换异常,
如: Object object=args[2];//此时ok 向上转型 String->Object
Integer i=(Integer) object;//异常 Object->Integer
String j=(String)object;//ok 向下转型 Object->String
(4)NullPointerException:空指针异常,如:Student.name(此时Student=null,相当于null.name)
(5) NumberFormatException :数字格式化异常
3.2 编译时异常
FileNotFoundException、 ClassNotFoundException等,(读取不存在文件、网络连接中断、数据库。。。。。)
4. 异常处理
1. try-catch-finally:捕获异常,自行处理
注:当异常被catch捕获处理后,程序会继续执行catch块之后的代码
若:catch块中抛出新的未捕获的异常 或 return语句导致方法提前返回
则catch语句块之后的代码块不会被执行
细节如下:
(1)
try{
//可能有异常的代码
}catch {
//捕获到的异常
//1.当异常发生时
//2.系统将异常封装成Exception对象e,传递给catch
//3.得到异常对象之后,程序员自行处理 (也可做业务处理)
//4.若无异常,catch不处理
}finally {
//无论是否有异常,finally都执行(资源关闭)
}
(2) try必需,try-finally没有捕获异常,程序崩掉,退出
可以有多个catch,子类异常在前,父类异常在后
2. throws:抛出异常,交给调用者处理,最顶级处理者jvm
运行时,若没有显示处理异常,默认throws,最终抛给jvm,jvm打出异常,程序终止。
语法:
修饰符 返回值类型 方法名(参数1,参数2.....) throws 异常1,异常2......{
方法体
}
注:
子类重写父类方法时:子类所抛出的异常类型等于父类抛出异常类型,或者是父类异常类型的子类,如:父RuntimeException,子NullPointException
5. 自定义异常
(1)定义类
(2)继承异常类Exception或其子类
(3)自定义异常类使用super()语句调用Exception构造方法
注:
一般情况下,自定义异常类继承RuntimeException(运行时异常),因为可以使用默认处理机制(jvm),比较方便。
6.throw
在java程序中,除了使用throws关键字,还可以使用throw关键字抛出异常。
throw关键字用于方法体内,抛出一个异常对象,并且每次只能抛出一个异常对象。
语法:
throw ExceptionInstance;
7. throw和throws的对比
关键字 | 意义 | 位置 | 后面跟的东西 |
throws | 异常处理的一种方式 | 方法声明处 | 异常类型 |
throw | 手动生成异常对象的关键字 | 方法体中 | 异常对象(且每次只能抛出一个异常实例) |
public class Cal { public static void main(String[] args) throws NumberFormatException,ArrayIndexOutOfBoundsException,ArithmeticException{ try { //长度不对 if(args.length!=2){ throw new ArrayIndexOutOfBoundsException("参数个数不对"); } //是否是整形 int n1=Integer.parseInt(args[0]); int n2=Integer.parseInt(args[1]); double res=de(n1,n2); System.out.println("结果是:"+res); } catch (ArrayIndexOutOfBoundsException e) { // throw new RuntimeException(e); System.out.println(e.getMessage()); }catch (NumberFormatException e){ System.out.println("参数格式不正确,需要输出整数"); }catch (ArithmeticException e){ System.out.println("出现除数为0的异常"); } } public static int de(int n1,int n2){ return n1/n2; } }