异常体系简介
异常就是java通过面向对象的思想将不正常情况封装成了对象,用异常类对其进行描述。
try catch finally 语句:
- try语句中若检测到异常(Throwable)会将相关的信息封装成异常对象,然后传递给catch,catch捕获到后对异常进行处理。
-
try中是一个独立的代码块,在其中定义的变量只在该代码块中有效,如果要在try以外继续使用,需要在try外进行声明。
- try中如果可能会捕获到多个异常,那么应该(建议)有对应个数的catch进行针对性处理。
- 一个try对应多个catch语句时,后面的catch子句中的参数类型只能是前面catch字句中参数类型的同级或父类,而不能是子类,也不能是同一个类型。
- 一个try对应多个catch语句时,若前面的catch子句中的参数类型和实际捕获到的异常类型一致,则只执行此catch语句,而不会再匹配或执行下面的catch字句。
- finally语句里通常用来关闭资源。比如:数据库资源,IO资源等。
-
finally语句中的代码只有一种情况不会被执行,就是在之前执行了System.exit(0)。
try {
throw new RuntimeException();
} catch (ArithmeticException e) {
e.printStackTrace();
} catch (RuntimeException e) {
System.out.println("==============只执行此catch语句,而不会再匹配或执行下面的catch字句============");
e.printStackTrace();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable th) {
th.printStackTrace();
} finally {
System.out.println("编译通过,但是因为之前执行了System.exit(0),所以执行不到");
}
System.out.println("编译通过,同样因为之前执行了System.exit(0),所以执行不到");
16
16
1
try {
2
throw new RuntimeException();
3
} catch (ArithmeticException e) {
4
e.printStackTrace();
5
} catch (RuntimeException e) {
6
System.out.println("==============只执行此catch语句,而不会再匹配或执行下面的catch字句============");
7
e.printStackTrace();
8
System.exit(0);
9
} catch (Exception e) {
10
e.printStackTrace();
11
} catch (Throwable th) {
12
th.printStackTrace();
13
} finally {
14
System.out.println("编译通过,但是因为之前执行了System.exit(0),所以执行不到");
15
}
16
System.out.println("编译通过,同样因为之前执行了System.exit(0),所以执行不到");
子类在覆盖父类方法时:
-
子类的方法只能抛出父类的方法抛出的异常或者该异常的子类,而不能抛出该异常的父类或其他类型的异常
-
如果父类的方法抛出多个异常,那么子类的该方法只能抛出父类该方法抛出的异常的子集
-
如果父类的方法没有抛出异常,那么子类覆盖父类的该方法时也不能抛,如果有异常只能使用 try catch 语句
class Fu {
protected void test() throws ArithmeticException, BufferOverflowException {
}
}
class Zi extends Fu {
@Override
protected void test() throws ArithmeticException {
}
}
1
class Fu {
2
protected void test() throws ArithmeticException, BufferOverflowException {
3
}
4
}
5
6
class Zi extends Fu {
7
8
protected void test() throws ArithmeticException {
9
}
10
}
throw 语句用于抛出异常对象,一条 throw 语句只可能抛出一个异常对象,且
throw
语句之后不能再有其他语句,因为 throw 语句后面的代码是执行不到的。
RuntimeException 以及其子类可以在函数中通过 throw 抛出而不用在函数上声明。
throw new RuntimeException();
System.out.println("编译失败");//编译失败,因为 throw 语句后面的代码是执行不到的
2
2
1
throw new RuntimeException();
2
System.out.println("编译失败");//编译失败,因为 throw 语句后面的代码是执行不到的
try {
throw new RuntimeException();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("编译通过"); //try catch 语句后面的语句是可以正常执行的
6
6
1
try {
2
throw new RuntimeException();
3
} catch (Exception e) {
4
e.printStackTrace();
5
}
6
System.out.println("编译通过"); //try catch 语句后面的语句是可以正常执行的
Throwable 官方文档
继承自:Object
实现的接口:Serializable
直接已知子类:Error, Exception
3
3
1
继承自:Object
2
实现的接口:Serializable
3
直接已知子类:Error, Exception
Throwable 类是 Java 语言中
所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java
throw 语句抛出。类似地,只有此类或其子类之一才可以是
catch 子句中的参数类型。
两个子类的实例,Error 和 Exception,通常用于指示发生了异常情况。通常,这些实例是
在异常情况的上下文中新近创建的,因此包含了相关的信息(比如堆栈跟踪数据)。
Throwable 包含了
其线程创建时线程执行堆栈的快照,它还包含了给出有关错误更多信息的消息字符串。最后,它还可以包含 cause(原因):另一个导致此 throwable 抛出的 throwable。此 cause 设施在 1.4 版本中首次出现。它也称为
异常链 设施,因为 cause 自身也会有 cause,依此类推,就形成了异常链,
每个异常都是由另一个异常引起的。
导致 throwable cause 的一个理由是,抛出它的类构建在低层抽象之中,而高层操作由于低层操作的失败而失败。
导致 throwable cause 的另一个
理由是,抛出它的方法必须符合通用接口,而通用接口不允许方法直接抛出 cause。
在版本 1.4 中还引入了 getStackTrace() 方法,它允许通过各种形式的 printStackTrace() 方法编程访问堆栈跟踪信息,这些信息以前只能以文本形式使用。此信息已经添加到该类的序列化表示形式,因此 getStackTrace 和 printStackTrace 将可在反序列化时获得的 throwable 上正确操作。
构造方法
-
Throwable(String message, Throwable cause) 构造一个带指定详细消息和 cause 的新 throwable。
- 注意,与 cause 相关的详细消息不是 自动合并到这个 throwable 的详细消息中的。调用 fillInStackTrace() 方法来初始化新创建的 throwable 中的堆栈跟踪数据。
- 参数:message - 详细消息。保存此消息,以便以后通过 getMessage() 方法获取它
-
参数:cause - 原因。保存此 cause,以便以后通过 getCause() 方法获取它。允许 null 值,指出 cause 是不存在的或是未知的。
public class Test {
public static void main(String[] args) {
Throwable throwable = new Throwable("你好", new Exception("一个cause"));
System.out.println(throwable.getMessage() + " " + throwable.getCause());//你好 java.lang.Exception: 一个cause
System.out.println("-----------------------------------------");
throwable.printStackTrace();
throwable.fillInStackTrace();
System.out.println("-----------------------------------------");
throwable.printStackTrace();
}
}
11
11
1
public class Test {
2
public static void main(String[] args) {
3
Throwable throwable = new Throwable("你好", new Exception("一个cause"));
4
System.out.println(throwable.getMessage() + " " + throwable.getCause());//你好 java.lang.Exception: 一个cause
5
System.out.println("-----------------------------------------");
6
throwable.printStackTrace();
7
throwable.fillInStackTrace();
8
System.out.println("-----------------------------------------");
9
throwable.printStackTrace();
10
}
11
}
你好 java.lang.Exception: 一个cause
-----------------------------------------
java.lang.Throwable: 你好
at Test.main(Test.java:3)
Caused by: java.lang.Exception: 一个cause
... 1 more
-----------------------------------------
java.lang.Throwable: 你好
at Test.main(Test.java:7)
Caused by: java.lang.Exception: 一个cause
at Test.main(Test.java:3)
11
11
1
你好 java.lang.Exception: 一个cause
2
-----------------------------------------
3
java.lang.Throwable: 你好
4
at Test.main(Test.java:3)
5
Caused by: java.lang.Exception: 一个cause
6
... 1 more
7
-----------------------------------------
8
java.lang.Throwable: 你好
9
at Test.main(Test.java:7)
10
Caused by: java.lang.Exception: 一个cause
11
at Test.main(Test.java:3)
- Throwable(String message) 构造带指定详细消息的新 throwable。Cause 尚未进行初始化,可在以后通过调用 initCause(java.lang.Throwable) 来初始化。
- Throwable(Throwable cause) 构造一个将 null 作为其详细消息的新 throwable。
-
Throwable() 构造一个将 null 作为其详细消息的新 throwable。
普通 get/set 方法
-
String getMessage() 返回此 throwable 的详细消息字符串。
-
String getLocalizedMessage() 创建此 throwable 的本地化描述。
- 子类可以重写此方法,以便生成特定于语言环境的消息。
- 对于不重写此方法的子类,默认实现返回与 getMessage() 相同的结果。
-
String toString() 返回此 throwable 的简短描述。
- 如果 getLocalizedMessage 返回 null,则只返回类名称。
- 格式【此对象的类的 name: (冒号和一个空格) 调用此对象 getLocalizedMessage() 方法的结果】,如【java.lang.Throwable: 异常信息】
-
Throwable getCause() 返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null。该 Cause 是导致抛出此 throwable 的throwable。
- Throwable initCause(Throwable cause) 将此 throwable 的 cause 初始化为指定值。
- 允许 null 值,指出 cause 是不存在的或是未知的。
- 此方法至多可以调用一次。
- 此方法通常从构造方法中调用,或者在创建 throwable 后立即调用。
- 如果此 throwable 通过 Throwable(Throwable) 或 Throwable(String,Throwable) 创建,此方法一次也不能调用。
堆栈跟踪相关 StackTrace
操作堆栈跟踪信息
-
Throwable fillInStackTrace() 在异常堆栈跟踪中填充。此方法在 Throwable 对象信息中记录有关当前线程堆栈帧的当前状态。
-
StackTraceElement[] getStackTrace() 提供编程访问由 printStackTrace() 输出的堆栈跟踪信息。
-
void setStackTrace(StackTraceElement[] stackTrace) 设置将由 getStackTrace() 返回,并由 printStackTrace() 和相关方法输出的堆栈跟踪元素。
打印堆栈跟踪信息
-
void printStackTrace() 将此 throwable 及其追踪输出至标准错误流System.err。
-
void printStackTrace(PrintStream s) 将此 throwable 及其追踪输出到指定的输出流。
- void printStackTrace(PrintWriter s) 将此 throwable 及其追踪输出到指定的PrintWriter。
注意,不必 重写任何 PrintStackTrace 方法,应通过调用 getCause 方法来确定 throwable 的 cause。
通过 printStackTrace 输出的堆栈跟踪信息的格式:
第一行包含此对象的 toString() 方法的结果,剩余行表示以前由方法
fillInStackTrace() 记录的数据。此信息的格式取决于实现,但以下示例是最常见的:
Exception in thread "main" java.lang.NullPointerException
at Test.mash(Test.java:11)
at Test.crunch(Test.java:7)
at Test.main(Test.java:3)
4
4
1
Exception in thread "main" java.lang.NullPointerException
2
at Test.mash(Test.java:11)
3
at Test.crunch(Test.java:7)
4
at Test.main(Test.java:3)
本示例通过运行以下程序生成:
public class Test {
public static void main(String[] args) {
crunch(null);
}
static void crunch(int[] a) {
mash(a);
}
static void mash(int[] b) {
System.out.println(b[0]);
}
}
13
13
1
public class Test {
2
public static void main(String[] args) {
3
crunch(null);
4
}
5
6
static void crunch(int[] a) {
7
mash(a);
8
}
9
10
static void mash(int[] b) {
11
System.out.println(b[0]);
12
}
13
}
对于带初始化非空 cause 的 throwable 的追踪,通常应该包括 cause 的追踪。此信息的格式取决于实现,但以下示例是最常见的:
HighLevelException: MidLevelException: LowLevelException
at Test.a(Test.java:14)
at Test.main(Test.java:4)
Caused by: MidLevelException: LowLevelException
at Test.c(Test.java:26)
at Test.b(Test.java:19)
at Test.a(Test.java:12)
... 1 more
Caused by: LowLevelException
at Test.e(Test.java:35)
at Test.d(Test.java:31)
at Test.c(Test.java:24)
... 3 more
13
13
1
HighLevelException: MidLevelException: LowLevelException
2
at Test.a(Test.java:14)
3
at Test.main(Test.java:4)
4
Caused by: MidLevelException: LowLevelException
5
at Test.c(Test.java:26)
6
at Test.b(Test.java:19)
7
at Test.a(Test.java:12)
8
... 1 more
9
Caused by: LowLevelException
10
at Test.e(Test.java:35)
11
at Test.d(Test.java:31)
12
at Test.c(Test.java:24)
13
... 3 more
注意,存在包含字符 "..." 的行。这些行指示此异常的椎栈跟踪的其余部分匹配来自异常(由 "enclosing" 异常引起)的堆栈跟踪底部的指定数量的帧。这种简便方法可以大大缩短通常情况下的输出长度,这里抛出了包装的异常,其方法与捕获“作为 cause 的异常”的方法相同。上述示例通过运行以下程序生成:
public class Test {
public static void main(String args[]) {
try {
a();
} catch (HighLevelException e) {
e.printStackTrace();
}
}
static void a() throws HighLevelException {
try {
b();
} catch (MidLevelException e) {
throw new HighLevelException(e);
}
}
static void b() throws MidLevelException {
c();
}
static void c() throws MidLevelException {
try {
d();
} catch (LowLevelException e) {
throw new MidLevelException(e);
}
}
static void d() throws LowLevelException {
e();
}
static void e() throws LowLevelException {
throw new LowLevelException();
}
}
37
37
1
public class Test {
2
public static void main(String args[]) {
3
try {
4
a();
5
} catch (HighLevelException e) {
6
e.printStackTrace();
7
}
8
}
9
10
static void a() throws HighLevelException {
11
try {
12
b();
13
} catch (MidLevelException e) {
14
throw new HighLevelException(e);
15
}
16
}
17
18
static void b() throws MidLevelException {
19
c();
20
}
21
22
static void c() throws MidLevelException {
23
try {
24
d();
25
} catch (LowLevelException e) {
26
throw new MidLevelException(e);
27
}
28
}
29
30
static void d() throws LowLevelException {
31
e();
32
}
33
34
static void e() throws LowLevelException {
35
throw new LowLevelException();
36
}
37
}
class HighLevelException extends Exception {
HighLevelException(Throwable cause) {
super(cause);
}
}
class MidLevelException extends Exception {
MidLevelException(Throwable cause) {
super(cause);
}
}
class LowLevelException extends Exception {
}
14
14
1
class HighLevelException extends Exception {
2
HighLevelException(Throwable cause) {
3
super(cause);
4
}
5
}
6
7
class MidLevelException extends Exception {
8
MidLevelException(Throwable cause) {
9
super(cause);
10
}
11
}
12
13
class LowLevelException extends Exception {
14
}
Exception 官方文档
Exception 类及其子类是 Throwable 的一种形式,它指出了
合理的应用程序想要捕获的条件。
直接已知子类:
AclNotFoundException, ActivationException, AlreadyBoundException, ApplicationException, AWTException, BackingStoreException, BadAttributeValueExpException, BadBinaryOpValueExpException, BadLocationException, BadStringOperationException, BrokenBarrierException, CertificateException, ClassNotFoundException, CloneNotSupportedException, DataFormatException, DatatypeConfigurationException, DestroyFailedException, ExecutionException, ExpandVetoException, FontFormatException, GeneralSecurityException, GSSException, IllegalAccessException, IllegalClassFormatException, InstantiationException, InterruptedException, IntrospectionException, InvalidApplicationException, InvalidMidiDataException, InvalidPreferencesFormatException, InvalidTargetObjectTypeException, InvocationTargetException, IOException, JAXBException, JMException, KeySelectorException, LastOwnerException, LineUnavailableException, MarshalException, MidiUnavailableException, MimeTypeParseException, MimeTypeParseException, NamingException, NoninvertibleTransformException, NoSuchFieldException, NoSuchMethodException, NotBoundException, NotOwnerException, ParseException, ParserConfigurationException, PrinterException, PrintException, PrivilegedActionException, PropertyVetoException, RefreshFailedException, RemarshalException, RuntimeException, SAXException, ScriptException, ServerNotActiveException, SOAPException, SQLException, TimeoutException, TooManyListenersException, TransformerException, TransformException, UnmodifiableClassException, UnsupportedAudioFileException, UnsupportedCallbackException, UnsupportedFlavorException, UnsupportedLookAndFeelException, URIReferenceException, URISyntaxException, UserException, XAException, XMLParseException, XMLSignatureException, XMLStreamException, XPathException
1
1
1
AclNotFoundException, ActivationException, AlreadyBoundException, ApplicationException, AWTException, BackingStoreException, BadAttributeValueExpException, BadBinaryOpValueExpException, BadLocationException, BadStringOperationException, BrokenBarrierException, CertificateException, ClassNotFoundException, CloneNotSupportedException, DataFormatException, DatatypeConfigurationException, DestroyFailedException, ExecutionException, ExpandVetoException, FontFormatException, GeneralSecurityException, GSSException, IllegalAccessException, IllegalClassFormatException, InstantiationException, InterruptedException, IntrospectionException, InvalidApplicationException, InvalidMidiDataException, InvalidPreferencesFormatException, InvalidTargetObjectTypeException, InvocationTargetException, IOException, JAXBException, JMException, KeySelectorException, LastOwnerException, LineUnavailableException, MarshalException, MidiUnavailableException, MimeTypeParseException, MimeTypeParseException, NamingException, NoninvertibleTransformException, NoSuchFieldException, NoSuchMethodException, NotBoundException, NotOwnerException, ParseException, ParserConfigurationException, PrinterException, PrintException, PrivilegedActionException, PropertyVetoException, RefreshFailedException, RemarshalException, RuntimeException, SAXException, ScriptException, ServerNotActiveException, SOAPException, SQLException, TimeoutException, TooManyListenersException, TransformerException, TransformException, UnmodifiableClassException, UnsupportedAudioFileException, UnsupportedCallbackException, UnsupportedFlavorException, UnsupportedLookAndFeelException, URIReferenceException, URISyntaxException, UserException, XAException, XMLParseException, XMLSignatureException, XMLStreamException, XPathException
RuntimeException 官方文档
RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。
可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明。
直接已知子类:
AnnotationTypeMismatchException
ArithmeticException
ArrayStoreException
BufferOverflowException
BufferUnderflowException
CannotRedoException
CannotUndoException
ClassCastException
CMMException
ConcurrentModificationException
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
46
46
1
AnnotationTypeMismatchException
2
ArithmeticException
3
ArrayStoreException
4
BufferOverflowException
5
BufferUnderflowException
6
CannotRedoException
7
CannotUndoException
8
ClassCastException
9
CMMException
10
ConcurrentModificationException
11
DOMException
12
EmptyStackException
13
EnumConstantNotPresentException
14
EventException
15
IllegalArgumentException
16
IllegalMonitorStateException
17
IllegalPathStateException
18
IllegalStateException
19
ImagingOpException
20
IncompleteAnnotationException
21
IndexOutOfBoundsException
22
JMRuntimeException
23
LSException
24
MalformedParameterizedTypeException
25
MirroredTypeException
26
MirroredTypesException
27
MissingResourceException
28
NegativeArraySizeException
29
NoSuchElementException
30
NoSuchMechanismException
31
NullPointerException
32
ProfileDataException
33
ProviderException
34
RasterFormatException
35
RejectedExecutionException
36
SecurityException
37
SystemException
38
TypeConstraintException
39
TypeNotPresentException
40
UndeclaredThrowableException
41
UnknownAnnotationValueException
42
UnknownElementException
43
UnknownTypeException
44
UnmodifiableSetException
45
UnsupportedOperationException
46
WebServiceException
Error 官方文档
Error 是 Throwable 的子类,用于指示合理的
应用程序不应该试图捕获的严重问题。大多数这样的错误都是异常条件。虽然 ThreadDeath 错误是一个“正规”的条件,但它也是 Error 的子类,因为大多数应用程序都不应该试图捕获它。
在执行该方法期间,无需在其 throws 子句中声明可能抛出但是未能捕获的 Error 的任何子类,因为这些错误可能是再也不会发生的异常条件。
常见的直接子类:
-
IOError:当发生严重的 I/O 错误时,抛出此错误。
- LinkageError:LinkageError 的子类指示一个类在一定程度上依赖于另一个类;但是,在编译前一个类之后,后一个类发生了不相容的改变。
- ClassCircularityError:当初始化类时检测到类的循环调用的时候,抛出该错误。
- ClassFormatError:当 Java 虚拟机试图读取类文件并确定该文件存在格式错误或无法解释为类文件时,抛出该错误。
- ExceptionInInitializerError:静态初始化程序中发生意外异常的信号。抛出此错误表明在计算静态初始值或静态变量的初始值期间发生异常。
- IncompatibleClassChangeError:在某些类定义中出现不兼容的类更改时抛出该异常。某些目前执行的方法所依赖的类定义已发生了变化。
- NoClassDefFoundError:当 Java 虚拟机或 ClassLoader 实例试图在类的定义中加载,但无法找到该类的定义时,抛出此异常。
- UnsatisfiedLinkError:当 Java 虚拟机无法找到声明为 native 的方法的适当本地语言定义时,抛出该错误。
- VerifyError:当“校验器”检测到一个类文件虽然格式正确,但包含着一些内部不一致性或安全性问题时,抛出该错误。
- ThreadDeath:调用 Thread 类中带有零参数的 stop 方法时(此方法已过时),受害线程将抛出一个 ThreadDeath 实例。仅当应用程序在被异步终止后必须清除时才应该捕获这个类的实例。
-
VirtualMachineError:当 Java 虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误。
- InternalError:该异常指示 Java 虚拟机中出现一些意外的内部错误。
- OutOfMemoryError:因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象,这时抛出该异常。
- *Error:当应用程序递归太深而发生堆栈溢出时,抛出该错误。
- UnknownError:当 Java 虚拟机中出现一个未知但严重的异常时,抛出该错误。
2018-6-8