dok*_*par 30 java lambda exception java-8
我升级到Java 8并试图用一个新的lamdba表达式替换一个简单的迭代迭代.循环搜索空值并在找到异常时抛出异常.旧的Java 7代码如下所示:
for (Map.Entry<String, String> entry : myMap.entrySet()) {
if(entry.getValue() == null) {
throw new MyException("Key '" + entry.getKey() + "' not found!");
}
}
Run Code Online (Sandbox Code Playgroud)
我将其转换为Java 8的尝试如下所示:
myMap.forEach((k,v) -> {
if(v == null) {
// OK
System.out.println("Key '" + k+ "' not found!");
// NOK! Unhandled exception type!
throw new MyException("Key '" + k + "' not found!");
}
});
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么throw这里不允许的声明以及如何纠正这个问题?
Eclipse的快速修复建议看起来并不合适......它只是throw用一个try-catch块来围绕语句:
myMap.forEach((k,v) -> {
if(v == null) {
try {
throw new MyException("Key '" + k + "' not found!");
}
catch (Exception e) {
e.printStackTrace();
}
}
});
Run Code Online (Sandbox Code Playgroud)
And*_*lko 46
您不能抛出已检查的异常,因为接口中的accept(T t, U u)方法java.util.function.BiConsumer<T, U>未在其throws子句中声明任何异常.而且,如你所知,Map#forEach采取这种类型.
public interface Map<K, V> {
default void forEach(BiConsumer<? super K, ? super V> action) { ... }
} |
|
V
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u); // <-- does throw nothing
}
Run Code Online (Sandbox Code Playgroud)
当我们谈论检查异常时,这是事实.但你仍然可以抛出一个未经检查的异常(例如a java.lang.IllegalArgumentException):
new HashMap<String, String>()
.forEach((a, b) -> { throw new IllegalArgumentException(); });
Run Code Online (Sandbox Code Playgroud)
Dav*_* SN 26
你可以在lambdas中抛出异常.
允许lambda抛出与lambda实现的功能接口相同的异常.
如果函数接口的方法没有throws子句,则lambda不能抛出CheckedExceptions.(你仍然可以抛出RuntimeExceptions).
在您的特定情况下,Map.forEach使用a BiConsumer作为参数,BiConsumer定义为:
public interface BiConsumer<T, U> {
void accept(T t, U u);
}
Run Code Online (Sandbox Code Playgroud)
此功能接口的lambda表达式不能抛出CheckedExceptions.
java.util.function包中定义的功能接口中的方法不会抛出异常,但是您可以使用其他功能接口或创建自己的接口以便能够抛出异常,即给定此接口:
public interface MyFunctionalInterface<T> {
void accept(T t) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
以下代码是合法的:
MyFunctionalInterface<String> f = (s)->throw new Exception("Exception thrown in lambda");
Run Code Online (Sandbox Code Playgroud)