Java 的异常体系

Java 中 Throwable 是所有异常和错误的超类,两个直接子类是 Error(错误)和 Exception(异常)
在Java中,异常的根类是java.lang.Throwable类,而根类又分为两大类:Error和Exception:
Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常Exception,也就是我们经常见到的一些异常情况,比如NullPointerException、IndexOutOfBoundsException,这些异常是我们可以处理的异常
1)Error 是程序无法处理的错误,由 JVM 产生和抛出,如 OOM、ThreadDeath 等。这些异常
发生时,JVM 一般会选择终止程序。
2)Exception 是程序本身可以处理的异常,又分为运行时异常(RuntimeException)(也叫 Checked
Eception) 和 非 运 行 时 异 常 ( 不 检 查 异 常 Unchecked Exception) 。 运 行 时 异 常 有NullPointerException\IndexOutOfBoundsException 等,这些异常一般是由程序逻辑错误引起的,应尽可能避免。非运行时异常有 IOException\SQLException\FileNotFoundException 以及由用户自定义的 Exception 异常等。
常见的运行时异常的编译时异常:
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ClassNotFoundException - 类找不到异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常

Java的异常体系是基于类的继承关系构建的,所有的异常类都是从Throwable类派生的。Java的异常体系包括以下几个主要的类和接口:

  1. Throwable:是所有异常类的根类,它有两个重要的子类:Error和Exception。
    ○ Error:表示系统级错误或者资源耗尽等严重问题,通常不需要程序员进行捕获和处理。例如,OutOfMemoryError和StackOverflowError。
    ○ Exception:表示可以被程序捕获和处理的异常,它又分为两种类型:
    ■ 受检异常(Checked Exception):编译器要求程序必须显示地处理这类异常,否则无法通过编译。例如,IOException和SQLException。
    ■ 非受检异常(Unchecked Exception):也称为运行时异常(RuntimeException),程序在运行时才会遇到这类异常,编译器不要求强制处理。例如,NullPointerException和ArrayIndexOutOfBoundsException。
  2. Exception和RuntimeException:Exception是受检异常的父类,RuntimeException是非受检异常的父类。程序员可以自定义异常类,继承自Exception或RuntimeException,并添加自己的异常类型。
  3. 异常处理相关的关键字和语句:
    ○ try-catch:用于捕获和处理异常的语句块。
    ○ throws:用于在方法签名中声明方法可能会抛出的异常类型。
    ○ finally:可选的清理代码块,在try-catch块执行完毕后无论是否发生异常都会执行。
    ○ throw:用于手动抛出异常对象。
  4. 异常处理的接口:
    ○ Throwable接口:所有异常类都实现了该接口,它提供了一些方法用于获取异常信息的相关内容,如getMessage()和printStackTrace()。
    ○ Exception接口:继承自Throwable接口,是所有受检异常的父接口。
    ○ RuntimeException接口:继承自Exception接口,是所有非受检异常的父接口。
    通过Java的异常体系,程序员可以根据具体的情况捕获和处理异常,从而增加程序的健壮性和可靠性。同时,合理地使用异常处理机制能够提供更好的错误处理和故障排查能力。
public class Main {
    public static void main(String[] args) {
        try {
            System.out.println("开始执行try块");
            int result = 10 / 0; // 这里会抛出ArithmeticException异常
            System.out.println("执行try块中的除法运算结果:" + result); // 这句代码不会被执行
        } catch (ArithmeticException e) {
            System.out.println("捕获到ArithmeticException异常:" + e.getMessage());
        }
        System.out.println("try-catch块外的代码"); // 这句代码会被执行
    }
}

异常处理方式

在Java中,异常处理是通过使用try-catch语句块来实现的。以下是Java中常见的异常处理方式:

  1. try-catch语句块:用于捕获和处理异常。在try块中,放置可能抛出异常的代码,而在catch块中,处理捕获到的异常。
try {
    // 可能抛出异常的代码
} catch (ExceptionType1 e1) {
    // 处理 ExceptionType1 类型的异常
} catch (ExceptionType2 e2) {
    // 处理 ExceptionType2 类型的异常
} finally {
    // 可选的 finally 块,用于执行清理操作,无论是否发生异常都会执行
}
  1. throws声明:如果方法可能抛出异常,但不想在方法内捕获它们,可以使用throws关键字在方法签名中声明。这将使得调用该方法的代码需要处理(捕获或继续抛出)这些异常。
    javaCopy Codepublic void method() throws ExceptionType1, ExceptionType2 {
    // 可能抛出异常的代码
    }
  2. 自定义异常:除了Java内置的异常类型,您还可以创建自定义的异常类型来表示特定的错误情况。为此,您可以扩展Exception或RuntimeException类。
