为什么我不能在创建实例或抛出异常时调用 initCause()
Why I can not call initCause() at creation of an instance or throwing an exception
我不明白为什么我不能 initCause()
在创建实例或抛出异常的同一行中。如果我把它放在同一行,编译器认为该方法必须抛出一个可抛出的对象。
// All exceptions in the example are subclass of Exception class;
private static void throwException() throws BadCodeException {
throw new BadCodeException("Actual cause");
}
private static void rethrowException() throws BadProgramException{
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
ex.initCause(e);
throw ex;
} /* catch (BadCodeException e) { // Compiler tells about unhandled Throwable;
throw new BadProgramException("Problem that occurred").initCause(e);
} */
此外,如果有人告诉我链式异常的使用是否正确,我会很高兴,因为只有我发现。
如 khelwood 所述,initCause
声明了 return 类型的 Throwable
(查看 API 文档)。因此,如果您抛出 initCause
的结果,那么(就编译器而言),您的方法可能会抛出任何类型的 Throwable
.
为了回答您的其他问题,执行链式异常的正常方法是
throw new BadProgramException("Problem that occurred", e);
然后向 BadProgramException
添加另一个构造函数,如果它没有这样的构造函数,它只是用它的两个参数调用 super
。
那个方法没有这个问题。如果 BadProgramException
是无法修改以添加额外构造函数的遗留 class,则只需要调用 initCause
。
因为这是签名:
public synchronized Throwable initCause(Throwable cause);
可以看到,这里的return类型是Throwable
;
一行完成等于:
// Throwable is not BadProgramException! It's wider type
private static void rethrowException() throws BadProgramException {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
Throwable throwable = ex.initCause(e);
throw throwable;
}
}
什么需要额外处理。您更改 引用类型 在一行中完成。您的方法不再抛出 BadProgramException
。它抛出 wider,顶级异常类型。
一行完成不会改变引用类型:
private static void rethrowException() throws BadProgramException {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
ex.initCause(e);
throw ex; // Reference type is still BadProgramException and matches current signature
}
}
基本上单线调用可以这样解决:
private static void rethrowException() throws Throwable {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
throw ex.initCause(e);
}
}
但这不是抛出所有错误的超类的好方法,如 Throwable
。您需要抛出尽可能窄的异常类型。
我不明白为什么我不能 initCause()
在创建实例或抛出异常的同一行中。如果我把它放在同一行,编译器认为该方法必须抛出一个可抛出的对象。
// All exceptions in the example are subclass of Exception class;
private static void throwException() throws BadCodeException {
throw new BadCodeException("Actual cause");
}
private static void rethrowException() throws BadProgramException{
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
ex.initCause(e);
throw ex;
} /* catch (BadCodeException e) { // Compiler tells about unhandled Throwable;
throw new BadProgramException("Problem that occurred").initCause(e);
} */
此外,如果有人告诉我链式异常的使用是否正确,我会很高兴,因为只有我发现。
如 khelwood 所述,initCause
声明了 return 类型的 Throwable
(查看 API 文档)。因此,如果您抛出 initCause
的结果,那么(就编译器而言),您的方法可能会抛出任何类型的 Throwable
.
为了回答您的其他问题,执行链式异常的正常方法是
throw new BadProgramException("Problem that occurred", e);
然后向 BadProgramException
添加另一个构造函数,如果它没有这样的构造函数,它只是用它的两个参数调用 super
。
那个方法没有这个问题。如果 BadProgramException
是无法修改以添加额外构造函数的遗留 class,则只需要调用 initCause
。
因为这是签名:
public synchronized Throwable initCause(Throwable cause);
可以看到,这里的return类型是Throwable
;
一行完成等于:
// Throwable is not BadProgramException! It's wider type
private static void rethrowException() throws BadProgramException {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
Throwable throwable = ex.initCause(e);
throw throwable;
}
}
什么需要额外处理。您更改 引用类型 在一行中完成。您的方法不再抛出 BadProgramException
。它抛出 wider,顶级异常类型。
一行完成不会改变引用类型:
private static void rethrowException() throws BadProgramException {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
ex.initCause(e);
throw ex; // Reference type is still BadProgramException and matches current signature
}
}
基本上单线调用可以这样解决:
private static void rethrowException() throws Throwable {
try {
throwException();
} catch (BadCodeException e) {
BadProgramException ex = new BadProgramException("Problem that occurred");
throw ex.initCause(e);
}
}
但这不是抛出所有错误的超类的好方法,如 Throwable
。您需要抛出尽可能窄的异常类型。