λ和副作用

总览

Java 8添加了诸如lambda和类型推断之类的功能。 这使语言不那么冗长和简洁,但是它带来了更多的副作用,因为您不必对所做的事情那么明确。

Lambda的返回类型很重要

Java 8推断闭包的类型。 一种方法是查看返回类型(或是否返回任何内容)。 这可能会产生令人惊讶的副作用。 考虑下面的代码。

es.submit(() -> {
    try(Scanner scanner = new Scanner(new FileReader("file.txt"))) {
        String line = scanner.nextLine();
        process(line);
    }
    return null;
});

此代码可以正常编译。 但是,该行返回null; 似乎是多余的,您可能很想删除它。 但是,如果删除该行,则会出现错误。

Error:(12, 39) java: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown

这是在抱怨FileReader的使用。 返回null与捕获未捕获的异常有什么关系!

类型推断

ExecutorService.submit()是一个重载方法。 它有两种采用一个参数的方法。

这两种方法都没有参数,那么javac编译器如何推断lambda的类型? 它查看返回类型。 如果返回null; 它是Callable <Void>,但是如果不返回任何内容(甚至不返回null),则它是aRunnable。

Callable和Runnable具有另一个重要区别。 Callable引发检查异常,但是Runnable不允许引发检查异常。

返回null的副作用是您不必处理已检查的异常,这些异常将存储在Future <Void> Submit()返回中。 如果不返回任何内容,则必须处理已检查的异常。

结论

尽管lambda和类型推断会删除大量的样板代码,但您会发现更多的边缘情况,在这种情况下,编译器推断的隐藏细节可能会有些混乱。

脚注

您可以使用类型转换明确说明类型推断。 考虑一下:

Callable<Integer> calls = (Callable<Integer> & Serializable) () -> { return null; }
if (calls instanceof Serializable) // is true

这种石膏有许多副作用。 不仅call()方法返回一个Integer并且添加了标记接口,为lambda生成的代码也发生了变化,即,它添加了writeObject()和readObject()方法来支持lambda的序列化。

注意:每个调用站点都会创建一个新类,这意味着此转换的详细信息在运行时通过反射可见。

翻译自: https://www.javacodegeeks.com/2014/09/lambdas-and-side-effects.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值