【问题标题】:why isn't java.lang.Throwable an abstract class?为什么 java.lang.Throwable 不是抽象类?
【发布时间】:2010-11-30 13:43:33
【问题描述】:

可能重复:why-is-java-lang-throwable-a-class

嗨!我不明白为什么 Throwable 不是抽象类。我只看到一个用例:在日志系统中找出调用层次结构。但它可以是这个或其他类的一些静态方法。那么,为什么?)

谢谢。

更新

来自 java.util.logging.LogRecord

// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();

为什么它不能是 Throwable.getStackTrace(); 或 java.lang.Thread 中的

(new Exception()).getStackTrace();

这样我们就可以避开throw new Throwable();

更新2 来自 javadoc

Throwable 类是超类 中的所有错误和异常 Java 语言。

所以,作为一个超类,它应该是抽象的,恕我直言。根据这个定义,使用它来获取堆栈跟踪并不是很好的情况。

【问题讨论】:

  • 它在哪里“抛出新的 Throwable();” ?不确定您是否需要避免永远不会发生的事情。 ;)
  • @Peter Lawrey:有人可以写。 API 应该避免使用不当(不仅是我的恕我直言)。
  • @Stas,极不可能意外编译,因为它是检查异常。您必须处理它或将其添加到 throws 子句中。我认为这已经足够回避了。不相信存在需要其他解决方案的严重问题。
  • @Stas,我的IDE也有一个警告“Prohibited Exception throw”这个可以改成编译器错误级别。

标签: java class-design throwable


【解决方案1】:

我不明白为什么 Throwable 不是抽象类。

答案写得很清楚here

为什么不能 Throwable.getStackTrace();或如 java.lang.Thread

很简单,getStackTrace() 调用非静态的getOurStackTrace() 方法。如果getStackTrace() 是静态的,那么getOurStackTrace() 也应该如此。这不会发生,因为printStackTrace() 方法使用getOurStackTrace()。这在 JavaDoc 中有详细说明:

提供对 堆栈跟踪信息由 printStackTrace()。

java.lang.Throwable 的来源:

 public StackTraceElement[] getStackTrace() {
        return (StackTraceElement[]) getOurStackTrace().clone();
    }

另外,如果您阅读getOurStackTrace() 方法的代码,您会看到它调用了以下方法:

private native int getStackTraceDepth();

据我所知,native 不能是静态的(我可能错了)。

【讨论】:

  • 本机方法可以是静态的(几乎可以参见java.lang.StrictMath 中的任何方法)。
  • @Peter Lawrey,它在 JDK 的 Throwable 类上(我的是 1.6.0-21,我相信它是从 JDK 4 开始引入的?)
  • 如果原生可以是静态的,我认为Throwable.getStackTrace()new Throwable().getStackTrace() 更好
  • @精英绅士,java.lang.Thread也有这个方法。它被标记为@since 1.4。不确定是否有 JDK 4。;)
  • @Stas:如果它是静态的,它们会有完全不同的语义。 getStackTrace() 的子类 Throwable 应该在调用 fillInStackTrace() 时返回堆栈跟踪,这通常是在构造 Throwable 时。静态调用它必须返回堆栈跟踪的任何内容.
【解决方案2】:

我经常用它来记录日志,所以我很高兴它不是抽象的。有一种获取调用堆栈的方法,Thread.currentThread().getStackTrace(),但这会返回一个 StackTraceElement[],这对于日志记录不是很有用。

编辑:

StackTraceElement[] stes = Thread.currentThread().getStackTrace();  

注意:此方法也可用于获取另一个线程的堆栈跟踪,这很方便。

【讨论】:

  • 你能展示一下你是如何使用它的吗?在 java.util.logging 它用于获取 StackTraceElement[] "(new Throwable()).getStackTrace();"
  • 我不认为制作 Throwable 抽象会真正阻止您...您可以使用 new Throwable(){}.printStackTrace() 进行一次性日志记录,或者对于您保留的日志记录,您可能应该使用清洁器 Thread无论如何解决方案(或者至少是一个包装它的库方法)。
  • @Mark,记录 StackTraceElement[] 难以阅读。例如,您不希望它被其他日志消息拆分。尤其是另一个堆栈跟踪。
  • 很公平,但对于非一次性日志记录,我希望有人使用一个日志框架,无论如何都可以为您完成所有这些工作(我见过的所有日志框架都有直接记录 Throwable 的方法) .
猜你喜欢
  • 2014-06-24
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 2013-09-21
  • 2023-01-28
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
相关资源
最近更新 更多