在处理抛出 Throwable 的方法时,我应该避免抛出 Throwable 吗?
Should I avoid throwing Throwable when dealing with a method that throws Throwable?
我有一个 @Aspect
注释 class 正在调用 ProceedingJoinPoint#proceed()
。
此方法 throws Throwable
和 class 看起来像这样:
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return joinPoint.proceed();
} finally {
//some more code here
}
}
}
在我必须调用另一个方法 throws Throwable
的情况下,myMehtod
可以抛出 Throwable
吗?
我应该避免抛出 Throwable
并以某种方式将其转换为 Exception
或 Error
吗?
无论哪种情况,我都想知道为什么。谢谢。
不行,扔Throwable不行。错误和未经检查的异常不应该被捕获;错误是严重的或致命的系统问题,而未经检查的异常(通常)会暴露程序员的错误。使用 throws Throwable
声明签名会强制调用者捕获并允许他们抑制不应捕获或抑制的内容。
如果可能,您应该修复 ProceedingJoinPoint.proceed()
方法的签名,但如果您无法控制 class,您自己的代码应该将其包装在更合理的异常中。
如何包装它取决于您对代码调用者的期望。如果任何 Throwable 可能是一个条件,没有人可以做任何事情来纠正或解决,你不妨将它包装在一个未经检查的 RuntimeException 中:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
//some more code here
}
如果你想确保调用者优雅地处理所有 Throwable,你应该创建你自己的特定于应用程序的异常 class:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new JoinPointException(t);
} finally {
//some more code here
}
异常 class 很简单:
public class JoinPointException
extends Exception {
private static final long serialVersionUID = 1;
public JoinPointException(Throwable cause) {
super(cause);
}
public JoinPointException(String message,
Throwable cause) {
super(message, cause);
}
}
如果您使用 Lombok you can use @SneakyThrows 以便在不声明的情况下重新抛出 Throwable。
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return proceed(joinPoint)
} finally {
//some more code here
}
}
@SneakyThrows
public Object proceed(ProceedingJoinPoint joinPoint) {
return joinPoint.proceed();
}
}
这是我所知道的避免捕获和包装 Throwable 或已检查异常的唯一方法。
我有一个 @Aspect
注释 class 正在调用 ProceedingJoinPoint#proceed()
。
此方法 throws Throwable
和 class 看起来像这样:
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return joinPoint.proceed();
} finally {
//some more code here
}
}
}
在我必须调用另一个方法 throws Throwable
的情况下,myMehtod
可以抛出 Throwable
吗?
我应该避免抛出 Throwable
并以某种方式将其转换为 Exception
或 Error
吗?
无论哪种情况,我都想知道为什么。谢谢。
不行,扔Throwable不行。错误和未经检查的异常不应该被捕获;错误是严重的或致命的系统问题,而未经检查的异常(通常)会暴露程序员的错误。使用 throws Throwable
声明签名会强制调用者捕获并允许他们抑制不应捕获或抑制的内容。
如果可能,您应该修复 ProceedingJoinPoint.proceed()
方法的签名,但如果您无法控制 class,您自己的代码应该将其包装在更合理的异常中。
如何包装它取决于您对代码调用者的期望。如果任何 Throwable 可能是一个条件,没有人可以做任何事情来纠正或解决,你不妨将它包装在一个未经检查的 RuntimeException 中:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
//some more code here
}
如果你想确保调用者优雅地处理所有 Throwable,你应该创建你自己的特定于应用程序的异常 class:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new JoinPointException(t);
} finally {
//some more code here
}
异常 class 很简单:
public class JoinPointException
extends Exception {
private static final long serialVersionUID = 1;
public JoinPointException(Throwable cause) {
super(cause);
}
public JoinPointException(String message,
Throwable cause) {
super(message, cause);
}
}
如果您使用 Lombok you can use @SneakyThrows 以便在不声明的情况下重新抛出 Throwable。
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return proceed(joinPoint)
} finally {
//some more code here
}
}
@SneakyThrows
public Object proceed(ProceedingJoinPoint joinPoint) {
return joinPoint.proceed();
}
}
这是我所知道的避免捕获和包装 Throwable 或已检查异常的唯一方法。