Java使⽤lambda时异常处理问题
⽂章⽬录
问题
在Java中使⽤lambda,我觉得很重要的⼀点就是为了代码的简洁,但是由于Java常⽤的函数式接⼝都没有异常的处理,导致我们必须要try-catch来处理异常,使得代码变得臃肿,违背了初衷。
假设有这⼀个类
public class TestEntity {
private String name;
private int age;
try catch的使用方法
// getter setter and constructors
/**
* 如果name的长度⼩于2,抛出⼀个CheckedException
*/
public void throwCheck()throws IOException {
if(name.length()<2){
throw new IOException();
}
}
/**
* 年龄⼤于22时会触发UnCheckedException
*/
public void throwUnCheck(){
if(age >22){
int i = age /0;
}
}
}
如下例⼦,TestEntity实例的throwCheck()⽅法会抛出⼀个CheckedExcpetion,这个异常我们必须使⽤try-catch处理,否则编译⽆法通过。
public static void main(String[] args){
TestEntity t1 =new TestEntity("mqb",23);
TestEntity t2 =new TestEntity("f",22);
List<TestEntity> list =new ArrayList<>(Arrays.asList(t1, t2));
list.forEach(t->{
try{
t.throwCheck();
}catch(IOException e){
e.printStackTrace();
}
});
}
但是吧,这样写了之后总看的很难受,因为代码由原来的list.forEach(t -> t.throwCheck()); 这样的简洁的⼀⾏,膨胀成这样。特别是如果是在Stream中写多个intermediate operations时,每个都要这样处理异常,就更难受了。如下,随便举个例⼦
list.stream().filter(t ->{
try{
t.throwCheck();
}catch(IOException e){
e.printStackTrace();
}
return true;
}).map(t->{
try{
t.throwCheck();
}catch(IOException e){
e.printStackTrace();
}
return"a";
}).count();
解决办法
经过⼀番百度、google,⽬前主要的解决办法就是⾃⼰重写⼀个函数式接⼝,让此接⼝可以抛出异常,代替原接⼝使⽤。如下是对Consumer接⼝的重写
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception>{
void accept(T t)throws E;
static<T,E extends Exception> Consumer<T>unchecked(ThrowingConsumer<T,E> consumer){
return(t)->{
try{
consumer.accept(t);
}catch(Exception e){
throw new RuntimeException(e);
}
};
}
}
使⽤ ThrowingConsumer.unchecked()⽅法来替代原先的 Consumer接⼝
原先:
list.forEach(t->{
try{
t.throwCheck();
}catch(IOException e){
throw new RuntimeException();
}
});
使⽤ ThrowingConsumer:
list.forEach(ThrowingConsumer.unchecked(TestEntity::throwCheck));

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。