Java异常体系详解之RuntimeException
一. RuntimeException
RuntimeException 同 IOException、SQLException一样,都是 Exception的一个子类。
RuntimeException通常指示程序在运行时出现了错误,需要立即停止程序的执行,通常是由程序员编写的代码错误引起的,如除以零、数组越界、空指针等。
在Java中,RuntimeException并不需要显式地捕获和处理,但是良好的编程习惯应该尽可能地避免抛出RuntimeException,以确保程序健壮性和可维护性。
1、ArithmeticException
ArithmeticException(数学运算异常)是Java中的一个运行时异常类,它继承自RuntimeException。
这种异常通常是由于程序员的错误或数据错误导致的。例如,如果一个程序试图除以零,那么JVM会抛出ArithmeticException异常。
ArithmeticException是一个非受检异常,意味着它不需要在方法声明或者在方法中进行捕获。
然而,为了使程序更加健壮,建议在可能引起ArithmeticException异常的地方进行相应的异常处理。例如,在进行除法运算之前,可以检查分母是否为0,从而避免抛出此异常。
异常例图:
2、ConcurrentModificationException
ConcurrentModificationException (并发修改异常)通常在使用迭代器(Iterator)遍历集合(Collection)时出现。
当一个线程正在遍历一个集合时,如果另一个线程同时修改了该集合的结构(增加、删除或者修改元素),那么就会抛出ConcurrentModificationException异常。
这是因为在Java中,集合的迭代器在遍历时会维护一个“期望修改次数”的计数器,如果该计数器与集合的实际修改次数不一致,就会抛出ConcurrentModificationException异常。
一般可以通过以下方式来避免出现此异常:
- 使用线程安全的集合类,如CopyOnWriteArrayList、ConcurrentHashMap等;
- 在遍历集合时,使用Iterator的remove方法来删除元素,而不是使用集合本身的删除方法;
- 在多线程环境下,使用同步机制来避免多个线程同时修改集合的情况。
异常例图:
3、ClassCastException
ClassCastException(类转换异常)是Java中的一个运行时异常,表示在进行对象类型转换时 发生了错误。当程序尝试将一个对象强制转换为另一种不兼容的类型 时,就可能会抛出该异常。
ClassCastException通常发生在以下情况下:
- 试图将一个对象转换为其子类,但该对象实际上不是该子类的实例;
- 试图将一个对象转换为其超类,但该对象实际上不是该超类的实例;
- 试图将一个对象转换为一个不相关的类,即这两个类之间没有继承关系或实现关系。
异常举例:
Object obj = "hello";
Integer i = (Integer) obj;
异常分析:
此处试图将一个字符串对象转换为Integer类型。但由于这两种类型不兼容,因此在运行时会抛出ClassCastException。
所以要避免ClassCastException,应该在进行类型转换之前检查对象的类型。可以使用instanceof关键字来检查对象是否为特定类型的实例,或者使用try-catch块来处理可能出现的ClassCastException异常。
4、ClassNotFoundException
ClassNotFoundException( 类找不到异常)异常类表示在尝试加载类时找不到该类。
ClassNotFoundException通常发生在以下情况下:
- 尝试加载不存在的类;
- 类路径中缺少所需的类文件;
- 类文件已经被删除或移动。
异常举例:
Class.forName("com.xiaoshan.MyClass");
异常分析:
此处尝试通过反射方式加载一个名为"com.xiaoshan.MyClass"的类。此时如果该类不存在,则会抛出ClassNotFoundException异常。
要避免ClassNotFoundException,应该确保所需的类存在,并且已经正确地配置了类路径。
可以使用Class.forName()方法在运行时加载类,也可以使用import关键字在编译时引入类。如果捕获到ClassNotFoundException异常,应该根据具体情况采取相应的处理措施,例如打印错误信息或者提供备选方案。
5、IllegalArgumentException
IllegalArgumentException(非法参数异常)异常类用于指示传递给方法的参数不合法或不正确。当一个方法接收到一个参数,但是这个参数不符合预期的类型、范围或格式 时,就会抛出IllegalArgumentException异常。
例如,当一个方法接收一个数字类型的参数,但是传递的参数是一个字符串时,就会抛出IllegalArgumentException异常;当一个方法接收一个数组类型的参数,但是传递的参数为null时,也会抛出IllegalArgumentException异常。
在处理IllegalArgumentException异常时,常见的做法是在方法中添加参数检查,以确保方法接收到的参数符合预期的类型、范围或格式。如果发现参数不正确,就可以抛出IllegalArgumentException异常并提供有用的错误消息,以便调用方可以了解参数的问题并进行相应的修正。
异常例图:
6、IndexOutOfBoundsException
IndexOutOfBoundsException(索引越界异常)异常类,通常在访问数组、字符串等类型的数据时出现,表示访问的索引超出了数据的范围。具体来说,当尝试访问一个不存在的数组元素或是字符串中不存在的字符时,就会抛出这个异常。
IndexOutOfBoundsException的两个子类,一个是ArrayIndexOutOfBoundsException,表示访问数组或集合相关的数据类型时发生的索引越界;一个是StringIndexOutOfBoundsException,表示访问字符串数据类型时发生的索引越界。
IndexOutOfBoundsException继承自RuntimeException,因此可以不用显式地捕获或声明。当程序运行时出现这个异常,会导致程序终止并抛出一个错误信息,通常包含错误的位置、原因和调用堆栈等信息。
异常例图:
7、MissingResourceException
MissingResourceException(资源缺失异常)异常类,表示找不到特定资源的异常。通常在尝试读取某个资源文件(如.properties文件)时,如果该文件不存在或者无法访问,就会抛出MissingResourceException。
MissingResourceException一般包含两个重要信息:资源文件的路径和资源文件的名称。它通常会在以下情况下抛出:
- 资源文件不存在或者无法访问;
- 资源文件存在,但是无法读取;
- 资源文件中缺少某些必要的键值对。
当程序抛出MissingResourceException时,可以通过捕获异常并处理,或者提醒用户检查资源文件是否存在或者是否有访问权限,以及是否包含了必要的键值对等方式来解决问题。
异常例图:
8、NoSuchElementException
NoSuchElementException( 元素缺失异常)异常类,表示在请求元素时,集合或迭代器中没有更多元素可用,即“没有这样的元素”。
当尝试从一个空的集合或迭代器中获取下一个元素时,就会抛出NoSuchElementException异常。这通常发生在使用迭代器遍历集合时,迭代器已经到达了集合的末尾,但仍然尝试获取下一个元素。
该异常通常是由于编码错误或逻辑错误导致的。为了避免NoSuchElementException异常,应该在调用next()方法之前,先调用 hasNext()方法检查集合是否还有更多的元素可用。
异常例图:
9、NullPointerException
NullPointerException(空指针异常)异常通常是指,出现在代码试图访问一个空对象时,试图调用一个空对象的方法或属性时的一种异常。
例如,如果一个对象引用为null,而代码试图调用该对象的方法或属性,则会抛出NullPointerException。这通常是由于未正确初始化对象引用或者未正确处理对象引用为null的情况 导致的。
NullPointerException可以被捕获并处理,但通常应该避免在代码中出现该异常。在编写代码时,应该检查对象引用是否为null,以确保不会发生NullPointerException异常。
异常例图: