1. 异常概述
1.1 异常分类
Java程序在执行过程中所发生的异常事件可分为两类(语法错误与逻辑错误不是异常):
- Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等。一般不编写针对性代码进行处理。
- Exception:因编程错误或偶然的外在因素导致的一般性问题,可使用针对性的代码进行处理。如:空指针访问、试图读取不存在的文件、网络连接中断、数组角标越界。
Exception又分为编译时异常和运行时异常,编译时异常必须要显式地处理。
1.2 常见异常
1.2.1 常见的编译时异常
- IOException → FileNotFoundException
- ClassNotFoundException
1.2.2 常见的运行时异常
- NullPointerException 空指针异常
- ArrayIndexOutOfBoundsException 数组角标越界
- ClassCastException 类型转换异常
- ArithmeticException 算术异常
2. 异常处理机制
Java提供异常处理的抓抛模型。
- 过程一:抛。程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出。一旦抛出对象以后,其后的代码就不再执行。
- 过程二:抓。即异常的处理方式,分为两种:① try-catch-finally;② throws
2.1 try-catch-finally
使用try-catch-finally处理编译时异常,相当于把编译时异常延迟到运行时出现。开发中,由于运行时异常比较常见,通常不处理。
try{
可能出现异常的代码
}catch(异常类型1 变量名1){
处理异常的方式1
}catch(NumberFormatException e){
System.out.println(e.getMessage());
e.printStackTrace(); //二者选一,常用第二种
}finally{
//finally为可选的
一定会执行的代码
}
- try-catch结构顺序执行,执行结束则跳出。若异常类有包含关系,则子类必须放在上面。
- 异常对象常用的处理方法:① String getMessage();② printStackTrace()
- finally中的语句无论try-catch的异常是否被处理、是否有return返回,其内的语句都会执行。需要手动释放资源的操作要放在finally中。
2.2 throws+异常类型
若异常不确定如何处理,显示抛出后由该方法调用者处理。异常代码后续的代码不再执行。
public void readFile(String file) throws FileNotFoundException{
FileInputStream f = new FileInputStram(file);
}
- 异常一步步向上抛之后,若在main方法内调用还是没用try-catch解决该异常,则main方法中throws会将异常抛给JVM,此时将编译时异常转化为了运行时异常。
- 子类重写的方法throws的异常类型不能大于父类被重写方法throws的异常类型。
2.3 两种处理方法的选择
- 若父类中被重写的方法没有throws异常,则子类重写的方法中的异常必须用try-catch-finally处理。
- 若几个方法是递进执行的,则这几个方法都用throws处理异常,若用try-catch-finally处理则出现异常后会执行没用的代码。
2.4 手动抛出异常
除了系统生成异常对象外,可以手动生成一个异常对象,并抛出(throw,该抛出是生成异常,throws的抛出是处理异常)。
throw new RuntimeException("输入数据非法");
若抛出的异常非RuntimeException类型,为编译时异常,必须显式处理。
2.5 自定义异常类
- 继承现有的异常结构,一般为:RuntimeException、Exception
- 提供一个全局常量serialVersionUID ,唯一地标识异常类型
- 提供重载的构造器
public class MyException extends RuntimeException{
static final long serialVersionUID = -389529847598L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}