在Java 8 中,当写lambda表达式并处理异常时代码变得冗余不堪,本文主要介绍lambda表达式中一些异常处理方式。
下面的代码,当i为0时会引发ArithmeticException异常。
List<Integer> integers = Arrays.asList(3, 9, 7, 6, 10, 20);
integers.forEach(i -> System.out.println(50 / i));
通常的做法是通过try…catch来处理异常,防止系统崩溃。
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(i -> {
try {
System.out.println(50 / i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
使用try…catch后代码不再像以前一样简洁。我们可以通过写一个包装方法来进行处理。
static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
return i -> {
try {
consumer.accept(i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(lambdaWrapper(i -> System.out.println(50 / i)));
通过编写包装方法lambdaWrapper并接收一个lambda表达式,在该方法内会进行异常处理。因此对于同类问题就可以避免反复写try…catch。
再次改进增加一个异常类型, 可以抛出我们希望抛出的异常。
static <T, E extends Exception> Consumer<T>
consumerWrapper(Consumer<T> consumer, Class<E> clazz) {
return i -> {
try {
consumer.accept(i);
} catch (Exception ex) {
try {
E exCast = clazz.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw ex;
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(
consumerWrapper(
i -> System.out.println(50 / i),
ArithmeticException.class));
类似的可以根据实际需求写出各种类型的函数式接口包装类,如Function, BiFunction, BiConsumer等。
这个例子中writeToFile会抛出IOException。IOException是一个Checked异常,所以必须处理。因此要么抛出要么捕获。
static void writeToFile(Integer integer) throws IOException {
// logic to write to file which throws IOException
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(i -> writeToFile(i));
throws抛出异常仍然会提示错误unhandled IOException。
public static void main(String[] args) throws IOException {
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(i -> writeToFile(i));
尝试实现Consumer,并指定accept抛出Exception,仍然错误。因为accept定义中并未
抛出任何异常。
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
writeToFile(integer);
最直接的处理方法是通过try…catch捕获。
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(i -> {
try {
writeToFile(i);
} catch (IOException e) {
throw new RuntimeException(e);
其次我们可以通过自定义函数式接口并声明方法抛出异常。
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception> {
void accept(T t) throws E;
编写包装类,接着使用,这样在foreach中方法不但可以抛出异常同时又能保持简洁性。
static <T> Consumer<T> throwingConsumerWrapper(
ThrowingConsumer<T, Exception> throwingConsumer) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(throwingConsumerWrapper(i -> writeToFile(i)));
接着对throwingConsumerWrapper进行改造,使其能接收一个异常类型参数。
static <T, E extends Exception> Consumer<T> handlingConsumerWrapper(
ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
try {
E exCast = exceptionClass.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw new RuntimeException(ex);
List<Integer> integers = Arrays.asList(3, 9, 7, 0, 10, 20);
integers.forEach(handlingConsumerWrapper(
i -> writeToFile(i), IOException.class));
类似的,可以根据实际需求编写ThowingFunction, ThrowingBiFunction, ThrowingBiConsumer。
本文主要介绍了java 8Lamda表达式的异常处理方式,如果希望使用现成的工具可以考虑Vavr或ThrowingFunction,这两个工具值得一看。vavr的功能简介可参考https://blog.csdn.net/revivedsun/article/details/80088080。
http://www.baeldung.com/java-lambda-exceptions
1. 概述在Java 8 中,当写lambda表达式并处理异常时代码变得冗余不堪,本文主要介绍lambda表达式中一些异常处理方式。2. 处理 Unchecked 异常下面的代码,当i为0时会引发ArithmeticException异常。List&lt;Integer&gt; integers = Arrays.asList(3, 9, 7, 6, 10, 20);in...
对于STL中的map中的key可以重复吗?答案就是key不可以重复,但是value是可以重复的。
如果需要key值相同那么可以采用multimap,是允许key值重复的。
m.insert(make_pair<int, int>(1, 3));
m.insert(make_pair<int, int>(0, 4));
m.insert(make_pair<int, int>(0, 2));
MyMap::iterator it;
for(it = m.begin(
Java集合容器面试题(2020最新版) 笔记概述集合框架底层数据结构哪些集合类是线程安全的?Java集合的快速失败机制 “fail-fast”?Collection接口List接口Set接口Queue接口Map接口
Java 容器分为 Collection 和 Map 两大类,Collection集合的子接口有Set、List、Queue三种子接口。我们比较常用的是Set、List,Map接口不是collection的子接口。
Collection集合主要有List和Set两大接口
List:一个
今儿在使用lambda表达式时,lambda表达式内出现了异常,准备直接抛出,没想到却还是报错:
由于博主lambda表达式用的比较少,刚看到这问题时,可以说是一脸懵逼.毕竟两边的提示可以说是前后矛盾啊.
刷新几下编译器还是报错,就只能老老实实的找原因.
所幸Java是一门比较成熟的语言,前辈们已经踩了足够的坑.
之所以有这种现象是因为lambda表达式本身没有处理异常的机制 ,以至于遇到受检异常时,无法通过主动抛出来解决.
但具体的也不是很清楚了,若有其他道友遇到这种问题,欢迎评论区
java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Interface通常都是没有抛出异常的,这意味着需要我们自己手动来处理异常。
因为异常分为Unchecked Exception和checked Exception,我们分别来讨论。
处理Unchecked Exception
Unchecked exception
Stream API 和 lambda 是 Java8以来对Java的重大改进。从那时起,我们可以使用更具有功能性的语法风格的代码。但是有个问题就是,我们使用了 lambda 表达式,那 lambda 中的异常该怎么处理呢。
大家都知道,不能直接在 lambda 中调用那些会抛出异常的方法,因为这样从编译上都通不过。所以我们需要捕获异常以使代码能够编译通过。
例如,我们可以在 lambda...
FtpManager * p = new FtpManager(this);
p->SetHost("127.0.0.1", 21);
p->SetUserName("anonymous");
p->SetPwd("");
p->SetPort(21);
ui->tableWidget->setRowCount(1);
ui->tableWidget->setColumnCount(3);
public static void main(String[] args) {
String name = "小花";
// 定义匿名内部类作为参数传递给animalShout()方法
animalShout(n
文章目录问题解决办法
参考博客:https://dzone.com/articles/how-to-handle-checked-exception-in-lambda-expressi
在Java中使用lambda,我觉得很重要的一点就是为了代码的简洁,但是由于Java常用的函数式接口都没有异常的处理,导致我们必须要try-catch来处理异常,使得代码变得臃肿,违背了初衷。
假设有这一个类
public class TestEntity {
private String name;
foreach 循环中,每次都需要http请求,http请求会抛出异常。idea会自动提示 try…catch
但是此时,是 循环中内部try…catch,catch则无法向外throw异常。
初步解决:把try…catch放到整个foreach 循环外面,但是依旧存在循环内部需要try…catch
把try…catch放到整个循环外面,如果使用普通的for循环,自己设定索引i 进行循环,就可以成功在catch中向外抛异常