Java 中的异常类型
基本上,Java API中有两种类型的异常。它们是:
- 预定义异常(内置异常)
- 自定义例外
预定义异常:
预定义异常是 Java 系统已定义的那些异常。这些异常也称为内置异常。
Java API 通过提供预定义异常的数量来支持异常处理。这些预定义的异常由 java 中的类表示。
当发生预定义异常时,JVM(Java 运行时系统)会创建预定义异常类的对象。所有异常都派生自 java.lang.Throwable 类,但并非所有异常类都在同一包中定义。
Java 支持的所有预定义异常都组织为 Throwable 类下层次结构中的子类。
Throwable 类是异常层次结构的根,是 Object 类的直接子类。让我们了解一下 java 异常层次结构,如下图所示。
1. Throwable 可抛出类:如上图所示,从 Object 类派生的可抛出类是异常层次结构的顶部,所有异常类都直接或间接派生自该层次结构。它是所有异常类的根。它存在于java.lang包中。
可抛出类是 java 中所有异常的超类。此类有两个子类:错误和异常。Java 程序中发生的错误或异常是这些类的对象。使用 Throwable 类,您还可以创建自己的自定义异常。
2. Error 错误:错误类是 Throwable 类的子类,也是所有运行时错误类的超类。如果存在与系统或资源 (JVM) 相关的问题,它将终止程序。
错误通常表示难以恢复的异常问题或情况。它不是由程序员的错误引起的。如果系统无法正常工作或资源分配不正确,通常会发生这种情况。
VirtualMachineError、StackOverFlowError、AssertionError、LinkageError、OutOfMmeoryError等都是错误的例子。我们将在进一步的教程中了解更多详细信息。
3.Exception 异常:它由一个异常类表示,该类表示由程序和外部因素引起的错误。异常类是 Throwable 类的子类,也是所有异常类的超类。
所有异常类都直接或间接派生自 Exception 类。它们源自应用程序内部。
异常类提供两个构造函数:
- public Exception()(默认构造函数)
- public Exception(String message)(它接受消息字符串作为参数)
每个异常类都提供两个构造函数:一个没有参数,另一个带有 String 类型参数。异常类不提供自己的方法。它继承了 Throwable 类提供的所有方法。
Java 中的异常类层次结构
我们可以在下图中看到 Java 中异常类的层次结构,这对于面试目的非常重要。
自定义例外:
自定义异常是用户或程序员根据自己的需要创建的那些异常。自定义异常也称为用户定义的异常,这些异常是通过扩展异常类创建的。
因此,Java为程序员提供了抛出和处理异常的自由,同时处理他们正在解决的问题的功能需求。我们将在后续教程中更详细地讨论自定义异常。
让我们看看 Exception 类的每个子类的简要说明。
运行时异常类(未选中的异常)
类是 Exception 类的子类。当程序中执行的算术运算不正确或程序代码中出现缺陷/错误时,它由 JVM 或以编程方式抛出。
Java 编译器不检查 RuntimeException 及其所有异常子类,因为它们发生在程序运行时。这就是为什么这些异常也称为未经检查的异常。
类由许多其他异常子类组成,这些子类用于处理特定类型的异常。
除了上图所示的 RuntimeException 类的这些异常子类。RuntimeException 类还有其他子类,为了避免复杂性,这些子类尚未显示在层次结构图中。
让我们看一下它们的简要说明。
1. ArithmeticException:当发生算术问题(例如数字除以零)时,会抛出此异常。也就是说,它是由数学错误引起的。
2. ClassCastException:ClassCastException是一个运行时异常,当我们尝试在程序中进行无效的类型转换时,JVM会抛出它。也就是说,当我们将对象转换为对象不是实例的子类时,就会抛出它。
3. IllegalArgumentException:当传递非法或适当的参数来调用方法时,以编程方式引发此运行时异常。此异常类还有另外两个子类:
- NumberFormatException
- IllegalThreadStateException
NumericFormatException:当我们尝试将字符串转换为数字类型并且非法转换过程失败时,以编程方式抛出 NumberFormatException。也就是说,它是由于将字符串非法转换为数字格式而发生的。
IllegalThreadStateException:IllegalThreadStateException 异常是一个运行时异常,当我们尝试在线程上执行任何操作时,它以编程方式引发,但它与当前线程状态不兼容。
4. IndexOutOfBoundsException:当数组或字符串超出指定索引时,JVM 会抛出此异常类。它还有两个子类:
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
ArrayIndexOutOfBoundsException:当数组元素从索引之外访问时,将引发 ArrayIndexOutOfBoundsException 异常。
StringIndexOutOfBoundsException:当从索引之外访问 String 或 StringBuffer 元素时,将引发 StringIndexOutOfBoundsException 异常。
5. NullPointerException:NullPointerException是当我们尝试使用null而不是对象时由JVM抛出的运行时异常。也就是说,当引用为 null 时,将引发它。
6.ArrayStoreException:当我们尝试将任何值存储在非数组类型的数组中时,会发生此异常。例如,假设一个数组是整数类型,但我们试图存储另一种类型的元素的值。
7. IllegalStateException:当运行时环境未处于调用任何方法的适当状态时,将以编程方式引发非法状态异常。
8. IllegalMonitorStateException:当线程无权监视对象并尝试访问对象的 wait()、notify() 和 notifyAll() 方法时,将引发此异常。
9. NegativeArraySizeException 负数组大小异常:当创建具有负大小的数组时,将引发负数组大小异常。
Java 中已检查的异常列表
现在,我们在简要说明中列出了已检查的异常。
1. ClassNotFoundException:ClassNotFoundException是一种检查异常,当我们尝试使用不存在的类时会抛出它。
检查异常是由 Java 编译器本身检查的异常。
2. FileNotFoundException:FileNotFoundException是一个经过检查的异常,当我们尝试访问不存在的文件时会抛出该异常。
3. InterruptedException 中断异常:中断异常是一个经过检查的异常,当一个线程处于休眠或等待状态并且另一个线程试图中断它时,会引发该异常。
4. InstantiationException 实例化异常:此异常也是当我们尝试创建抽象类或接口的对象时抛出的检查异常。也就是说,实例化抽象类或接口时,会发生实例化异常异常。
5. IllegalAccessException 非法访问异常:非法访问异常是一个已检查的异常,当在另一个方法或类中调用一个方法但调用方法或类无权访问该方法时,会抛出它。
6. IllegalAccessException克隆不支持异常:当我们尝试克隆对象而不实现可克隆接口时,会抛出此选中的异常。
7. NoSuchFieldException:这是在程序中使用未知变量时引发的已检查异常。
8. NoSuchMethodException:当在程序中使用未定义的方法时,将引发此检查异常。
要记住的要点:
- Java 中的两种异常类型:预定义异常和自定义异常。
- 异常类层次结构中所有异常的根类是java.lang.Throwable。
- 异常类主要分为三种类型:系统错误、异常和运行时异常。
- 系统错误由错误类表示,并由 JVM 抛出。
- 异常由描述程序中错误的 Exception 类表示。