通常来讲,Java中的异常会被分为三种:
- Error: 这种异常被设计成不被捕获,因为这种异常产生于JVM自身。
- Runtime Exception: 运行时异常往往与环境有关,编译时无法检查,并且可能发生的情况太广泛,所以系统会去处理,程序不需要捕获。
- 普通异常: 常见的异常大多属于此类。
这里的Java异常指直接继承java.lang.Throwable的异常类,他们的结构如下图:
- java.lang.Throwable
- java.lang.Error
- java.lang.Exception
- java.lang.RuntimeException
java.lang.Throwable
java.lang.Throwable是Java中所有可以错误和异常的父类。这里设计成父类而不是接口,我想部分原因可能是在Java诞生的早期,使用类继承结构更为流行。但更重要的原因应该是由于Exception不适于设计为接口。接口重视的是实现方法,规则的描述,而Exception重视的是里面含有的信息以及类名等信息。
Throwable的子类一般含有两个构造函数:空参数的构造函数和带异常信息String参数的构造函数。如果此类继承自其它Exception类,又会多两个构造函数:含Throwable参数的构造函数和含Throwable,描述信息String两个参数的构造函数。
java.lang.Error
java.lang.Error发生在应用程序不应该试图捕获的情况。Java程序不需要去throw或catch此类及其子类,因为这种异常不应该由应用程序处理,并且通常属于abnormal的情况。
java.lang.Exception
java.lang.Exception是指Java程序应该捕获的异常。其中,java.lang.RuntimeException是其中一个特别的子类。
java.lang.RuntimeException
Java程序应该捕获,却可以不去捕获的一个异常。在大多数情况下,都不会去捕获他,一个重要原因是这种异常可能发生的情况太普遍,几乎每行代码都会有RuntimeException的风险,因此反而无需去捕获了。JDK文档中的原话是:“
A method is not required to declare in its
throws
clause any subclasses of
RuntimeException
that might be thrown during the execution of the method but not caught.”
java.lang.RuntimeException的直接子类有这些:
- AnnotationTypeMismatchException
- ArithmeticException
- ArrayStoreException
- BufferOverflowException
- BufferUnderflowException
- CannotRedoException
- CannotUndoException
- ClassCastException
- CMMException
- ConcurrentModificationException
- DataBindingException
- DOMException
- EmptyStackException
- EnumConstantNotPresentException
- EventException
- IllegalArgumentException
- IllegalMonitorStateException
- IllegalPathStateException
- IllegalStateException
- ImagingOpException
- IncompleteAnnotationException
- IndexOutOfBoundsException
- JMRuntimeException
- LSException
- MalformedParameterizedTypeException
- MirroredTypeException
- MirroredTypesException
- MissingResourceException
- NegativeArraySizeException
- NoSuchElementException
- NoSuchMechanismException
- NullPointerException
- ProfileDataException
- ProviderException
- RasterFormatException
- RejectedExecutionException
- SecurityException
- SystemException
- TypeConstraintException
- TypeNotPresentException
- UndeclaredThrowableException
- UnknownAnnotationValueException
- UnknownElementException
- UnknownTypeException
- UnmodifiableSetException
- UnsupportedOperationException
- WebServiceException
类设计时使用Exception的几个最佳实践(读Effective Java有感)
在Effective Java的Item 58中,Java Exception被分为三类:Error,checked exception和runtime exception。在设计类时,这三种Exception这样使用为佳:
- Error:用于JVM相关的错误,例如resource deficiences,invariant failures以及其他使JVM无法正常运行的异常。
- Runtime Exception:用于编程错误,JDK自带的很多就是用于编程错误
- Checked Exception:用于可以恢复的异常。
由于Error通常用于JVM相关的错误,因此其他的unchecked exception都应该继承自Runtime Exception