Lombok的@SneakyThrows为何在Lambda表达式上无效

通过还原语法糖 解释为什么 @SneakyThrows 无法对 Lambda 表达式生效

很多人喜欢用 @SneakyThrows 抑制某些方法抛出异常 但是在 Java8 中 Lambda 表达式上发现 这个东西无效了 这是为啥呐

  • 这里用一个简单的 循环处理 URLDecoder.decode 演示一下
  • 第一种 用普通的for循环 可以看到 是有效的

    1
    2
    3
    4
    5
    6
    7
    @SneakyThrows
    public void testNormal() {
    List<String> list = Collections.emptyList();
    for (String o : list) {
    URLDecoder.decode(o, "UTF-8");
    }
    }
  • 然后换为 forEach 发现在 decode 方法上报错了 Unhandled exception: java.io.UnsupportedEncodingException

    1
    2
    3
    4
    5
    @SneakyThrows
    public void testLambda() {
    List<String> list = Collections.emptyList();
    list.forEach(o -> URLDecoder.decode(o, "UTF-8"));
    }
  • 实际上 Lambda 表达式 只是一个语法糖 我们还原一下现场

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @SneakyThrows
    public void testLambda() {
    List<String> list = Collections.emptyList();
    list.forEach(new Consumer<String>() {
    @Override
    @SneakyThrows
    public void accept(String o) {
    URLDecoder.decode(o, "UTF-8");
    }
    });
    }
  • 实际上 他是一个匿名的内部类 方法是没有抛出异常的 所以在方法上加上 @SneakyThrows 就可以正常了

  • 那么 有没有办法在使用 Lambda 的情况下 使用 @SneakyThrows
  • 当然是可以的 我们需要要曲线救国一下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void testLambda() {
    List<String> list = Collections.emptyList();
    list.forEach(o -> decode(o));
    }

    @SneakyThrows
    public String decode(String str) {
    return URLDecoder.decode(str, "UTF-8");
    }