java - 使用重新抛出异常的异常处理程序有什么明显的区别吗
问题描述
给定一个可能抛出的函数:
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);
}
}
目的是将抛出异常的函数包装到在类型级别隐藏异常的函数中。这使得异常可用于例如流。
解决方案
与直接调用 f 有什么不同?
不。
即调用者可以通过检查异常来检测差异吗?
不,因为此时您没有构建新的异常。堆栈跟踪是在new WhateverException(...)
调用 the 的地方构建的(不是在哪里throw
,尽管它们通常在同一个地方)。
通常,如果由于异常而需要进行一些清理,则重新抛出捕获的异常:
try {
// ...
} catch (SomeException e) {
// Clean up resources.
throw e;
}
调用堆栈展开时发生的事情对调用者既不可见也不相关。
一个快速演示可以显示堆栈跟踪是相同的,无论异常是被捕获并重新抛出还是仅仅允许传播。
使用 catchF 而不是 f 是否有任何明显的开销?
构造异常的开销将远远超过这个冗余构造的任何开销。
推荐阅读
- reactjs - React JSX array.map() 无法读取数据。不明确的
- node.js - findOneAndUpdate 在数组中不起作用
- python - 使用变量查找 xpath selenium 不起作用
- authentication - 登录时 POST http://127.0.0.1:8000/api/login 401 (Unauthorized) 错误
- instagram - 是否有关于 Instagram 推荐引擎可解释性/因果推理的论文发表?
- python - python随机抽样行并生成抽样权重
- python - 使用 Flask 和 Pandas 将大型数据框写入 excel
- pine-script - 研究错误消息:输入订单的数量必须为正,输入值为 -834444.22394394
- reactjs - 如何在 React JSX 中使用 css 剪辑路径
- php - 如何根据用户角色和产品类别在 WooCommerce 中激活“零税率”税类