阅读(1468) (6)

鸿蒙OS Throwable

2022-04-28 16:03:30 更新

Throwable

java.lang.Object

|---java.lang.Throwable

public class Throwable
extends Object
implements Serializable

Throwable 类是 Java 语言中所有错误和异常的超类。只有作为此类(或其子类之一)实例的对象才会被 Java 虚拟机抛出,或者可以被 Java throw 语句抛出。同样,只有此类或其子类之一可以是 catch 子句中的参数类型。出于对异常的编译时检查的目的,Throwable 和任何不是 RuntimeException 或 Error 的子类的 Throwable 子类都被视为已检查异常。

两个子类的实例,错误和异常,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中新创建的,以便包含相关信息(例如堆栈跟踪数据)。

throwable 包含其线程在创建时的执行堆栈的快照。它还可以包含提供有关错误的更多信息的消息字符串。随着时间的推移,一个 throwable 可以 Throwable#addSuppressed 其他 throwable 被传播。最后,throwable 还可以包含一个原因:另一个 throwable 导致该 throwable 被构造。这种因果信息的记录被称为链式异常设施,因为原因本身可以有一个原因,依此类推,导致异常“链”,每个异常都由另一个引起。

throwable 可能有原因的一个原因是抛出它的类是构建在较低层抽象之上的,并且由于较低层中的失败而导致上层上的操作失败。让下层抛出的 throwable 向外传播是不好的设计,因为它通常与上层提供的抽象无关。此外,这样做会将上层的 API 与其实现的细节联系起来,假设下层的异常是已检查异常。抛出“包装异常”(即包含原因的异常)允许上层将失败的细节传达给其调用者,而不会产生这些缺点中的任何一个。它保留了更改上层实现的灵活性,而无需更改其 API(特别是其方法引发的异常集)。

throwable 可能有原因的第二个原因是,抛出它的方法必须符合不允许该方法直接抛出原因的通用接口。例如,假设一个持久化集合符合 Collection 接口,并且它的持久性是在 java.io 上实现的。假设 add 方法的内部可以抛出一个 IOException。该实现可以将 IOException 的详细信息传达给其调用者,同时通过将 IOException 包装在适当的未经检查的异常中来符合 Collection 接口。 (持久化集合的规范应该表明它能够抛出这样的异常。)

原因可以通过两种方式与 throwable 相关联:通过将原因作为参数的构造函数,或通过 initCause(java.lang.Throwable) 方法。希望允许原因与它们关联的新 throwable 类应提供采用原因的构造函数,并将(可能间接)委托给采用原因的 Throwable 构造函数之一。因为 initCause 方法是公共的,它允许一个原因与任何 throwable 相关联,甚至是一个“legacy throwable”,其实现早于将异常链接机制添加到 Throwable。

按照惯例,Throwable 类及其子类有两个构造函数,一个不带参数,另一个带可用于生成详细消息的 String 参数。此外,那些可能有相关原因的子类应该有另外两个构造函数,一个采用 Throwable(原因),另一个采用 String(详细消息)和 Throwable(原因)。

构造函数摘要

修饰符 构造函数 描述
Throwable() 构造一个以 null 作为其详细消息的新 throwable。
Throwable(String message) 使用指定的详细消息构造一个新的 throwable。
Throwable(String message, Throwable cause) 使用指定的详细消息和原因构造一个新的 throwable。
protected Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) 使用指定的详细消息、原因、启用或禁用抑制以及启用或禁用可写堆栈跟踪构造一个新的 throwable。
Throwable(Throwable cause) 使用指定的原因和 (cause==null ? null : cause.toString()) 的详细消息构造一个新的 throwable(通常包含原因的类和详细消息)。

方法总结

