给定一个可能会抛出异常的函数:
public static int f() throws Exception {
// do something
}
这段代码有什么办法吗:
public static int catchF() throws Exception {
try {
return f();
} catch (Exception ex) {
throw ex;
}
}
与直接调用f
有什么不同吗? IE。调用者可以通过检查异常来检测差异吗?使用 catchF
而不是 f
是否有任何明显的开销?
如果没有区别,编译器或 JVM 能否将对 catchF
的调用优化为对 f
的直接调用?
虽然这看起来像是一件奇怪的事情,但用例是在之前隐藏异常之后在类型级别重新引入异常:
class Test {
// Hide the exception.
public static <X extends Exception, T> T throwUnchecked(Exception ex) throws X {
throw (X) ex;
}
// Interface for functions which throw.
interface Throws<T, R, X extends Exception> {
R apply(T t) throws X;
}
// Convert a function which throws a visible exception into one that throws a hidden exception.
public static <T, R, X extends Exception> Function<T, R> wrap(Throws<T, R, X> thrower) {
return t -> {
try {
return thrower.apply(t);
} catch(Exception ex) {
return throwUnchecked(ex);
}
};
}
// Unhide an exception.
public static <R, X extends Exception> R unwrap(Supplier<R> supp) throws X {
try {
return supp.get();
} catch (Exception ex) {
throw (X)ex;
}
}
public static Stream<Integer> test(Stream<String> ss) throws NumberFormatException {
return Test.<Stream<Integer>, NumberFormatException>unwrap(
() -> ss.map(wrap(Integer::parseInt))
);
}
public static void main(String[] args) throws NumberFormatException {
final List<Integer> li = test(Arrays.stream(new String[]{"1", "2", "3"})).collect(toList());
System.out.println(li);
}
}
目的是将抛出异常的函数包装到在类型级别隐藏异常的函数中。这使得异常可以用于流等情况。
最佳答案
is any different to calling f directly?
没有。
I.e. could the caller detect the difference by inspecting the exception?
不,因为此时您没有构建新的异常。堆栈跟踪是在调用 new WhateverException(...)
的位置构建的(不是在 throw
所在的位置,尽管它们是通常在同一个地方)。
通常,如果您需要因异常而进行一些清理,则可以重新抛出捕获的异常:
try {
// ...
} catch (SomeException e) {
// Clean up resources.
throw e;
}
调用堆栈展开时发生的事情对于调用者来说既不可见也不相关。
快速演示可以显示,无论异常是 caught and rethrown,堆栈跟踪都是相同的。或者简单地 allowed to propagate .
Is there any discernible overhead in using catchF instead of f?
构造异常的开销将远远超过此冗余构造的任何开销。
关于java - 使用重新抛出异常的异常处理程序是否有任何明显的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57353781/