Java教程 - Java异常类型
下图显示了Java异常类型层次结构:
Throwable | | +---Exception. | | | | | +--- RuntimeException | +---Error
异常及其子类用于用户程序应捕获的异常条件。您可以子类化Exception以创建自己的自定义异常类型。
错误定义在正常情况下不期望捕获的异常。 Java运行时系统使用错误以指示运行时环境中的错误。 堆栈溢出是这种错误的一个例子。
未捕获异常
这个小程序包括一个有意造成除以零误差的表达式:
public class Main { public static void main(String args[]) { int d = 0; int a = 42 / d; } }
以下是执行此示例时生成的异常:
例子
这里是另一个版本的前面的程序,引入相同的错误,但在一个方法与main()分开:
public class Main { static void subroutine() { int d = 0; int a = 10 / d; } public static void main(String args[]) { subroutine(); } }
从默认异常处理程序生成的堆栈跟踪显示如何显示整个调用堆栈:
例2
您可以在println()语句中显示异常描述消息。
例如,catch块可以这样写:
import java.util.Random; public class Main { public static void main(String args[]) { int a = 0, b = 0, c = 0; Random r = new Random(); for (int i = 0; i < 32000; i++) { try { b = r.nextInt(); c = r.nextInt(); a = 12345 / (b / c); } catch (ArithmeticException e) { System.out.println("Exception: " + e); a = 0; // set a to zero and continue } System.out.println("a: " + a); } } }
上面的代码生成以下结果。
什么是Java的内置异常
子类化RuntimeException的异常不需要包含在任何方法的throws列表中。这些被称为未检查异常。
java.lang中定义的未检查异常在下表中列出。
异常 | 含义 |
---|---|
ArithmeticException | 算术错误,如除以零。 |
ArrayIndexOutOfBoundsException | 数组索引超出边界。 |
ArrayStoreException | 分配给不兼容类型的数组元素。 |
ClassCastException | 投射无效。 |
EnumConstantNotPresentException | 尝试使用未定义的枚举值。 |
IllegalArgumentException | 用于调用方法的非法参数。 |
IllegalMonitorStateException | 非法监视器操作,例如等待解锁的线程。 |
IllegalStateException | 环境或应用程序状态不正确。 |
IllegalThreadStateException | 请求的操作与当前线程状态不兼容。 |
IndexOutOfBoundsException | 一些类型的索引是超出界限的。 |
NegativeArraySizeException | 使用负尺寸创建的数组。 |
NullPointerException | 无效引用的使用无效。 |
NumberFormatException | 字符串到数字格式的转换无效。 |
SecurityException | 试图违反安全。 |
StringIndexOutOfBounds | 尝试在字符串的边界之外建立索引。 |
TypeNotPresentException | 未找到类型。 |
UnsupportedOperationException | 遇到不支持的操作。 |
检查的异常在下表中列出。
异常 | 含义 |
---|---|
ClassNotFoundException | 找不到类。 |
CloneNotSupportedException | 尝试克隆不实现Cloneable接口的对象。 |
IllegalAccessException | 对类的访问被拒绝。 |
InstantiationException | 尝试创建抽象类或接口的对象。 |
InterruptedException | 一个线程已被另一个线程中断。 |
NoSuchFieldException | 请求的字段不存在。 |
NoSuchMethodException | 请求的方法不存在。 |
Java自定义异常类
您可以通过定义 Exception
的子类来创建自己的异常类。
异常
类没有定义自己的任何方法。它继承由 Throwable
提供的方法。
以下程序创建自定义异常类型。
class MyException extends Exception { private int detail; MyException(int a) { detail = a; } public String toString() { return "MyException[" + detail + "]"; } } public class Main { static void compute(int a) throws MyException { System.out.println("Called compute(" + a + ")"); if (a > 10) throw new MyException(a); System.out.println("Normal exit"); } public static void main(String args[]) { try { compute(1); compute(20); } catch (MyException e) { System.out.println("Caught " + e); } } }
上面的代码生成以下结果。
Java链接异常
链接异常允许您将另一个异常与异常相关联。第二个异常描述了第一个异常的原因。
为了允许链接异常,两个构造函数和两个方法被添加到 Throwable
。
Throwable(Throwable causeExc) Throwable(String msg, Throwable causeExc)
这里是一个例子,说明处理链接异常的机制:
public class Main { static void demoproc() { NullPointerException e = new NullPointerException("top layer"); e.initCause(new ArithmeticException("cause")); throw e; } public static void main(String args[]) { try { demoproc(); } catch (NullPointerException e) { System.out.println("Caught: " + e); System.out.println("Original cause: " + e.getCause()); } } }
上面的代码生成以下结果。