是否有任何理由将异常的原因设置为自身?
我在Java库中遇到过一些我正在构建的地方,其中异常的原因被设置为异常本身。
是否有任何理由将例外本身作为其原因?
编辑
根据要求,这里有一个具体的例子:
我在Java库中遇到过一些我正在构建的地方,其中异常的原因被设置为异常本身。
是否有任何理由将例外本身作为其原因?
编辑
根据要求,这里有一个具体的例子:
我经常看到框架或库(如Hibernate或Spring引用)引发的异常本身就是原因(在此过程中混淆了调试器GUI)。
我一直想知道他们为什么这样做,因为这似乎是一个坏主意。今天,当我试图将一个序列化为JSON时,它实际上引起了一个问题:bam,无周期。
所以我进一步研究了它:
在源代码中(这里列出的所有源代码都来自JDK 1.7),我们有这个:Throwable
/**
* The throwable that caused this throwable to get thrown, or null if this
* throwable was not caused by another throwable, or if the causative
* throwable is unknown. If this field is equal to this throwable itself,
* it indicates that the cause of this throwable has not yet been
* initialized.
*
* @serial
* @since 1.4
*/
private Throwable cause = this;
现在我特别遇到了一个扩展的异常类的问题,所以我从那里开始。的构造函数之一:RuntimeException
RuntimeException
/** Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public RuntimeException(String message) {
super(message);
}
由上述调用的 构造函数:Exception
/**
* Constructs a new exception with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public Exception(String message) {
super(message);
}
由上述调用的 构造函数:Throwable
/**
* Constructs a new throwable with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* <p>The {@link #fillInStackTrace()} method is called to initialize
* the stack trace data in the newly created throwable.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
}
fillInStackTrace
是一种本机方法,并且似乎不会修改原因字段。
因此,如您所见,除非随后调用该方法,否则该字段永远不会从 的原始值更改。initCause
cause
this
结论 :如果您使用不带参数的构造函数创建一个新的(或存在于野外并且不覆盖此行为的许多子类之一),并且您不调用该方法,则异常的原因将是它本身!Exception
cause
initCause
所以我想这应该使它成为一个非常普遍的情况。
接受的答案具有误导性,其他答案是不完整的。所以。。。
虽然将异常作为其自身原因传递是糟糕的设计,但正是由于这个原因,在Shrewable实现中是不可能的。原因要么在构造过程中传递,要么传递到initCause()方法,并且如第二个答案中指出的那样,后者将导致非法参数异常。
正如第三个答案所指出的那样,如果你没有提供原因,那么根据Srowtable实现,原因将是这个。
可能缺少的(给定原始问题)是Spredable的getCause()方法永远不会返回这个,如果原因==this,它将返回null。因此,尽管调试器将此引用显示为原因,因为它正在使用反射,但在使用 Throwable 的公共接口时,您将看不到它,因此它不会成为问题。