gpt4 book ai didi

java-8 - Java 8 lambda 捕获异常

转载 作者:行者123 更新时间:2023-12-04 02:07:34 25 4
gpt4 key购买 nike

摘自 Cay Horstmann 的Java 8 for the impatient一书:

Didn’t you always hate it that you had to deal with checked exceptions in a Runnable? Write a method uncheck that catches all checked exceptions and turns them into unchecked exceptions. For example,

new Thread(uncheck(
() -> { System.out.println("Zzz"); Thread.sleep(1000); })).start();
// Look, no catch (InterruptedException)!

Hint: Define an interface RunnableEx whose run method may throw any exceptions. Then implement

public static Runnable uncheck(RunnableEx runner)

Use a lambda expression inside the uncheck function.

为此我编写了这样的代码:

public interface RunnableEx {
void run() throws Exception;
}

public class TestUncheck {
public static Runnable uncheck(RunnableEx r) {
return new Runnable() {
@Override
public void run() {
try {
r.run();
} catch (Exception e) {
}
}
};
}

public static void main(String[] args) {
new Thread(uncheck(
() -> {
System.out.println("Zzz");
Thread.sleep(1000);
}
)).start();
}
}

我有按照提示去做吗?有更好的方法吗?

还有一个补充问题:

Why can’t you just use Callable<Void> instead of RunnableEx?

最佳答案

您的代码无法将已检查的异常包装到未检查的异常中。此外,它没有遵循使用 lambda 表达式的提示。更正后的版本是:

public static Runnable uncheck(RunnableEx r) {
return () -> {
try {
r.run();
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}

确实有可能进一步改进这一点。自 RunnableEx 的整个目的接口(interface)是包装一个Runnable ,您可以将工厂方法放在接口(interface)本身内:

public interface RunnableEx {
void run() throws Exception;
public static Runnable uncheck(RunnableEx r) {
return () -> {
try {
r.run();
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}
}

当然,现在您的调用代码必须适应:

public static void main(String[] args) {
new Thread(RunnableEx.uncheck(
() -> {
System.out.println("Zzz");
Thread.sleep(1000);
}
)).start();
}

现在,接口(interface)本身可以实现包装功能,与Runnable 兼容。 , 这将消除对 Runnable 的需求和一个 RunnableEx表示单个 Action 的实例:

public interface RunnableEx extends Runnable {
void runWithException() throws Exception;
@Override default void run() {
try {
runWithException();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Runnable uncheck(RunnableEx r) {
return r;
}
}

请注意,虽然调用代码在语法上没有改变,但它会隐式创建一个 Runnable首先是实例,在创建 RunnableEx 时例如,这就是为什么 uncheck变成空操作,仅仅作为 RunnableEx 的标记应该创建而不是 Runnable .使用此接口(interface)定义,您可以通过

public static void main(String[] args) {
new Thread( (RunnableEx) () -> {
System.out.println("Zzz");
Thread.sleep(1000);
}
).start();
}

您不能“只使用”Callable<Void> 的原因在这里,是Callable<Void>仍然是Callable ,要求实现代码返回一个值。换句话说,不存在从 void 的隐式转换。至 Void .所以你可以使用它,但 lambda 表达式需要 return null;然后在其末尾声明( null 是唯一与 Void 兼容的值)。

public class TestUncheck {
public static Runnable uncheck(Callable<Void> r) {
return () -> {
try { r.call(); }
catch (Exception e) { throw new RuntimeException(e); }
};
}

public static void main(String[] args) {
new Thread(uncheck(
() -> {
System.out.println("Zzz");
Thread.sleep(1000);
return null;
}
)).start();
}
}

关于java-8 - Java 8 lambda 捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41913091/

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