Java-高阶-异常处理

目录

Java异常体系

Error

Exception

未检查异常

已检查异常

异常的捕获与处理

try语句块

catch语句块

finally语句块

try-catch-finally语句的执行过程

基本执行流程

try块中有return语句:

catch块中有return语句:

实例:

try中有return,finally无return

try和finally都有return

catch中有return

关键规则总结

使用throws抛出异常

基本规则

子类重写父类方法是throws的规则

经典练习:下面那个语句不能通过编译?        

自定义异常类


异常,是程序在运行期间发生的意外状况。对于程序设计者需要尽可能地预见可能发生的意外,尽可能地保证程序在各种糟糕的情况下仍可以运行。Java语言提供了成熟的异常处理机制。

Java异常体系

Java将所有的错误封装成为一个对象,Throwable类是这个异常体系的根,它有两个子类:Error和Exception

Error

Error类及其子类对象代表了程序运行时Java系统内部的错误。对于Error,程序设计者无能为力,程序不能从Error恢复,因此不必处理它们,从技术上讲Error不是异常

Exception

  • Exception通常是由于某个资源不可用,或者正确执行程序所需的条件不满足所造成的。Exception类及其子类对象是程序设计者应该关心、并尽可能加以处理的部分。

Java将Exception分为两类:

  • RuntimeException(运行时异常,也称为未检查异常Unchecked Exception)
  • 非RuntimeException(也称为已检查异常 checked Exception)

以下称未检查异常和已检查异常

未检查异常

  • 未检查异常包含java.lang.RuntimeException类及其所有子类
  • 未检查异常是程序员没有进行必要的检查,因疏忽或者是错误而引起的异常,是可以避免的

已检查异常

  • 除了java.lang.RuntimeException之外的所有异常都属于此类
  • 最常见的如IOException及其子类(像找不到文件的FileNotFoundException,意外到达文件尾部EOFException等都是它的子类)、数据库访问错误SQLException、解析时出现的异常ParseException等,已检查异常是不可避免的

异常的捕获与处理

try语句块

  • 将可能产生异常的代码放在try语句块中尝试执行,异常发生之后的代码不会被执行
  • 在程序执行过程中,该段代码可能会产生并抛出一种或几种异常,这些异常都由它后面的catch负责捕获、处理。所以一个try语句块后面可以跟多个catch语句块(从语法的角度也可以一个catch都没有)

catch语句块

  • 每个catch语句块捕获、处理一种类型的异常。当异常发生时,程序会中断正常的流程,离开try语句块去执行相应的catch语句块
  • 在catch中声明了异常对象(如ParseException e),异常对象封装了异常事件的相关信息,在catch语句块中可以使用这个对象获取这些信息,常用方法包括:
  1. getMessage():返回该异常的详细描述字符串。
  2. printStackTrace():将异常事件的跟踪栈信息输出。

注意:一般情况下,catch语句块只能捕获一种异常,但是Java 7 SE之后,允许catch捕获多个Exception,即当出现多个异常处理措施时,可以使用 | 符号隔开跟在catch后面。但是不允许这些异常出现继承关系。

finally语句块

  • finally语句块为可选,一旦出现,无论try语句块是否抛出异常,finally代码块都要被执行
  • finally语句块为异常处理提供统一的善后处理,使流程转到其他部分之前,能够对程序的状态进行统一的管理
  • 通常在finally语句块中进行资源释放的工作,如关闭已打开的文件、关闭数据库连接等

try-catch-finally语句的执行过程

基本执行流程

  • try块中有return语句
    1. 先执行try块中的代码,直到遇到return语句

    2. 计算return表达式的值(此时值会被暂存,但不会立即返回)

    3. 执行finally块中的代码

    4. 最后返回之前暂存的return值

  • catch块中有return语句
    1. 如果try块抛出异常,进入匹配的catch块

    2. 执行catch块中的代码,直到遇到return语句

    3. 计算return表达式的值(暂存)

    4. 执行finally块中的代码

    5. 返回暂存的return值

实例:

try中有return,finally无return
public static int test1() {
    try {
        System.out.println("try block");
        return 1;  // 这个值会被暂存
    } catch (Exception e) {
        System.out.println("catch block");
        return 2;
    } finally {
        System.out.println("finally block");
    }
}

// 输出:
// try block
// finally block
// 返回: 1
try和finally都有return
public static int test2() {
    try {
        System.out.println("try block");
        return 1;  // 这个值会被丢弃
    } catch (Exception e) {
        System.out.println("catch block");
        return 2;
    } finally {
        System.out.println("finally block");
        return 3;  // 这个值会覆盖之前的return
    }
}

// 输出:
// try block
// finally block
// 返回: 3 (finally中的return会覆盖try中的return)
catch中有return
public static int test3() {
    try {
        System.out.println("try block");
        throw new Exception();
    } catch (Exception e) {
        System.out.println("catch block");
        return 2;  // 这个值会被暂存
    } finally {
        System.out.println("finally block");
    }
}

// 输出:
// try block
// catch block
// finally block
// 返回: 2

关键规则总结

  • finally优先执行:无论try或catch是否有return,finally都会执行(因为try、catch中是暂存的)

  • 返回值确定时机

    • 如果finally中没有return:try或catch中的return值会在执行前计算并暂存,finally执行后返回

    • 如果finally中有return:会覆盖之前try或catch中的return值

  • 特殊情况

    • 如果在finally中修改了try/catch中要返回的变量,不会影响已暂存的基本类型值

    • 但对于引用类型,修改对象状态会影响返回的对象

使用throws抛出异常

基本规则

[访问修饰符] 返回类型 方法名(参数列表) throws 异常类型1, 异常类型2, ... {
    // 方法体
}

子类重写父类方法是throws的规则

  • 可以抛出与父类相同的异常
  • 可以抛出父类异常的子类
  • 可以不抛出异常

经典练习:下面那个语句不能通过编译?        

public class CC {
	void doStuff() throws IOException{}
}
public class CC2 extends CC{
	void doStuff() throws FileNotFoundException {}
}
public class CC3 extends CC{
	void doStuff() throws Exception{}
}
public class CC4 extends CC{
	void doStuff(int x) throws Exception{}
}
public class CC5 extends CC{
	void doStuff(){}
}

自定义异常类

  • 为该异常类取一个能标识异常状况的有意义的名字
  • 令其继承Exception类
  • 在异常类中至少定义两个构造方法:一个是无参的;另一个是带String参数的,将此字符串传递给父类Exception的相同构造方法。这个String将作为该异常对象的描述信息(即getMessage()方法的返回值)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值