java 8 lambda表达式中的异常处理
java 8 lambda表达式中的异常处理
简介
java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Interface通常都是没有抛出异常的,这意味着需要我们自己手动来处理异常。
因为异常分为Unchecked Exception和checked Exception,我们分别来讨论。
处理Unchecked Exception
Unchecked exception也叫做RuntimeException,出现RuntimeException通常是因为我们的代码有问题。RuntimeException是不需要被捕获的。也就是说如果有RuntimeException,没有捕获也可以通过编译。
我们看一个例子:
List<Integer> integers = Arrays.asList(1,2,3,4,5);
integers.forEach(i -> System.out.println(1 / i));
这个例子是可以编译成功的,但是上面有一个问题,如果list中有一个0的话,就会抛出ArithmeticException。
虽然这个是一个Unchecked Exception,但是我们还是想处理一下:
integers.forEach(i -> {
try {
System.out.println(1 / i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
});
上面的例子我们使用了try,catch来处理异常,简单但是破坏了lambda表达式的最佳实践。代码变得臃肿。
我们将try,catch移到一个wrapper方法中:
static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
return i -> {
try {
consumer.accept(i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
};
}
则原来的调用变成这样:
integers.forEach(lambdaWrapper(i -> System.out.println(1 / i)));
但是上面的wrapper固定了捕获ArithmeticException,我们再将其改编成一个更通用的类:
static <T, E extends Exception> Consumer<T>
consumerWrapperWithExceptionClass(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;
}
}
};
}
上面的类传入一个class,并将其cast到异常,如果能cast,则处理,否则抛出异常。
这样处理之后,我们这样调用:
integers.forEach(
consumerWrapperWithExceptionClass(
i -> System.out.println(1 / i),
ArithmeticException.class));
处理checked Exception
checked Exception是必须要处理的异常,我们还是看个例子:
static void throwIOException(Integer integer) throws IOException {
}
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
integers.forEach(i -> throwIOException(i));
上面我们定义了一个方法抛出IOException,这是一个checked Exception,需要被处理,所以在下面的forEach中,程序会编译失败,因为没有处理相应的异常。
最简单的办法就是try,catch住,如下所示:
integers.forEach(i -> {
try {
throwIOException(i);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
当然,这样的做法的坏处我们在上面已经讲过了,同样的,我们可以定义一个新的wrapper方法:
static <T> Consumer<T> consumerWrapper(
ThrowingConsumer<T, Exception> throwingConsumer) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
我们这样调用:
integers.forEach(consumerWrapper(i -> throwIOException(i)));
我们也可以封装一下异常:
static <T, E extends Exception> Consumer<T> consumerWrapperWithExceptionClass(
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);
}
}
};
}
然后这样调用:
integers.forEach(consumerWrapperWithExceptionClass(
i -> throwIOException(i), IOException.class));
总结
本文介绍了如何在lambda表达式中处理checked和unchecked异常,希望能给大家一些帮助。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/lambda-exception
欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com
java 8 lambda表达式中的异常处理的更多相关文章
- Java 8 Lambda表达式
Java 8 Lambda表达式探险 http://www.cnblogs.com/feichexia/archive/2012/11/15/Java8_LambdaExpression.html 为 ...
- 深入浅出 Java 8 Lambda 表达式
摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...
- Java 8 Lambda表达式10个示例【存】
PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...
- Java SE 8 for the Really Impatient读书笔记——Java 8 Lambda表达式
1. lambda表达式的语法 lambda表达式是一种没有名字的函数,它拥有函数体和参数. lambda表达式的语法十分简单:参数->主体.通过->来分离参数和主体. 1.1 参数 la ...
- Java 8 Lambda 表达式
Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...
- java 8 Lambda表达式(翻译自Stackoverflow)
(原文链接)Lambda只能作用于一个只有一个抽象方法的函数式接口(Function Interface),不过函数式接口可以有任意数量default或static修饰的方法(因此,它们有时也被当做单 ...
- Java 8 Lambda 表达式(一)
Java 8 新特性 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). 使用 Lambda 表 ...
- 聊聊Java 8 Lambda 表达式
早在2014年oracle发布了jdk 8,在里面增加了lambda模块.于是java程序员们又多了一种新的编程方式:函数式编程,也就是lambda表达式.我自己用lambda表达式也差不多快4年 ...
- Java 8 lambda表达式示例
例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...
随机推荐
- list容器排除重复单词的程序
#include<iostream> #include<fstream> #include<string> #include<algorithm> #i ...
- 实验十三 MySQL多用户事务管理
实验十三 MySQL多用户事务管理 一. 实验内容: 1. 事务机制的使用 2. 锁机制的使用 二. 实验项目:员工管理数据库 用于企业管理的员工管理数据库,数据库名为YGGL中,YGGL数据库中 ...
- Rust入坑指南:万物初始
有没有同学记得我们一起挖了多少个坑?嗯-其实我自己也不记得了,今天我们再来挖一个特殊的坑,这个坑可以说是挖到根源了--元编程. 元编程是编程领域的一个重要概念,它允许程序将代码作为数据,在运行时对代码 ...
- 测试Activity和Fragment的生命周期
Activity的生命周期有7个函数,Fragment的生命周期有11个函数. Activity生命周期除上述6个方法还有一个Restart()方法,该方法在该Activity从不可见(仍存在)到重新 ...
- VUE CLI3.0安装及配置
# 安装 npm install -g @vue/cli # 查看已安装版本vue --version 或者 vue -V # 卸载 npm uninstall @vue/cli -g # 新建项目 ...
- LeetCode | 1013. 将数组分成和相等的三个部分
给定一个整数数组 A,只有我们可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false. 形式上,如果我们可以找出索引i+1 < j且满足(A[0] + A[1] + ... ...
- .NET Core项目部署到Linux(Centos7)(四)VMware Workstation虚拟机Centos 7安装
目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...
- iSCSI集群与存储
...
- .net 后台调用前台JS函数
ScriptManager.RegisterStartupScript(this, this.GetType(), "", "<script>alert('上 ...
- Array(数组)对象-->数组长度的获取以及增减
1.数组长度的获取: 属性:length 用法:数组名.length 举例:求一个数组的长度 var arr = [1,2,3,4,5] var arr_length = arr.length con ...