public class CustomException extends Exception {
    // 添加自定义异常的额外信息和行为
}
1. finally块:finally块是可选的,它通常用于执行清理操作,例如关闭文件或释放资源。无论是否发生异常,finally块中的代码都会被执行。
javaCopy Codetry {
    // 可能抛出异常的代码
} catch (Exception e) {
    // 处理异常
} finally {
    // 清理操作
}
1. 异常链:通过在catch块中使用throw语句,可以将一个异常对象抛出到更高层的异常处理程序,从而创建异常链。
javaCopy Codetry {
    // 可能抛出异常的代码
} catch (Exception e) {
    throw new HigherLevelException("An error occurred.", e);
}

这些是Java中常见的异常处理方式。通过合理地处理异常,可以增加程序的稳定性和可靠性,并提供更好的错误信息和故障排查能力

常见异常总结

此部分可以api文档中进行查阅,这里仅做参考。
常见异常:
java.lang.IllegalAccessError:违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常。
java.lang.InstantiationError:实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.
java.lang.OutOfMemoryError:内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。
java.lang.StackOverflowError:堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出或者陷入死循环时抛出该错误。
java.lang.ClassCastException:类造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。
java.lang.ClassNotFoundException:找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
java.lang.ArithmeticException:算术条件异常。譬如:整数除零等。
java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.IndexOutOfBoundsException:索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。
java.lang.InstantiationException:实例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。
java.lang.NoSuchFieldException:属性不存在异常。当访问某个类的不存在的属性时抛出该异常。
java.lang.NoSuchMethodException:方法不存在异常。当访问某个类的不存在的方法时抛出该异常。
java.lang.NullPointerException:空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
java.lang.NumberFormatException:数字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。
java.lang.StringIndexOutOfBoundsException:字符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常。
其他异常:
java.lang.AbstractMethodError:抽象方法错误。当应用试图调用抽象方法时抛出。
java.lang.AssertionError:断言错。用来指示一个断言失败的情况。
java.lang.ClassCircularityError:类循环依赖错误。在初始化一个类时,若检测到类之间循环依赖则抛出该异常。
java.lang.ClassFormatError:类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。
java.lang.Error:错误。是所有错误的基类,用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。
java.lang.ExceptionInInitializerError:初始化程序错误。当执行一个类的静态初始化程序的过程中,发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。
java.lang.IncompatibleClassChangeError:不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时,抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下,容易引发该错误。
java.lang.InternalError:内部错误。用于指示Java虚拟机发生了内部错误。
java.lang.LinkageError:链接错误。该错误及其所有子类指示某个类依赖于另外一些类,在该类编译之后,被依赖的类改变了其类定义而没有重新编译所有的类,进而引发错误的情况。
java.lang.NoClassDefFoundError:未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类,而找不到该类的定义时抛出该错误。
java.lang.NoSuchFieldError:域不存在错误。当应用试图访问或者修改某类的某个域,而该类的定义中没有该域的定义时抛出该错误。
java.lang.NoSuchMethodError:方法不存在错误。当应用试图调用某类的某个方法,而该类的定义中没有该方法的定义时抛出该错误。
java.lang.ThreadDeath:线程结束。当调用Thread类的stop方法时抛出该错误,用于指示线程结束。
java.lang.UnknownError:未知错误。用于指示Java虚拟机发生了未知严重错误的情况。
java.lang.UnsatisfiedLinkError:未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出。
java.lang.UnsupportedClassVersionError:不支持的类版本错误。当Java虚拟机试图从读取某个类文件,但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候,抛出该错误。
java.lang.VerifyError:验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误。
java.lang.VirtualMachineError:虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况。
java.lang.ArrayStoreException:数组存储异常。当向数组中存放非数组声明类型对象时抛出。
java.lang.CloneNotSupportedException:不支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。
java.lang.EnumConstantNotPresentException:枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象,但该枚举对象并不包含常量时,抛出该异常。
java.lang.Exception:根异常。用以描述应用程序希望捕获的情况。
java.lang.IllegalAccessException:违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法,而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。
java.lang.IllegalMonitorStateException:违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。
java.lang.IllegalStateException:违法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态,而调用了该方法时,抛出该异常。
java.lang.IllegalThreadStateException:违法的线程状态异常。当县城尚未处于某个方法的合法调用状态,而调用了该方法时,抛出异常。
java.lang.InterruptedException:被中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态,而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。
java.lang.NegativeArraySizeException:数组大小为负值异常。当使用负数大小值创建数组时抛出该异常。
java.lang.SecurityException:安全异常。由安全管理器抛出,用于指示违反安全情况的异常。
java.lang.TypeNotPresentException:类型不存在异常。

你可能感兴趣的:(java基础,Java面试总结,java)