Module java.base
Package java.lang

Class Throwable

java.lang.Object
java.lang.Throwable
所有已实现的接口:
Serializable
直接已知的子类:
Error, Exception

public class Throwable extends Object implements Serializable
Throwable类是Java语言中所有错误和异常的超类。只有属于这个类(或其子类之一)的对象才会被Java虚拟机抛出,或者可以被Java的throw语句抛出。同样,只有这个类或其子类可以作为catch子句中的参数类型。为了在编译时检查异常,Throwable和任何不是RuntimeExceptionError子类的Throwable子类都被视为已检查异常。

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

一个throwable包含创建时线程的执行堆栈的快照。它还可以包含一个消息字符串,提供有关错误的更多信息。随着时间的推移,throwable可以suppress其他throwable的传播。最后,throwable还可以包含一个cause:导致此throwable被构造的另一个throwable。记录这种因果信息被称为chained exception机制,因为原因本身可能有一个原因,依此类推,导致一系列异常,每个异常都由另一个异常引起。

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

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

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

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

参见Java语言规范:
11.2 编译时异常检查
自版本:
1.0
另请参阅:
  • Constructor Details

    • Throwable

      public Throwable()
      构造一个新的throwable,其详细消息为null。原因未初始化,可以随后通过调用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,带有指定的详细消息和原因。

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

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

      参数:
      message - 详细消息(将保存以便稍后通过getMessage()方法检索)。
      cause - 原因(将保存以便稍后通过getCause()方法检索)。(允许null值,表示原因不存在或未知。)
      自版本:
      1.4
    • Throwable

      public Throwable(Throwable cause)
      构造一个新的throwable,带有指定原因和详细消息为(cause==null ? null : cause.toString())(通常包含cause的类和详细消息)。

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

      参数:
      cause - 原因(将保存以便稍后通过getCause()方法检索)。(允许null值,表示原因不存在或未知。)
      自版本:
      1.4
    • Throwable

      protected Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
      构造一个带有指定详细消息、原因、抑制(启用或禁用)、可写堆栈跟踪(启用或禁用)的新可抛出对象。如果抑制被禁用,此对象的 getSuppressed() 方法将返回一个长度为零的数组,并且对于本对象的 addSuppressed(java.lang.Throwable) 的调用将不会将异常附加到抑制列表中。如果可写堆栈跟踪为 false,则此构造函数不会调用 fillInStackTrace(),将会向 stackTrace 字段写入一个 null,并且随后对 fillInStackTracesetStackTrace(StackTraceElement[]) 的调用将不会设置堆栈跟踪。如果可写堆栈跟踪为 false,则 getStackTrace() 将返回一个长度为零的数组。

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

      参数:
      message - 详细消息。
      cause - 原因。(允许值为 null,表示原因不存在或未知。)
      enableSuppression - 是否启用抑制
      writableStackTrace - 堆栈跟踪是否可写
      自版本:
      1.7
      参见:
  • Method Details

    • getMessage

      public String getMessage()
      返回此可抛出对象的详细消息字符串。
      返回:
      Throwable 实例的详细消息字符串(可能为 null)。
    • getLocalizedMessage

      public String getLocalizedMessage()
      创建此可抛出对象的本地化描述。子类可以重写此方法以生成特定于区域设置的消息。对于不重写此方法的子类, 默认实现将返回与 getMessage() 相同的结果。
      返回:
      此可抛出对象的本地化描述。
      自版本:
      1.1
    • getCause

      public Throwable getCause()
      返回此可抛出对象的原因,如果原因不存在或未知,则返回 null。(原因是导致此可抛出对象被抛出的可抛出对象。)

      此实现返回通过要求一个带有 Throwable 的构造函数提供的原因,或者在创建后使用 initCause(Throwable) 方法设置的原因。虽然通常不需要重写此方法,但子类可以重写它以返回通过其他方式设置的原因。这适用于“传统链式可抛出对象”,它在 Throwable 中添加链式异常之前就存在。请注意,不需要重写任何 PrintStackTrace 方法,所有这些方法都调用 getCause 方法来确定可抛出对象的原因。

      返回:
      此可抛出对象的原因,如果原因不存在或未知,则返回 null
      自版本:
      1.4
    • initCause

      public Throwable initCause(Throwable cause)
      将此可抛出对象的原因初始化为指定值。(原因是导致此可抛出对象被抛出的可抛出对象。)

      此方法最多只能调用一次。通常从构造函数内部调用,或者在创建可抛出对象后立即调用。如果此可抛出对象是使用 Throwable(Throwable)Throwable(String,Throwable) 创建的,则即使一次也不能调用此方法。

       try {
           lowLevelOp();
       } catch (LowLevelException le) {
           throw (HighLevelException)
                 new HighLevelException().initCause(le); // 传统构造函数
       }
       
      参数:
      cause - 原因(由 getCause() 方法保存以供以后检索)。(允许值为 null,表示原因不存在或未知。)
      返回:
      对此 Throwable 实例的引用。
      抛出:
      IllegalArgumentException - 如果 cause 是此可抛出对象。(可抛出对象不能是其自身的原因。)
      IllegalStateException - 如果此可抛出对象是使用 Throwable(Throwable)Throwable(String,Throwable) 创建的,或者此方法已在此可抛出对象上调用过一次。
      自版本:
      1.4
    • toString

      public String toString()
      返回此可抛出对象的简短描述。结果是以下内容的连接: 如果 getLocalizedMessage 返回 null,则只返回类名。
      覆盖:
      toString 在类 Object
      返回:
      此可抛出对象的字符串表示形式。
    • printStackTrace

      public void printStackTrace()
      打印此可抛出对象及其回溯到标准错误流。此方法在值为字段System.err的错误输出流上打印此Throwable对象的堆栈跟踪。输出的第一行包含此对象的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]);
           }
       }
       
      具有已初始化、非空原因的可抛出对象的回溯通常应包括原因的回溯。此信息的格式取决于实现,但以下示例可视为典型:
       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)
      将此可抛出对象及其回溯打印到指定的打印流。
      参数:
      s - 用于输出的PrintStream
    • printStackTrace

      public void printStackTrace(PrintWriter s)
      将此可抛出对象及其回溯打印到指定的打印写入器。
      参数:
      s - 用于输出的PrintWriter
      自版本:
      1.1
    • fillInStackTrace

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

      如果此Throwable的堆栈跟踪不可写,则调用此方法不会产生任何效果。

      返回:
      指向此Throwable实例的引用。
      另请参阅:
    • getStackTrace

      public StackTraceElement[] getStackTrace()
      提供对由printStackTrace()打印的堆栈跟踪信息的编程访问。返回一个堆栈跟踪元素数组,每个元素代表一个堆栈帧。数组的第零个元素(假设数组的长度非零)代表堆栈的顶部,即序列中的最后一个方法调用。通常,这是创建并抛出此可抛出对象的点。数组的最后一个元素(假设数组的长度非零)代表堆栈的底部,即序列中的第一个方法调用。

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

      返回:
      代表与此可抛出对象相关的堆栈跟踪的堆栈跟踪元素数组。
      自版本:
      1.4
    • setStackTrace

      public void setStackTrace(StackTraceElement[] stackTrace)
      设置将由getStackTrace()返回并由printStackTrace()和相关方法打印的堆栈跟踪元素。此方法旨在供RPC框架和其他高级系统使用,允许客户端覆盖在构造可抛出对象时由fillInStackTrace()生成的默认堆栈跟踪或在从序列化流读取可抛出对象时反序列化时生成的堆栈跟踪。

      如果此Throwable的堆栈跟踪不可写,则调用此方法除了验证其参数之外不会产生任何效果。

      参数:
      stackTrace - 与此Throwable关联的堆栈跟踪元素。此调用会复制指定的数组;在方法调用返回后对指定数组的更改不会影响此Throwable的堆栈跟踪。
      抛出:
      NullPointerException - 如果stackTracenullstackTrace的任何元素为null
      自版本:
      1.4
    • addSuppressed

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

      抑制行为已启用,除非通过构造函数禁用。当禁用抑制时,此方法除了验证其参数之外不会执行任何操作。

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

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

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

      参数:
      exception - 要添加到被抑制异常列表中的异常
      抛出:
      IllegalArgumentException - 如果exception就是这个throwable;一个throwable不能抑制自己。
      NullPointerException - 如果exceptionnull
      自从:
      1.7
    • getSuppressed

      public final Throwable[] getSuppressed()
      返回一个包含所有被抑制的异常的数组,通常是通过try-with-resources语句来传递这个异常。如果没有被抑制的异常或者抑制被禁用,则返回一个空数组。这个方法是线程安全的。对返回的数组的写操作不会影响对该方法的未来调用。
      返回:
      包含所有被抑制的异常以传递这个异常的数组。
      自从:
      1.7