给定一个可能抛出的函数:
public static int f() throws Exception {
// do something
}
这段代码有什么办法:
public static int catchF() throws Exception {
try {
return f();
} catch (Exception ex) {
throw ex;
}
}
和直接打电话有什么不同吗f?即调用者可以通过检查异常来检测差异吗?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);
}
}
目的是将抛出异常的函数包装到在类型级别隐藏异常的函数中。这使得异常可用于例如流。
皈依舞
ibeautiful
相关分类