修饰符和类型 方法 描述
void addSuppressed(Throwable exception) 将指定的异常附加到为传递此异常而被抑制的异常。
Throwable fillInStackTrace() 填写执行堆栈跟踪。
Throwable getCause() 如果原因不存在或未知,则返回此 throwable 的原因或 null。
String getLocalizedMessage() 创建此 throwable 的本地化描述。
String getMessage() 返回此 throwable 的详细消息字符串。
StackTraceElement[] getStackTrace() 提供对 printStackTrace() 打印的堆栈跟踪信息的编程访问。
Throwable[] getSuppressed() 返回一个数组,其中包含通常由 try-with-resources 语句抑制的所有异常,以传递此异常。
Throwable initCause(Throwable cause) 将此 throwable 的原因初始化为指定值。
void printStackTrace() 将此 throwable 及其回溯打印到标准错误流。
void printStackTrace(PrintStream s) 将此 throwable 及其回溯打印到指定的打印流。
void printStackTrace(PrintWriter s) 将此 throwable 及其回溯打印到指定的打印编写器。
void setStackTrace(StackTraceElement[] stackTrace) 设置将由 getStackTrace() 返回并由 printStackTrace() 和相关方法打印的堆栈跟踪元素。
String toString() 返回此 throwable 的简短描述。
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

构造函数详细信息

Throwable

public Throwable()

构造一个以 null 作为其详细消息的新 throwable。 原因未初始化,随后可能通过调用 initCause(java.lang.Throwable) 进行初始化。

调用 fillInStackTrace() 方法来初始化新创建的 throwable 中的堆栈跟踪数据。

Throwable

public Throwable(String message)

使用指定的详细消息构造一个新的 throwable。 原因未初始化,随后可能通过调用 initCause(java.lang.Throwable) 进行初始化。

调用 fillInStackTrace() 方法来初始化新创建的 throwable 中的堆栈跟踪数据。

参数:

参数名称 参数描述
message 详细信息。 详细消息被保存以供以后通过 getMessage() 方法检索。

Throwable

public Throwable(String message, Throwable cause)

使用指定的详细消息和原因构造一个新的 throwable。

请注意,与原因关联的详细消息不会自动合并到此 throwable 的详细消息中。

调用 fillInStackTrace() 方法来初始化新创建的 throwable 中的堆栈跟踪数据。

参数:

参数名称 参数描述
message 详细消息(保存以供以后通过 getMessage() 方法检索)。
cause 原因(由 getCause() 方法保存以供以后检索)。 (允许使用空值,表示原因不存在或未知。)

Throwable

public Throwable(Throwable cause)

使用指定的原因和 (cause==null ? null : cause.toString()) 的详细消息构造一个新的 throwable(通常包含原因的类和详细消息)。 此构造函数对于仅是其他 throwable 的包装器(例如 PrivilegedActionException)的 throwable 很有用。

调用 fillInStackTrace() 方法来初始化新创建的 throwable 中的堆栈跟踪数据。

参数:

参数名称 参数描述
cause 原因(由 getCause() 方法保存以供以后检索)。 (允许使用空值,表示原因不存在或未知。)

Throwable

protected Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)

使用指定的详细消息、原因、启用或禁用抑制以及启用或禁用可写堆栈跟踪构造一个新的 throwable。如果禁用了抑制,则此对象的 getSuppressed() 将返回一个长度为零的数组,并且调用 addSuppressed(java.lang.Throwable) 否则会将异常附加到抑制列表将无效。如果可写堆栈跟踪为 false,则此构造函数将不会调用 fillInStackTrace(),会将 null 写入 stackTrace 字段,随后对 fillInStackTrace 和 [setStackTrace(java.lang.StackTraceElement]) 的调用将不会设置堆栈跟踪。如果可写堆栈跟踪为假,getStackTrace() 将返回一个零长度数组。

