2022-07-29 第五小组 顾祥全 学习笔记 day22-JavaSE-异常

异常

  • 什么是异常:在程序中出现的不正常情况
  • 异常有什么作用:增强程序的健壮性1
  • 异常的存在形式:异常在Java中是以类的形式存在,所有的异常类都可以创建对象

异常继承结构

Throwable
Error
VirtualMachineError
IOError
Exception
直接子类
RuntimeException
NullPointerException
IndexOutOfBoundsException
  • Throwable是Error和Exception的直接父类,可以表示所有的错误和异常都是可抛出的
  • 错误一旦发生JVM只会有一个结果,那就是终止程序的运行,退出JVM。
  • 对于Exception的直接子类所表示的异常我们称之为编译时异常
  • 对于RuntimeException的直接子类所表示的异常我们称之为运行时异常

Error

  正常情况下,错误时不会发生的,绝大多数错误会导致程序处于不正常状态,错误是无法被处理的,错误一旦发生JVM只会有一个结果,那就是终止程序的运行,退出JVM。

Exception

编译时异常

编译时异常又被称为受控异常/受检测异常,编译时异常发生概率较高,要求开发人员在编写代码时对异常进行预处理2不处理编译器会报错,所有的编译时异常的直接父类都是Exception。

运行时异常

运行时异常又被称为非受控异常/非受检测异常,运行时异常发生概率较低,开发人员可以对该异常选择处理也可以选择不处理,所有运行时异常的直接父类都是RuntimeExcepiton。

Throwable常用方法

  1. public String getMessage() -----> 获取异常简单描述信息
  2. public void printStackTrace() -----> 打印异常堆栈信息

java后台打印异常堆栈追踪信息时候,采用了异步线程的方式打印

异常的处理

我们对异常的处理一般指的是编译时异常,编译时异发生概率高,要求在编写程序时必须预先进行处理;对于运行时异常,并不强制要求对异常进行处理(可以选择处理,也可以选择不处理),就算不处理程序也能通过编译。

throws关键字

在方法声明的位置使用throws关键字,将异常抛给调用者,调用者可以选择对异常处理(try…catch)也可以选择继续上抛(throws),如果异常一直选择上抛,最终会抛给main方法,main方法抛给调用者JVM,JVM知道异常的发生会终止虚拟机。

在这里插入图片描述

此处的IO异常是编译时异常,要求编写代码的时候必须进行预处理,不预先处理编译无法通过,而处理异常有两种方式此处选择使用throws关键字将异常上抛
在这里插入图片描述
此处可以看到,method方法将异常抛给调用者main方法,main方法没有对异常进行处理,所以此处同样无法通过编译,如果在main方法中选择将异常上抛,那么会将异常抛给JVM。
在这里插入图片描述
此时可以通过编译期,但是在程序运行期间,JVM看到异常的发生最终会终止程序的运行
在这里插入图片描述

深入throws

  1. 使用throws关键字抛出异常时,可以上抛多个,异常类型之间使用","隔开
  2. 可以抛出一个更宽泛的异常,即抛出父类异常类型(多态)

try…catch语句

在可能会发生异常中位置使用try语句块,同时使用catch语句块进行捕捉。对于下面的代码我们使用try…catch语句对异常进行处理
在这里插入图片描述
在这里插入图片描述
运行结果如下,此处对异常处理完毕,打印异常信息。
在这里插入图片描述

finally子句

  1. 何时使用:通常finally来完成资源的释放/关闭,因为finally语句块有保障,就算try中
    发生异常,finally也会正常执行
  2. finally语句块中的内容一定会执行,(使用System.exit(0)终止虚拟机除外)
  3. finally语句块必须和try语句块同时出现,不能单独使用

深入try…catch…finally

深入try…catch…finally

  1. catch后面的小括号中可以是具体的异常类型,也可以是父类的类型(多态)
  2. catch后面的小括号可以写多种异常类型,例如:“catch(IOException | NullPointerException e) {}” ----> Java8新特性
  3. catch可以写多个,建议catch的时候,精确的一个一个的处理,这样有利于程序的调试
  4. catch写多个的时候,从上到下,必须遵守从小到大
  5. try中语句出现异常后,后面的语句是无法被执行到的
  6. try语句块不能单独出现,必须和catch或finally语句块联合使用,反之亦然,
    即catch、finally语句块不能单独出现,必须和try语句块联合使用

自定义异常

自定义编译时异常

编写一个Java类,让其继承Exception,并在构造方法中调用父类构造

public class MyException extends Exception {

	public MyException(){}

	public MyException(String message){
		super(message);
	}
	
}


自定义运行时异常

编写一个Java类,让其继承RuntimeException,并在构造方法中调用父类构造

public class MyException extends RuntimeException {

	public MyException(){}

	public MyException(String message){
		super(message);
	}

}


异常相关面试题

throw和throws区别

  1. 使用位置不同:throw是在方法体中使用,throws是在方法定义时使用
  2. 抛出的内容不同:throw抛出的是异常对象,throws抛出的是异常的类型,可以同时抛出多种类型,类型之间使用“,”隔开
  3. 使用throw一定会有异常,使用throws可能会存在异常

finally与return同时出现

public class Test {

	static int i = 10;

	public static void main(String[] args){
		System.out.println("returnValue: " + method() + "," + "i: " + i);
	}

	public static int method() {

		try {
			return i;
		} finally {
			i++;
		}
		
	}
}

上面代码的运行结果是什么? 划我查看

在Java中有这样的两条规则,(规则不容破坏,必须遵守)

  • 方法体中的代码必须自上而下依此执行
  • return语句一旦执行方法必须结束。

所以对于上面的代码,为了保证这两条语法规则,编译器的编译结果是这样的

  1. 首先执行try语句块中的代码,将i的值赋值给一个临时变量j (即int j = i;)
  2. 然后执行finally语句块中的代码,i++;
  3. 最后将变量j返回

finally、finalize、final区别

final —> 关键字

1. 被final修饰的类无法被继承
2. 被final修饰的方法无法被重写
3. 被final修饰的变量无法再次赋值

finally —> 关键字

1. finally语句块必须和try语句块联合使用
2. finally中的代码必须执行(在try语句块中使用System.exit(0)除外)

finalize —> 标识符

1. finalize是Object类中的一个实例方法名
2. finalize方法是由GC机制调用,重写此方法在当前实例被GC机制回收时执行(实例的遗嘱)

异常UML图

在这里插入图片描述


  1. Java把异常信息打印到控制台,供程序员参考。程序员看到异常信息后可以对程序针对性修改,让程序更加健壮 ↩︎

  2. 在编写代码处理编译时异常时,此处并没有异常的产生只是对异常的预先处理,异常也是对象,对象只会在运行期初始化。 ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值