Java 在标准包 java.lang
中定义了多个异常类。
这些异常中最通用的是 RuntimeException
标准类型的子类。因为 java.lang
包在所有 Java 程序中都是隐式导入的,所以大多数从 RuntimeException
派生的异常都是自动可用的。
Java 内置异常的类型
Java 内置异常分为两类:已检查异常(Checked Exceptions)和未检查异常(Unchecked Exceptions)。
-
已检查异常:这类异常要求程序员在编写代码时进行处理,可以通过
try-catch
块来处理。这些异常在编译时就会被检查。
-
未检查异常:这类异常不需要程序员处理。这些异常是在运行时抛出的。一些常见的未检查异常包括
NullPointerException
, ArrayIndexOutOfBoundsException
, ArithmeticException
等。
Java 常见内置异常
Java 定义了许多其他类型的异常,这些异常与其各种类库有关。以下是 Java 中派生的未检查异常和已检查异常的列表:
未检查异常
序号 |
异常 |
描述 |
1 |
ArithmeticException |
数学运算错误,如除以零。 |
2 |
ArrayIndexOutOfBoundsException |
数组索引超出范围。 |
3 |
ArrayStoreException |
向数组元素赋值时不兼容的类型。 |
4 |
ClassCastException |
非法类型转换。 |
5 |
IllegalArgumentException |
使用非法参数调用方法。 |
6 |
IllegalMonitorStateException |
非法监视器操作,例如在未锁定的线程上调用等待。 |
7 |
IllegalStateException |
环境或应用程序处于不正确的状态。 |
8 |
IllegalThreadStateException |
请求的操作与当前线程状态不兼容。 |
9 |
IndexOutOfBoundsException |
某种类型的索引超出范围。 |
10 |
NegativeArraySizeException |
创建了一个负大小的数组。 |
11 |
NullPointerException |
非法使用空引用。 |
12 |
NumberFormatException |
字符串到数值格式的非法转换。 |
13 |
SecurityException |
尝试违反安全性。 |
14 |
StringIndexOutOfBoundsException |
尝试索引字符串之外的位置。 |
15 |
UnsupportedOperationException |
遇到了不支持的操作。 |
已检查异常
-
ClassNotFoundException
类未找到。
-
CloneNotSupportedException
尝试克隆未实现 Cloneable
接口的对象。
-
IllegalAccessException
访问类被拒绝。
-
InstantiationException
尝试创建抽象类或接口的对象。
-
InterruptedException
一个线程被另一个线程中断。
-
NoSuchFieldException
请求的字段不存在。
-
NoSuchMethodException
请求的方法不存在。
Java 内置异常示例
示例 1:无 try-catch
的算术异常演示
在这个例子中,我们通过除以零来创建一个错误。在这种情况下,一个未检查的异常将会被抛出。由于是未检查的,编译器不会报错并且程序会成功编译。一旦程序运行,异常将会被抛出,JVM 将会拦截异常并终止程序,在打印最后一条语句之前。
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
int b = 0;
int c = 1/b;
System.out.println("c :" + c);
}
}
输出:
主线程异常:java.lang.ArithmeticException: / by zero
at com.tutorialspoint.ExcepTest.main(ExcepTest.java:8)
示例 2:带 try-catch
的算术异常演示
在这个例子中,我们正在处理一个未检查的异常。作为第一步,我们通过除以零来产生一个错误。在这种情况下,一个未检查的异常将会被抛出。我们通过 ArithmeticException
来处理它。一旦程序运行,异常将会被抛出,catch
块将会拦截异常并打印最后一条语句。
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
try {
int b = 0;
int c = 1/b;
System.out.println("c :" + c);
}
catch (ArithmeticException e) {
System.out.println("异常抛出:" + e);
}
System.out.println("已经离开异常处理块");
}
}
输出:
异常抛出:java.lang.ArithmeticException: / by zero
已经离开异常处理块
示例 3:展示 NoSuchMethodException
在这个例子中,我们展示了当一个方法抛出已检查异常时,必须在代码中处理这个异常,否则编译器会报错。每当一个方法抛出已检查异常,它要么必须处理这个异常,要么声明抛出异常的语句,就像我们为 getName()
方法所做的那样。当我们尝试运行该方法时,JVM 抱怨编译问题,如下面的输出所示:
package com.tutorialspoint;
public class ExcepTest {
public static void main(String args[]) {
ExcepTest excepTest = new ExcepTest();
excepTest.getName();
}
private String getName() throws NoSuchMethodException {
throw new NoSuchMethodException();
}
}
输出:
主线程异常:java.lang.Error: 未解决的编译问题:
未处理的异常类型 NoSuchMethodException
at com.tutorialspoint.ExcepTest.main(ExcepTest.java:7)