请注意,Throwable 的其他构造函数将抑制视为已启用,并将堆栈跟踪视为可写。 Throwable 的子类应记录禁用抑制的任何条件以及堆栈跟踪不可写的条件。只有在存在特殊要求的特殊情况下才应禁用抑制,例如虚拟机在内存不足的情况下重用异常对象。重复捕获和重新抛出给定异常对象的情况,例如实现两个子系统之间的控制流,是不可变可抛出对象适用的另一种情况。

参数:

参数名称 参数描述
message 详细信息。
cause 原因。 (允许使用空值,表示原因不存在或未知。)
enableSuppression 是否启用或禁用抑制
writableStackTrace 堆栈跟踪是否应该是可写的

方法详情

getMessage

public String getMessage()

返回此 throwable 的详细消息字符串。

返回:

此 Throwable 实例的详细消息字符串(可能为 null)。

getLocalizedMessage

public String getLocalizedMessage()

创建此 throwable 的本地化描述。 子类可以覆盖此方法以生成特定于语言环境的消息。 对于不覆盖此方法的子类,默认实现返回与 getMessage() 相同的结果。

返回:

此 throwable 的本地化描述。

getCause

public Throwable getCause()

如果原因不存在或未知,则返回此 throwable 的原因或 null。 (原因是导致这个 throwable 被抛出的 throwable。)

此实现返回通过需要 Throwable 的构造函数之一提供的原因,或者在使用 initCause(java.lang.Throwable) 方法创建之后设置的原因。 虽然通常不需要重写此方法,但子类可以重写它以返回通过其他方式设置的原因。 这适用于早于将链式异常添加到 Throwable 的“传统链式 throwable”。 请注意,没有必要重写任何 PrintStackTrace 方法,所有这些方法都会调用 getCause 方法来确定 throwable 的原因。

返回:

如果原因不存在或未知,则返回此 throwable 的原因或 null。

initCause

public Throwable initCause(Throwable cause)

将此 throwable 的原因初始化为指定值。 (原因是导致这个 throwable 被抛出的 throwable。)

该方法最多可以调用一次。 它通常在构造函数中调用,或者在创建 throwable 之后立即调用。 如果这个 throwable 是用 Throwable(java.lang.Throwable) 或 Throwable(java.lang.String,java.lang.Throwable) 创建的,这个方法甚至不能被调用一次。

在没有其他设置原因的支持的情况下在遗留可抛出类型上使用此方法的示例是:

 try {
     lowLevelOp();
 } catch (LowLevelException le) {
     throw (HighLevelException)
           new HighLevelException().initCause(le); // Legacy constructor
 }

 

参数:

参数名称 参数描述
cause 原因(由 getCause() 方法保存以供以后检索)。 (允许使用空值,表示原因不存在或未知。)

返回:

对此 Throwable 实例的引用。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果原因是可抛出的。 (一个 throwable 不能是它自己的原因。)
IllegalStateException 如果这个 throwable 是用 Throwable(java.lang.Throwable) 或 Throwable(java.lang.String,java.lang.Throwable) 创建的,或者这个方法已经在这个 throwable 上调用过。

toString

public String toString()

返回此 throwable 的简短描述。 结果是以下内容的串联:

  • 这个对象的类的 Class#getName()
  • ":"(冒号和空格)
  • 调用此对象的 getLocalizedMessage() 方法的结果

如果 getLocalizedMessage 返回 null,则只返回类名。

覆盖:

类 Object 中的 toString

返回:

此 throwable 的字符串表示形式。

printStackTrace

public void printStackTrace()

将此 throwable 及其回溯打印到标准错误流。 此方法在错误输出流上打印此 Throwable 对象的堆栈跟踪,即字段 System.err 的值。 输出的第一行包含该对象的 toString() 方法的结果。 剩余的行表示先前由方法 fillInStackTrace() 记录的数据。 此信息的格式取决于实现,但以下示例可被视为典型示例:

 java.lang.NullPointerException
         at MyClass.mash(MyClass.java:9)
         at MyClass.crunch(MyClass.java:6)
         at MyClass.main(MyClass.java:3)

 

