λ 表达式中的异常处理



如果函数抛出已检查异常,则很难编写 λ 表达式。请看以下示例 −

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.stream.Collectors;

public class FunctionTester {
   public static void main(String[] args) {
      String url = "www.google.com";
      System.out.println(encodedAddress(url));
   }   

   public static String encodedAddress(String... address) {
      return Arrays.stream(address)
         .map(s -> URLEncoder.encode(s, "UTF-8"))
         .collect(Collectors.joining(","));
   }
}

上面的代码无法编译,因为 URLEncode.encode() 会抛出 UnsupportedEncodingException,但 encodeAddress() 方法不能抛出此异常。

一种可能的解决方案是将 URLEncoder.encode() 提取到一个独立的方法中并在那里处理异常。

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.stream.Collectors;

public class FunctionTester {
   public static void main(String[] args) {
      String url = "www.google.com";       
      System.out.println(encodedAddress(url));
   }   

   public static String encodedString(String s) {
      try {
         URLEncoder.encode(s, "UTF-8");
      }
      catch (UnsupportedEncodingException e) {        
         e.printStackTrace();
      }
      return s;
   }

   public static String encodedAddress(String... address) {
      return Arrays.stream(address)
         .map(s -> encodedString(s))
         .collect(Collectors.joining(","));
   }   
}

但是,如果我们有可能会抛出异常的多个此类方法,那么上述方法就不好了。请看以下使用函数式接口和包装器方法的泛化解决方案。

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FunctionTester {
   public static void main(String[] args) {
      String url = "www.google.com";       
      System.out.println(encodedAddress(url));
   }   
   public static String encodedAddress(String... address) {
      return Arrays.stream(address)
         .map(wrapper(s -> URLEncoder.encode(s, "UTF-8")))
         .collect(Collectors.joining(","));
   }

   private static <T, R, E extends Exception> Function<T, R> 
   wrapper(FunctionWithThrows<T, R, E> fe) {
      return arg -> {
         try {
            return fe.apply(arg);
         } catch (Exception e) {
            throw new RuntimeException(e);
         }
      };
   }
}

@FunctionalInterface
interface FunctionWithThrows<T, R, E extends Exception> {
   R apply(T t) throws E;
}

输出

www.google.com
广告