根据b站韩顺平教育韩顺平教育java教学视频学习的学习笔记。个人学习理解,如有疏漏,敬请改正。
1、异常的概念
①基本概念
Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)。异常处理可以增加程序的健壮性。
②执行过程中所发生的异常事件可分为两大类
- Error(错误):java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of memory),error是严重错误,程序会崩溃
- Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等。Exception分为两大类:运行时异常(非受检异常)和编译时异常(受检异常)。
- 运行时异常(非受检异常),即编译器检查不出来,编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。Java.lang.RuntimeException类及它的子类都是运行时异常。
- 对于运行时异常可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
- 编译时异常是编译器要求必须处置的异常(try-catch与throws两种处理方式中二选一)。
2、异常体系图
异常体系图(表现了类和接口之间的继承与实现关系)
3、常见的异常
- 常见运行时异常
- NullPointerException空指针异常
- ArithmeticException数学运算异常
- ArrayIndexOutOfBoundsException数组下标越界
- ClassCastException类型转换异常
- NumberFormatException数字格式不正确
- 常见的编译异常(一般发生在网络、数据库和文件操作)
- SQLException操作数据库时,查询表可能发生异常
- IOException操作文件时发生的异常
- FileNotFoundException当操作一个不常在的文件时发生异常
- EOFException操作文件到文件末尾,发生异常
- IIlegalArguementException参数异常
4、异常处理
异常处理就是当异常发生时,对异常处理的方式
- 异常处理的方式
- try-catch-finally :程序员在代码中捕获发生的异常,自行处理
- throws:将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM。
- 异常处理机制
1、try-catch-finally处理机制(idea快捷键Ctrl+Alt+t)
try{
//可能有异常的代码//1、如果异常发生了,则try代码块中发生异常位置后面的代码不会执行,直接进入到catch块
//2、如果没有异常,则顺序执行try的代码块,不会进入catch
}catch (Exception e){
//捕获异常:
//1、当异常发生时,系统将异常封装成Exception对象e传递给catch
//2、得到异常对象后,程序员自己处理
//3、注意,如果没有发生异常,catch代码块不执行
}finally {
//1、不管try代码块是否有异常发生,始终要执行finally
//2、通常将释放资源、关闭链接等的代码放在finally
//3、finally不是必须的,可写可不写。
}try { String str = "hahha"; int a = Integer.parseInt(str); System.out.println("数字:"+a); } catch (NumberFormatException e) { System.out.println("异常信息:"+e.getMessage()); }finally { System.out.println("finally代码块被执行..."); } System.out.println("程序继续执行.....");
- 注意
①可以根据需要在程序中有多个数量的try-catch块
②如果try代码块有可能有多个异常,可以使用多个catch分别捕获不同的异常,但要求子类异常写在前面,父类异常写在后面。(当然只使用一个catch也可以)
try { Person person = new Person("zdz"); person = null; System.out.println(person.getName());//NullPointerException int n1 = 10; int n2 = 0; double n3 = n1 / n2;//ArithmeticException } catch (NullPointerException e){ System.out.println("这是一个空指针错误..."+e.getMessage()); }catch (ArithmeticException e){ System.out.println("这是一个数学运算错误..."+e.getMessage()); }catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); }
JDK8的新特性:
catch() 异常间可以自小到大用|
分割③可以进行try-finally配合使用,应用场景就是执行一段代码,不管是否发生异常(发生也不处理)都必须执行finally的业务逻辑。这种用法相当于没有捕获异常,因此程序会直接崩掉。
2、throws处理机制
①如果一个方法在执行时可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表面该方法将不对这些异常进行处理,而由该方法的调用者负责处理。不管错误还是异常都是可抛出的。
②在方法声明中用throws语句可以声明抛出异常的列表(可以是一个异常也可以是多个异常),throws后面的异常类型可以是方法中产生的异常类型,也可以是该异常类型的父类。
public static void main(String[] args) throws FileNotFoundException {//也可以使用 FileNotFoundException的父类Exception //可以使用try-catch-finally //也可以使用throws抛出异常,让调用main方法(所有方法都可以)的调用者处理 //throws关键字后也可以是异常列表,即可以抛出多个异常列表 如throws FileNotFoundException,NullPointerException{ FileInputStream love = new FileInputStream("d://aa.txt");//一个 FileNotFoundException异常 }
注意:
- 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型
- throws的运行机制是从出现异常的方法开始逐级往上一级抛出,每往上抛出,调用者都要对异常进行处理或继续往上抛出。对于编译异常需要立即处理而运行异常在编译时并不要求处理即不会报红。
5、自定义异常
- 概念
当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类中描述处理(即没有在异常体系图中),这个时候可以自己设计异常类,用于描述该错误信息。
- 步骤
①定义类:自定义异常类名继承Exception或RuntimeException
②如果继承Exception,属于编译异常
③如果继承RuntimeException则属于运行异常。
例如当我们接收Person对象年龄时,要求范围在18-20之间,否则抛出一个运行异常并给出提示信息。
public class CustomException { public static void main(String[] args) { int age = 80; if (!(age >= 18 && age <= 120)){ //可以通过构造器设置信息 throw new AgeException("年龄需要在18-120之间"); }else { System.out.println("年龄正常!"); } } } //自定义异常 //一般情况下自定义异常都是基于RuntimeException,这样可以使用默认处理机制(运行异常在编译时不用立即处理) class AgeException extends RuntimeException{ public AgeException(String message){ super(message); } }
6、throw和throws的对比
意义
位置
后面跟的东西
throws
异常处理的一种方式
方法声明处
异常类型
throw
手动生成异常对象的关键字
方法体中
异常对象
异常在java中以类的形式存在,每一个 异常类都可以创建异常对象。
7、异常两个主要方法
方法名
作用
String getMessage()
返回异常的详细消息字符串
void printStackTrace()
追踪堆栈异常信息(采用异步线程)