这个例子是通过运行程序产生的:

 class MyClass {
     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]);
     }
 }

 

具有已初始化的非空原因的 throwable 的回溯通常应包括原因的回溯。 此信息的格式取决于实现,但以下示例可被视为典型示例:

 HighLevelException: MidLevelException: LowLevelException
         at Junk.a(Junk.java:13)
         at Junk.main(Junk.java:4)
 Caused by: MidLevelException: LowLevelException
         at Junk.c(Junk.java:23)
         at Junk.b(Junk.java:17)
         at Junk.a(Junk.java:11)
         ... 1 more
 Caused by: LowLevelException
         at Junk.e(Junk.java:30)
         at Junk.d(Junk.java:27)
         at Junk.c(Junk.java:21)
         ... 3 more

 

请注意包含字符“...”的行的存在。 这些行表明此异常的堆栈跟踪的其余部分与此异常(“封闭”异常)导致的异常的堆栈跟踪底部的指定帧数相匹配。 这种速记可以大大减少输出的长度,在这种情况下,从与捕获“原因异常”相同的方法抛出包装异常的常见情况。 上面的例子是通过运行程序产生的:

 public class Junk {
     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();
     }
 }


 class HighLevelException extends Exception {
     HighLevelException(Throwable cause) { super(cause); }
 }


 class MidLevelException extends Exception {
     MidLevelException(Throwable cause)  { super(cause); }
 }


 class LowLevelException extends Exception {
 }

 

从版本 7 开始,平台支持抑制异常的概念(与 try-with-resources 语句一起使用)。 为了传递异常而被抑制的任何异常都将打印在堆栈跟踪下方。 此信息的格式取决于实现,但以下示例可被视为典型示例:

 Exception in thread "main" java.lang.Exception: Something happened
  at Foo.bar(Foo.java:10)
  at Foo.main(Foo.java:5)
  Suppressed: Resource$CloseFailException: Resource ID = 0
          at Resource.close(Resource.java:26)
          at Foo.bar(Foo.java:9)
          ... 1 more

 

请注意,“... n more”符号用于抑制异常,就像它用于原因一样。 与原因不同,被抑制的异常在其“包含异常”之外缩进。

一个异常可以有一个原因和一个或多个被抑制的异常:

 Exception in thread "main" java.lang.Exception: Main block
  at Foo3.main(Foo3.java:7)
  Suppressed: Resource$CloseFailException: Resource ID = 2
          at Resource.close(Resource.java:26)
          at Foo3.main(Foo3.java:5)
  Suppressed: Resource$CloseFailException: Resource ID = 1
          at Resource.close(Resource.java:26)
          at Foo3.main(Foo3.java:5)
 Caused by: java.lang.Exception: I did it
  at Foo3.main(Foo3.java:8)

 

同样,抑制的异常可能有原因:

 Exception in thread "main" java.lang.Exception: Main block
  at Foo4.main(Foo4.java:6)
  Suppressed: Resource2$CloseFailException: Resource ID = 1
          at Resource2.close(Resource2.java:20)
          at Foo4.main(Foo4.java:5)
  Caused by: java.lang.Exception: Rats, you caught me
          at Resource2$CloseFailException.<init>(Resource2.java:45)
          ... 2 more

 

printStackTrace

public void printStackTrace(PrintStream s)

将此 throwable 及其回溯打印到指定的打印流。

参数:

参数名称 参数描述
s 用于输出的 PrintStream

printStackTrace

public void printStackTrace(PrintWriter s)

将此 throwable 及其回溯打印到指定的打印编写器。

参数:

参数名称 参数描述
s PrintWriter 用于输出

fillInStackTrace

public Throwable fillInStackTrace()

填写执行堆栈跟踪。 此方法在此 Throwable 对象中记录有关当前线程的堆栈帧的当前状态的信息。

