Java 异常机制详解:从基础到自定义异常

目录

1. 异常概述

1.1 异常的体系

1.2 错误(Error)

1.3 异常(Exception)

2. 运行时异常

2.1 异常的自动抛出

2.2 异常的处理:try...catch

3. finally 块

3.1 try...finally

3.2 try...catch...finally

4. 编译期异常

4.1 处理方式

5. 自定义异常

5.1 自定义异常规则

5.2 使用自定义异常


1. 异常概述

1.1 异常的体系

Java 中的异常体系以 Throwable 为根类,分为两大类:

  • Error:表示程序无法处理的严重问题,通常由 JVM 抛出,如 OutOfMemoryError

  • Exception:表示程序可以处理的异常,分为运行时异常和编译期异常。

1.2 错误(Error)

Error 是 Throwable 的子类,表示程序出现了严重问题,通常无法通过程序解决。例如:

  • OutOfMemoryError:内存溢出。

  • StackOverflowError:栈溢出。

1.3 异常(Exception)

异常是程序可以处理的问题,分为两类:

  1. 运行时异常(RuntimeException):程序在运行期间抛出的异常,编译时不会报错。

    • 例如:ArithmeticException(算术异常)、NullPointerException(空指针异常)。

  2. 编译期异常:必须在编译时处理,否则无法通过编译。

    • 例如:IOExceptionSQLException


2. 运行时异常

2.1 异常的自动抛出

运行时异常会在程序运行期间自动抛出。例如:

public class ExceptionDemo {
    public static void main(String[] args) {
        int result = divide(10, 0); // 抛出 ArithmeticException
        System.out.println(result);
    }

    public static int divide(int a, int b) {
        return a / b;
    }
}

运行结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at ExceptionDemo.divide(ExceptionDemo.java:10)
    at ExceptionDemo.main(ExceptionDemo.java:5)

2.2 异常的处理:try...catch

通过 try...catch 块可以捕获并处理异常:

public class ExceptionDemo3 {
    public static void main(String[] args) {
        int result = 0;
        try {
            result = divide(10, 0); // 捕获异常
        } catch (ArithmeticException e) {
            System.out.println("除数不能为 0,已处理异常");
            result = divide(10, 2); // 处理异常后继续执行
        }
        System.out.println("结果:" + result);
    }

    public static int divide(int a, int b) {
        return a / b;
    }
}

运行结果:

除数不能为 0,已处理异常
结果:5

3. finally 块

finally 块用于执行必须完成的代码,无论是否发生异常。

3.1 try...finally

public static int divide(int a, int b) {
    int c = 0;
    try {
        c = a / b;
    } finally {
        System.out.println("finally 块执行");
    }
    return c;
}

3.2 try...catch...finally

public static int divide(int a, int b) {
    int c = 0;
    try {
        c = a / b;
    } catch (ArithmeticException e) {
        System.out.println("捕获异常");
    } finally {
        System.out.println("finally 块执行");
    }
    return c;
}

4. 编译期异常

编译期异常必须在编译时处理,否则无法通过编译。常见的编译期异常包括 IOExceptionSQLException 等。

4.1 处理方式

  • try...catch 处理

    public class ExceptionDemo12 {
        public static void main(String[] args) {
            try {
                method();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method() throws IOException {
            ServerSocket ss = new ServerSocket(8080);
        }
    }
  • 向上抛出

    public class ExceptionDemo13 {
        public static void main(String[] args) throws FileNotFoundException {
            method();
        }
    
        public static void method() throws FileNotFoundException {
            FileReader fr = new FileReader("d:\\aaa.txt");
        }
    }

5. 自定义异常

在实际项目中,我们可能需要定义与业务相关的异常。自定义异常通常继承 RuntimeException

5.1 自定义异常规则

  • 继承 RuntimeException

  • 提供构造方法。

public class StockException extends RuntimeException {
    public StockException(String message) {
        super(message);
    }
}

5.2 使用自定义异常

public class ExceptionDemo14 {
    public static void main(String[] args) {
        try {
            submitOrder(6); // 抛出 StockException
        } catch (StockException e) {
            System.out.println(e.getMessage());
            submitOrder(5); // 处理异常后继续执行
        }
    }

    public static void submitOrder(int stock) {
        if (stock > 5) {
            throw new StockException("库存不足:" + stock);
        }
        System.out.println("购买成功");
    }
}

运行结果:

库存不足:6
购买成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值