JAVA基础教程12:异常

本文详细介绍了Java中的异常处理机制,包括Throwable、Error与Exception的区别,常见异常类型如NullPointerException和IOException的处理方式,以及如何正确地使用异常处理原则。

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

Throwable是java程序所有错误的父类。包括error和excepetin。
这里写图片描述

Error

简单理解,无法预期的严重错误无法(其实是不应该)任何回复操作。JVM回立刻退出。
如果深究,其实Error也可以catch住的。但是一般没啥意义,比如说OOM,所有线程都会再下面的操作中继续重复OOM。

    public static void main(String[] args) {
        try{
            test();
        }catch (Throwable e){
            System.out.println("catch!");
            e.printStackTrace();
        }
        System.out.println("finish");
    }

    private static int test(){
        return test();
    }

上面的代码回打印处finish。说明ERROR也是可以catch的。包括NoClassDefFoundError之类的Error都是可以捕获的。而且,Error即使不捕获,ERROR也影响只当前线程,不会导致JVM退出。下面代码运行JVM不会自动退出。

    public static void main(String[] args) {

        Thread thread = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();//即使Kill -9 这一块也不会被执行到!!
                    }
                }
            }
        });
        thread.start();
        test();
    }
    
    private static int test(){
        return test();
    }

多说一句,Kill -9 不会触发任何异常和Error。
所以使用KILL指令强行清除java进程时可能会造成一些问题,如TCP连接单方面关闭等。

java异常简介

exception提供了两类,一类是runtime exception 一类是checked exception(除了RuntimeException子类的所有异常)。对于后一种包括我们常见的IO异常和SQL异常,必须对这些异常进行catch。

常见的runtimeexception有
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常.

runtimeexception的设计初衷是JVM常用操作引发的错误。
下面的代码会在运行时报错。但是完全可以通过编译。

public class Test
{
	public static void main(String[] args)
    {
	    int a[]={2,3,5,32,6};
        for (int i = 0; i <5; i++)
        {
	        System.out.print(a[i]);
        }
    }
}

如果是checcked exception,在编译时就会被检查。所以,必须处理或者抛出。否则编译失败

Exception和Error的区别

NoClassDefFoundError VS ClassNotFoundException

NoClassDefFoundError一般是JVM通过默认的Classloader在进行类加载、链接的时候,找不对对应的Class文件而抛出来的,它的cause也是ClassNotFoundException。
ClassNotFoundException一般不会是直接抛出来的最上层的异常。现在很多项目都会使用第三方的框架或者运行在容器中,这些框架通常都会定义自己的Classloader去加载不同的类,然后通过反射去操作这些类。当找不对对应的Class文件时,自定义的Classloader也会抛出ClassNotFoundException,框架可以捕获这个异常,并将其包装成具体的异常,然后向上抛出。

  • ClassNotFoundException是在类加载时找不到class文件时抛出的异常
  • JVM默认的Classloader在遇到ClassNotFoundException时,会抛出NoClassDefFoundError
  • 自定义Classloader进行管理类加载的框架或容器,在遇到ClassNotFoundException时,通常会抛出和当前具体错误相关的异常

java异常处理原则

java异常处理的三原则是具体明确,提早抛出,延迟捕获。最后一条是指不要在有能力处理异常之前捕获异常。假设你要为别人提供一个返回正负金额的方法供调用,返回值是Integer,就请不要再自己的程序内部捕获诸如网络错误的异常。因为你捕获了也没什么用,捕获后最大的处理也不过就是让返回值为null,这一点将更加让别人困惑。

反射的异常

具体实现中发生的异常(无论是runtime exception还是checked exception)会被包装为InvocationTargetException(这是一个runtime exception)。一旦发生异常,如果代理类在接口中没有声明,就会抛出UndeclaredThrowableException(这是一个RuntimeException,java.lang.reflect包和cglib中都有对应实现)。为了还原异常,你需要在动态代理的invoke方法中手动捕获异常,根据e.cause抛出新的异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值