gpt4 book ai didi

java - 跳过try/catch block 以检查异常的Lambda

转载 作者:行者123 更新时间:2023-12-01 11:47:37 25 4
gpt4 key购买 nike

由于我尝试提取在我的大多数项目中使用的一些常见的包装lambda例程,因此我能够创建CheckedFunction,它是PermeableFunction FunctionalInterface的子类,它绕过了try/catch块的需要。我已经在Windows(v1.8.0_251)/linux(v1.8.0_261)和其他几个在线编译器的Oracle jdks上进行了测试(不确定在那里使用了哪种实现)。
不确定这是否确实违反了规范或标准是否允许...根据我对docs的解释,这应该是不可能的:

More precisely, suppose that B is a class or interface, and A is a superclass or superinterface of B, and a method declaration n in B overrides or hides a method declaration m in A. Then:

  • If n has a throws clause that mentions any checked exception types, then m must have a throws clause, or a compile-time error occurs.
  • For every checked exception type listed in the throws clause of n, that same exception class or one of its supertypes must occur in the erasure (§4.6) of the throws clause of m; otherwise, a compile-time error occurs.
  • If the unerased throws clause of m does not contain a supertype of each exception type in the throws clause of n, a compile-time unchecked warning occurs.

这是我使用的示例代码:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Function;

public class Main {

public static void main(String[] args) {

PermeableFunction<Path, Long> function = PermeableFunction.from(Files::size);

Path doesNotExist = Paths.get("/does/not/exist");

// function.apply(doesNotExist); -> throws WrappedException
function.applyChecked(doesNotExist); // throws NoSuchFileException without the need of a try/catch block!
}
}

interface PermeableFunction<T,R> extends CheckedFunction<T, R, RuntimeException> {

static <T, R> PermeableFunction<T, R> from(WrappedFunction<T, R> wrappedFunction) {

return CheckedFunction.<T,R, RuntimeException>from(wrappedFunction)::applyChecked;
}
}

interface CheckedFunction<T, R, E extends Exception> extends WrappedFunction<T, R> {

@Override
R applyChecked(T t) throws E;

static <T, R, E extends Exception> CheckedFunction<T, R, E> from(WrappedFunction<T, R> wrappedFunction) {

return wrappedFunction::applyChecked;
}
}

interface WrappedFunction<T, R> extends Function<T, R> {

R applyChecked(T t) throws Exception;

@Override
default R apply(T t) {

try {

return applyChecked(t);

} catch (Exception e) {

throw new WrappedException(e);
}
}
}

class WrappedException extends RuntimeException {

public WrappedException(Throwable cause) {
super(cause);
}
}
CheckedFunction还允许像这样对可抛出对象进行阴影处理:
enter image description here
所以这是我的问题:
这是应该报告给实现者的问题,还是该标准强加的普遍问题?

最佳答案

你的方法

static <T, R, E extends Exception> CheckedFunction<T, R, E> from(WrappedFunction<T, R> wrappedFunction) {
return wrappedFunction::applyChecked;
}
被我的Eclipse版本以及从9到14的所有JDK的 javac拒绝了。只有JDK 8接受了它,所以这是一个错误,但不值得报告,因为较新的版本没有它。
也就是说,可以通过泛型类型系统来破坏异常检查。
当您将方法更改为
static <T, R, E extends Exception> CheckedFunction<T, R, E> from(WrappedFunction<T, R> wrappedFunction) {
return (CheckedFunction)(CheckedFunction<T, R, Exception>)wrappedFunction::applyChecked;
}
所有编译器都将接受它,但是会产生“未经检查”的警告。这是已知的事情。
您可以将示例简化为:
public class Main {
public static void main(String[] args) {
CheckedFunction<Path, Long, RuntimeException> function = (CheckedFunction)
(CheckedFunction<Path, Long, IOException>)Files::size;
Path doesNotExist = Paths.get("/does/not/exist");

function.applyChecked(doesNotExist); // throws NoSuchFileException without the need of a try/catch block!
}

interface CheckedFunction<T, R, E extends Exception> {
R applyChecked(T t) throws E;
}
}
即使没有lambda表达式,也可能有几种变体。它所需要的只是一个使用类型参数的 throws声明以及与此类型参数有关的未经检查的操作。
例如。
public class Main {
public static void main(String[] args) {
try {
Files.size(Paths.get("/does/not/exist"));
}
catch(IOException ex) {
doThrow(ex); // throws undeclared IOException
}
}

static <T extends Throwable> void doThrow(Throwable t) throws T {
throw (T)t;
}
}
如前所述,这是众所周知的,但总的来说,您永远不应忽略“未经检查”的警告。

关于java - 跳过try/catch block 以检查异常的Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63391917/

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