gpt4 book ai didi

java - 使用重新抛出异常的异常处理程序是否有任何明显的区别

转载 作者:行者123 更新时间:2023-11-30 01:47:40 26 4
gpt4 key购买 nike

给定一个可能会抛出异常的函数:

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com