在java8使用lambda表达式的时候,不可避免的要调用异常处理机制,下面主要记录受检异常与非受检异常在lambda中的处理。
一、非受检异常处理
例子如下所示:
1 public static void testUncheckedException(){ 2 List<Integer> integers = Arrays.asList(5, 10, 11, 32, 40, 60); 3 integers.forEach(i ->{ 4 try { 5 System.out.println(50 / i); 6 } catch (ArithmeticException e) { 7 System.err.println("Arithmetic Exception occurred : " + e.getMessage()); 8 } 9 }); 10 }
编写包装方法来进行处理:
1 /** 2 * @param consumer 接收一个泛型的参数T,然后调用accept,对这个参数做一系列的操作 3 */ 4 private static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) { 5 return i -> { 6 try { 7 System.out.println("accepted value is : "+i); 8 consumer.accept(i); 9 } catch (ArithmeticException e) { 10 System.err.println("Arithmetic Exception occurred : " + e.getMessage()); 11 } 12 }; 13 }
1 public static void testUncheckedException1(){ 2 List<Integer> integers = Arrays.asList(5, 10, 11, 32, 40, 60); 3 integers.forEach(lambdaWrapper(i-> System.out.println(50/i))); 4 }
对方法加以改进并对异常进行抛出:
1 private static <T, E extends Exception> Consumer<T> consumerWrapper(Consumer<T> consumer, Class<E> clazz) { 2 return i -> { 3 try { 4 consumer.accept(i); 5 } catch (Exception e) { 6 try { 7 E eCast = clazz.cast(e); 8 System.err.println("Exception occurred : " + eCast.getMessage()); 9 } catch (ClassCastException ccEx) { 10 throw e; 11 } 12 } 13 }; 14 }
1 public static void testUncheckedException2(){ 2 List<Integer> integers = Arrays.asList(5, 10, 11, 32, 40, 60); 3 integers.forEach( 4 consumerWrapper( 5 i -> System.out.println(50 / i), 6 ArithmeticException.class)); 7 }
二、受检异常处理
例子如下所示:
1 private static void writeToFile(String string) throws IOException { 2 File file = new File("c:/newfile.txt"); 3 4 try (FileOutputStream fop = new FileOutputStream(file)) { 5 6 if (!file.exists()) { 7 file.createNewFile(); 8 } 9 10 byte[] contentInBytes = string.getBytes(); 11 12 fop.write(contentInBytes); 13 fop.flush(); 14 fop.close(); 15 16 System.out.println("Done"); 17 18 } 19 } 20 21 public static void testCheckedException(){ 22 List<String> integers = Arrays.asList("3", "9", "7", "0", "10", "20"); 23 integers.forEach(i -> { 24 try { 25 writeToFile(i); 26 } catch (IOException e) { 27 throw new RuntimeException(e); 28 } 29 }); 30 }
可以首先编写一个可以抛出异常的函数式接口:
1 @FunctionalInterface 2 public interface ThrowingConsumer<T, E extends Exception> { 3 void accept(T t) throws E; 4 }
1 private static <T> Consumer<T> throwingConsumerWrapper(ThrowingConsumer<T, Exception> throwingConsumer) { 2 return i -> { 3 try { 4 throwingConsumer.accept(i); 5 } catch (Exception e) { 6 throw new RuntimeException(e); 7 } 8 }; 9 } 10 11 public static void testCheckedException1(){ 12 List<String> stringS = Arrays.asList("3", "9", "7", "0", "10", "20"); 13 stringS.forEach(throwingConsumerWrapper(ExceptionHandler::writeToFile)); 14 }
进行优化改造:
1 private static <T, E extends Exception> Consumer<T> handlingConsumerWrapper( 2 ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) { 3 return i -> { 4 try { 5 throwingConsumer.accept(i); 6 } catch (Exception ex) { 7 try { 8 E exCast = exceptionClass.cast(ex); 9 System.err.println("Exception occurred : " + exCast.getMessage()); 10 } catch (ClassCastException ccEx) { 11 throw new RuntimeException(ex); 12 } 13 } 14 }; 15 } 16 17 public static void testCheckedException2(){ 18 List<String> stringList = Arrays.asList("3", "9", "7", "0", "10", "20"); 19 stringList.forEach(handlingConsumerWrapper(ExceptionHandler::writeToFile, IOException.class)); 20 }