如果这个 Throwable Throwable#Throwable(String, Throwable, boolean, boolean) 的堆栈跟踪,调用这个方法是没有效果的。

返回:

对此 Throwable 实例的引用。

getStackTrace

public StackTraceElement[] getStackTrace()

提供对 printStackTrace() 打印的堆栈跟踪信息的编程访问。返回堆栈跟踪元素的数组,每个元素代表一个堆栈帧。数组的第零个元素(假设数组的长度不为零)表示堆栈的顶部,这是序列中的最后一个方法调用。通常,这是这个 throwable 被创建和抛出的点。数组的最后一个元素(假设数组的长度不为零)表示堆栈的底部,这是序列中的第一个方法调用。

在某些情况下,某些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,允许没有关于这个 throwable 的堆栈跟踪信息的虚拟机从这个方法返回一个长度为零的数组。一般来说,此方法返回的数组将为 printStackTrace 打印的每一帧包含一个元素。写入返回的数组不会影响以后对该方法的调用。

返回:

堆栈跟踪元素数组,表示与此 throwable 相关的堆栈跟踪。

setStackTrace

public void setStackTrace(StackTraceElement[] stackTrace)

设置将由 getStackTrace() 返回并由 printStackTrace() 和相关方法打印的堆栈跟踪元素。 此方法专为 RPC 框架和其他高级系统使用而设计,允许客户端覆盖默认堆栈跟踪,该堆栈跟踪要么在构造 throwable 时由 fillInStackTrace() 生成,要么在从序列化流中读取 throwable 时反序列化。

如果此 Throwable Throwable#Throwable(String, Throwable, boolean, boolean) 的堆栈跟踪,则调用此方法除了验证其参数外没有任何效果。

参数:

参数名称 参数描述
stackTrace 要与此 Throwable 关联的堆栈跟踪元素。 此调用复制指定的数组; 方法调用返回后对指定数组的更改不会影响此 Throwable 的堆栈跟踪。

Throws:

Throw名称 Throw描述
NullPointerException 如果 stackTrace 为 null 或 stackTrace 的任何元素为 null

addSuppressed

public final void addSuppressed(Throwable exception)

将指定的异常附加到为传递此异常而被抑制的异常。此方法是线程安全的,通常由 try-with-resources 语句调用(自动和隐式)。

除非通过构造函数禁用,否则会启用抑制行为。当抑制被禁用时,这个方法除了验证它的参数之外什么都不做。

请注意,当一个异常导致另一个异常时,通常会捕获第一个异常,然后抛出第二个异常作为响应。换句话说,这两个例外之间存在因果关系。相反,在某些情况下,可以在同级代码块中引发两个独立的异常,特别是在 try-with-resources 语句的 try 块和关闭资源的编译器生成的 finally 块中。在这些情况下,只能传播引发的异常之一。在 try-with-resources 语句中,当有两个这样的异常时,将传播源自 try 块的异常,并将 finally 块的异常添加到由 try 块的异常抑制的异常列表中。当一个异常展开堆栈时,它可以累积多个被抑制的异常。

一个异常可能已经抑制了异常,同时也由另一个异常引起。异常是否有原因在其创建时在语义上是已知的,这与异常是否会抑制其他异常不同,这通常仅在抛出异常后才确定。

请注意,程序员编写的代码也能够在存在多个同级异常且只能传播一个异常的情况下调用此方法。

参数:

参数名称 参数描述
exception 要添加到抑制异常列表中的异常

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果异常是可抛出的; throwable 无法抑制自身。
NullPointerException 如果异常为null

getSuppressed

public final Throwable[] getSuppressed()

返回一个数组,其中包含通常由 try-with-resources 语句抑制的所有异常,以传递此异常。 如果没有抑制异常或禁用抑制,则返回一个空数组。 此方法是线程安全的。 写入返回的数组不会影响以后对该方法的调用。

返回:

一个数组,其中包含为传递此异常而被抑制的所有异常。