第九章 异常的捕获和处理

异常的捕获和处理
一.异常概述
异常是指程序在运行过程中所发生的不正常事件,如所需文件找不到、网络连接不通或连接中断、算数运算出错(如被0除)、数组下标越界、装载一个不存在的类、对null对象操作、类型转换异常等。
异常会中断正在运行的程序。
可以通过if—else语句对各种异常情况进行判断处理,但是使用if—else进行异常处理会有代码臃肿、影响开发效率、难以穷举、后期维护困难等缺点。
Java提供了异常处理机制,可以由系统来处理程序在运行过程中可能出现的异常事件,使程序员有更多精力关注于业务代码的编写。
异常处理机制使程序的异常处理代码和业务逻辑代码分离,保证了程序代码的优雅型,提高了程序的健壮性、安全性和可维护性。
二.常见异常类型
Java中的异常有很多类型,异常在Java中被封装成了各种异常类,所有异常类型都是 Throwable 类的子类,它派生了两个子类:Error类和Exception类。

hasNextInt判断下一个输入是否是整数型,函数是返回类型是Boolean型也就是如果下一个输入转换整数那就那就返回true否则是fale

  1. Error类
    表示仅靠程序本身无法恢复的严重错误,如内存溢出、动态链接失败、虚拟机错误。应用程序不应该抛出这种类型的错误(一般由虚拟机抛出)。

假如出现这种错误,应尽力使程序安全退出。所以在进行程序设计时,应该更关注Exception类。

  1. Exception类
    由Java应用程序抛出和处理的非严重错误,如所需文件找不到、网络连接不通或连接中断、算数运算出错(如被0除)、数组下标越界、装载一个不存在的类、对null对象操作、类型转换异常等。它的各种不同的子类分别对应不同类型的异常。Exception又可分为两大类异常。

1)运行时异常:包括RuntimeException及其所有子类。

2)Checked异常:除了运行时异常外的其他从Exception类继承来的异常类。
在这里插入图片描述
三.异常处理
1.基本概念
异常处理机制就像人们对平时可能会遇到的意外情况,预先想好了一些处理的办法。

在程序执行代码时,若发生了异常,程序会按照预定的处理办法对异常进行处理,异常处理完毕之后,程序继续运行。

Java的异常处理是通过5个关键字来实现,即:try、catch、finally、throw和throws。

2.使用 try—cath 处理异常
Java中提供了try—catch结构进行异常捕获和处理,把可能出现异常的代码访入try语句块中,并使用catch语句块捕获异常。
案例
在这里插入图片描述
2)执行流程
首先执行try语句块中的语句。

当try中的语句没有发生异常,catch中的语句将被忽略,执行后续代码;

当try中的语句发生异常,并且这个异常与catch语句块中声明的异常类型一致,那么try语句块中剩余的代码都将被忽略,而相应的catch语句块将被执行。

当try中的语句发生异常,并且这个异常与catch语句块中声明的异常类型不一致或不是它的子类,那么方法立即退出。

3)常用异常对象的方法
void printStackTrace():

输出异常的堆栈信息。堆栈信息包括程序运行到当前类的执行流程,他将输出从方法调用处到异常抛出处的方法调用序列。

String getMessage():

返回异常信息描述字符串,该字符串描述了异常产生的原因,是printStackTrace()输出信息的一部分。

  1. finally 关键字
    如果希望无论try中的语句是否发生异常都要运行的代码块,需要在try—catch语句后加上finally语句块。
    finally 语句块中语句不执行的唯一情况是在异常处理代码中执行了System.exit(1)退出Java虚拟机
    无论是否发生异常,finally中的代码总能被执行。
    案例
    在这里插入图片描述
    注意
    try—catch—finally结构中try语句块是必须存在的,catch、finally语句块可选,但两者至少出现其中之一。

需要特别注意的是,即使在catch语句块中存在return语句,finally语句块中的语句也会执行。发生异常时的执行顺序是,先执行catch语句块中return之前的语句,再执行finally语句块中的语句,最后执行catch语句块中return语句退出。

finally语句块中语句不执行的唯一情况是在异常处理代码(catch)中执行了**System.exit(1)**退出java虚拟机。
4.多重catch
一段代码可能会引发多种类型的异常,此时可以用在一个try语句块后面跟多个catch语句块分别处理不同的异常。

但排列顺序必须是子类到父类, 最后一个一般都是Exception类。因为按照匹配原则,如果把父类异常放到前面,后面的catch语句块将不会被执行机会。

运行时,系统从上到下分别对每个catch语句块处理的异常类型进行检测,并执行第一个与异常类型匹配的catch语句。执行其中的一条catch语句之后,其后的catch语句将被忽略。

5.抛出异常
1)使用throws声明自动抛出异常
throws用在方法声明后面,后带异常类型,可以带多个异常类型,之间由逗号隔开。

throws表示出现异常的一种可能性,并不一定会发生这些异常

作用是表明该方法可能要抛出这种类型异常,不处理异常,将其抛给方法调用者,提醒方法调用者要捕获该异常。

如果throws声明的方法在main方法中确实出现了异常,则有两种处理方式:

​ ①通过try—catch捕获并处理

​ ②继续使用throws抛出异常,让再上一级调用者处理异常,main()方法抛出的异常将有Java虚拟机来处理。

2)使用throw声明手动抛出异常
throw是用在方法体里,用来抛出不符合程序员设计这个程序理念的特定异常,由程序员手动抛出,明确这个地方要抛出异常,把问题提交给设计者解决。

throw是抛出了异常,执行throw则一定抛出了某种异常,所以它是抛出一个异常实例。

3)注意
两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
在这里插入图片描述
6.自定义异常
当JDK中的异常类型不能满足程序的需要时,可以自定义异常类。使用自定义异常一般有如下几个步骤。

1)步骤
①定义异常类,并继承Exception或者RuntimeException。

②编写异常类的构造方法,并继承父类的实现,常见的构造方法有如下4种形式。

public MyException() {
		super();
	}
public MyException(String message) {
		super(message);
	}
public MyException(String message,Throwable cause) {
		super(message,cause);
	}
public MyException(Throwable cause) {
		super(cause);
	}

③实例化自定义异常对象,并在程序中使用throw抛出。
在这里插入图片描述
7.异常链
当A方法调用了B方法,B方法却抛出了异常。

那么A方法是抛出原有异常还是抛出一个新异常?

如果抛出原有异常,因为A与B进行了关联,所以不便于代码的修改和扩展。

如果抛出新异常,虽然解决了A和B的关联问题,但是原有的异常却丢失了。

JDK1.4推出了异常链,正好解决了这个问题,虽然创建了新异常,但却保留了原有异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值