Java 异常知识讲解

本文深入解析Java异常处理机制,包括Throwable、Error与Exception类的区别,运行时异常与非运行时异常的特点,以及自定义异常的实现。探讨了异常在代码中的作用及如何有效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Throwable
Error
Exception
VirtualMachineError
ThreadDeath
RuntimeException
IOException
ArrayIndexOutOfBoundsException
ArithmeticException
IllegalArgumentException
ArrayStoreException
NegativeArraySizeException
NullPointerException
SecurityException
EOFException
FileNotFoundException

写在前面

一个方法通常有个程序出口,当方法不能被正确执行完毕时候,会以另一种方式执行完毕,这种执行方式就是异常的执行。

Java 中所有异常都有个共同祖先 Throwable,其有两个重要子类 Exception(异常)和 Error(错误),Error Java 编译器无法检查的,Exception 主要分为 RuntimeException 和其他非 RuntimeException 的异常,由于 RuntimeException 诸如数组越界这些异常时 Java 编译器在编译阶段无法发现的,只有程序运行到这一步才能报出异常,所以运行异常又称为不可查异常(unchecked exceptions)非运行异常又称可查异常(checked exceptions),像数组越界的异常等都属于运行异常(不可查异常),像一些代码逻辑错误和一些 IO 操作抛出的都是非运行异常(可查异常)

Throwable 类

  • 其及其子类有两个构造方法,一个不带参数,一个带 String 参数
  • 为什么要实现 Serializable 接口,因为将对象状态保存在存储媒体中以便在以后重新创建处完全相同的副本,还有可以按值将对象从一个应用程序域发送到另一个应用程序域。通俗说就是分布式应用中,你就得实现序列化。实际上 Java 很多类都实现了 Serializable 接口
  • 其下有 Error(不可检查)和 Exception(分可查和不可查)两大类
  • try catch可以捕获其及其子类对象的抛出,但是try catch效率非常低下

Error 类

  • 它们都在java.lang

  • 一般是程序中严重的错误,如虚拟机层面错误,一旦发生程序本身无法正常处理,通常和 JVM 内存区域脱不了关系,一旦程序出了 Error,我们建议去看一看 heap dump,修改下 JVM 参数,发生了 Error 程序直接崩掉,用 Java 代码的方式无法弥补

  • 可以throw抛出但是无法try catch捕获

  • OutOfMemoryError(OOM) 内存溢出错误,通常发生在 Java 堆上

  • StackOverflowError(SO) 栈溢出错误,常发生在递归过深的情况,常常发生在虚拟机栈上

Exception 类

  • 它们都在java.lang

  • 其可分为运行时异常(RuntimeException)和非运行异常(如 IOException),有很多异常都是运行时异常,Java 不强行对这类异常进行捕获,仍可进行手工捕获来避免意外,对运行时异常进行进一步划分:

    • 可预测异常(PE):一般由代码错误或外部因素,如空指针,数组越界
    • 警告级异常(CE):需要显示的捕获处理,否则程序不可用,如 TimeoutException
    • 可忽略异常(IE):程序可自行处理的异常,程序员可忽略,这类异常不由程序员捕捉
  • 非运行异常有如 SQLExceptionClassNotFoundExceptionCloneNotSupportedExceptionIllegalAccessExceptionInterruptedExceptionNoSuchFieldExceptionNoSuchMetodExceptionIOExceptionEOFExceptionFillNotFoundException

  • 对于运行时异常为 RuntimeException 及其子类,发生异常时候我们无需在方法上向上抛出,也没有必要去 try catch 处理,发生异常基本就是代码问题,需要修改

  • 对于非运行时异常的产生,我们需要向上抛出,如果不想再抛出需要进行 try catch 捕获自行做处理

自定义异常

对于项目中的自定义异常我们一般是继承 RuntimeException 运行时异常类(下面例子中是继承 Exception 类)

/**
 * 自定义异常类继承 Exception
 * 重写父类构造器
 */
public class MyException extends Exception{
    public MyException(){
		super();
	}
    public MyException(String str){
        super(str);
    }
}

/**
 * 测试类
 */
public class MyTest{
    public void testMyException(){
        // 产生随机数,1 或者 2
        Random r = new Random();
        int x = r.nextInt(2) + 1;
        // 判断
        if(x == 1){
            System.out.println("随机数是 1");
        }
        else{
            // 捕获自定义异常
            try{
                // 抛出自定义异常
                throw new MyException("随机数是 2 不是 1 !");
            } catch (MyException e) {
                e.printStackTrace();
            } finally {
                System.out.println("不论是否捕获了异常这里都将执行");
            }
        }
    }
}

其他

对于底层代码是如何实现异常的以及 JVM 底层是如何处理异常的机理,我推荐一篇博文深析 Java 线程池异常机理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值