【Java笔记】20 异常
一、异常概念
程序执行中发生的不正常情况称为异常,语法错误和逻辑错误不是异常
异常分为两大类:
- Error(错误):虚拟机无法解决的严重问题,如:JVM系统内部错误、资源耗尽等
- Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理,如:空指针访问,试图读取不存在的文件
- 运行时异常 程序运行时发生的异常 可以不做处理
- 编译时异常 编程时由编译器检查出的异常 必须处理
public class Exception01 {public static void main(String[] args) {int num1 = 10; int num2 = 0;// 抛出异常ArithmeticException// try-catch异常处理机制来解决// 代码块选中,快捷键ctrl+alt+t,选中try-catch// 异常处理后,即使出现了异常,程序可以继续运行try {int res = num1 / num2;} catch (Exception e) {e.printStackTrace();}System.out.println("程序继续运行....");}}
二、异常体系图
三、五个常见的运行时异常
- 空指针异常NullPointerException
当程序试图在需要对象的地方使用null时,抛出该异常
public class NullPointerException_ {public static void main(String[] args) {String name = null;System.out.println(name.length());}}
Exception in thread “main” java.lang.NullPointerException
at java20.exception.NullPointerException.main(NullPointerException_.java:6)
- ArithmeticException数学运算异常 如除以0
- ArrayIndexOutOfBoundsException数组下标越界异常 索引为负或等于数组大小
- ClassCastException试图将对象强制转换为不是实例的子类时
public class Exception02 {public static void main(String[] args) {A a = new B(); // 向上转型可以B b = (B)a; // 向下转型 a本身就指向B 可以C c = (C)a;}}class A{ }class B extends A{}class C extends A{}
Exception in thread “main” java.lang.ClassCastException: java20.exception.B cannot be cast to java20.exception.C
at java20.exception_.Exception02.main(Exception02.java:7)
- 数字格式不正确异常 将字符串转成一种数值类型,但该字符串不能转换为适当格式时,抛出
public class NumberFormatException_ {public static void main(String[] args) {String name = "aaa";int num = Integer.parseInt(name);//NumberFormatException}}
四、编译异常
在编译期间,就必须处理的异常
常见的编译异常
- SQLException 操作数据库时,查询表可能发生异常
- IOException 操作文件时
- FileNotFoundException 操作不存在的文件时
- ClassNotFoundException 加载类而类不存在时
- EOFException 操作文件到达文件末尾
- IllegalAraguementException 参数异常
五、异常处理
- try-catch-finally 捕获异常,自行处理
try{
代码可能有异常处
发生了异常,异常发生后面的代码不会执行,直接进入到catch块
}catch(Exception e){
捕获到异常系统将异常封装成Exception对象e,传递给catch
得到异常对象后,自行处理
可以有多个catch语句,捕获不同的异常,进行不同的业务处理,父类异常在后,子类异常在前
}finally{
不管try代码块是否有异常发生,始终要执行finally
通常将释放资源的代码放在finally、
可以没有finally
}
根据需要在程序中有多个try-catch块
try-finally配合使用,没有捕获异常,程序崩溃。应用场景:执行一段代码,不管是否发生异常,都执行某个业务逻辑
例:如果用户输入的不是一个整数,就提示他反复输入,直到输入一个整数为止public class TryCatchDetail02 {public static void main(String[] args) {//如果try 代码块有可能有多个异常,使用多个catch 分别捕获不同的异常,相应处理//子类异常在前面,父类异常在后面try {Person person = new Person();person = null;System.out.println(person.getName());//NullPointerExceptionint n1 = 10;int n2 = 0;int res = n1 / n2;//ArithmeticException} catch (NullPointerException e) {e.printStackTrace();} catch (ArithmeticException e) {System.out.println(e.getMessage());}finally {}}}class Person{private String name = "aaa";public String getName(){return name;}}
public class TryCatchDetail03 {public static void main(String[] args) {try {int n1 = 10;int n2 = 0;System.out.println(n1 / n2);} finally {System.out.println("执行了finally");}System.out.println("程序继续执行..");}}
Exception in thread “main” java.lang.ArithmeticException: / by zero
at java20.exception_.TryCatchDetail03.main(TryCatchDetail03.java:8)
执行了finallySystem.out.println(“程序继续执行..”); 这句话不执行
public class TryCatchExercise04 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int num = 0;String inputStr = "";while (true){System.out.println("请输入一个整数:");inputStr = scanner.next();try {num = Integer.parseInt(inputStr);break;} catch (NumberFormatException e) {System.out.println("输入的不是一个整数");}}System.out.println("输入的值是" + num);}}
- throws 抛出异常,交给调用者(方法)处理,最顶级的处理者是JVM
try-catch和throws二选一,没有显式的选择try-catch和throws ,默认throws
throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
- 注意事项
编译异常,程序中必须处理
运行时异常,程序中没有处理,默认就是throws
子类重写父类的方法时,子类重写的方法,所抛出的异常类型要么和父类的抛出异常一致,要么为父类抛出异常类型的子类型
throws过程中,如果方法有try-catch,就相当于处理异常,不必再throws
六、自定义异常
- 基本概念
程序中出现某些错误,但错误信息没有再Throwable子类中处理,自己设计异常类 - 步骤
- 定义类:自定义异常类名 继承Exception或RuntimeException
- 如果继承Exception,属于编译异常
- 如果继承RuntimeException,属于运行异常,一般都继承RuntimeException
例:年龄要求18-120之间,否则抛出自定义异常
public class CustomException {public static void main(String[] args){int age = 180;if(!(age >= 18 && age <= 120)){throw new AgeException("年龄不在范围");}System.out.println("范围正确");}}// 一般情况下,我们自定义异常是继承RuntimeException// 即把自定义异常做成运行时异常,好处是,可以使用默认的处理机制class AgeException extends RuntimeException {public AgeException(String message) {super(message);}}
七、throw和throws
| 意义 | 位置 | 后面跟的东西 | |
|---|---|---|---|
| throws | 异常处理的一种方式 | 方法声明处 | 异常类型 |
| throw | 手动生成异常对象的关键字 | 方法体中 | 异常对象 |
