`
deepinmind
  • 浏览: 451527 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:41627
社区版块
存档分类
最新评论

lambda表达式的副作用

阅读更多
概述

Java 8添加了lambda表达式及类型推导的特性。这使得语言更加简练和整洁,然而正因这样,你没有明确说明自己究竟要做什么,这也带来了一些副作用。

lambda表达式的返回值很重要

Java 8会去推导闭包的类型。推导的一个方式就是去查看它的返回值(或者是否有返回值)。而这带来的副作用令人咋舌。看下这段代码。




ExecutorService es = Executors.newSingleThreadExecutor();

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



这段代码能够通过编译。然而,return null的这行,显得有些多余,你可能会想把它删掉。然而一旦你删掉了这行,它就会报错了。



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





这是使用FileReader的时候在报错。return null和捕获这个异常到底有什么关系?

类型推导

ExecutorService.submit()是一个重载的方法。它有两个带单个参数的方法。

ExecutorService.submit(Runnable runnable);

ExecutorService.submit(Callable callable);

这些方法都不带参数,那么javac编译器如何能推导出lambda表达式的类型?它看的是返回值。如果你返回null,那就是Callable<Void>,然而如果不返回值,连null都没有了,那就是Runnble。

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表达式的序列化。

注意:每个调用点都会生成一个新类,也就是说通过反射这个转换的细节是运行时可见的。




原创文章转载请注明出处:http://it.deepinmind.com




英文原文链接
1
0
分享到:
评论

相关推荐

    Java8的lambda表达式

    Lambda表达式引入了函数式编程思想,使Java开发者能更好地利用函数式编程的优点,如高度抽象、避免副作用等。 总结,Java8的Lambda表达式是现代Java开发的重要工具,它为开发者提供了更灵活、简洁的代码实现方式,...

    JavaLambda表达式和匿名类.pdf

    Lambda表达式是Java 8中的一种语法糖,它允许开发者以更简洁的方式定义无状态、无副作用的函数。在描述中提到的代码示例中,对比了使用匿名类和Lambda表达式实现相同功能的方法。 首先,让我们看看匿名类的使用。在...

    精通lambda表达式: java多核编程

    函数式编程强调无副作用和纯函数,Lambda表达式是这一思想在Java中的体现。通过避免对状态的修改,可以更容易地理解和测试代码,同时减少并发编程中的错误来源。 6. **方法引用和构造器引用** Lambda表达式还可以...

    Lambda 表达式

    总之,Lambda表达式是C#中的一个重要特性,它使得代码更加简洁、可读性更强,特别是在处理数据查询和编写无状态、无副作用的函数时。通过Lambda表达式,开发者能够更好地利用函数式编程的思想,提高代码的灵活性和可...

    python之lambda表达式.pdf

    总的来说,Lambda表达式是Python语言的一个强大特性,它提供了简洁的代码表示方式,尤其适用于编写简短、无副作用的函数。然而,过度使用Lambda可能会降低代码的可读性,因此在实际应用中需要权衡简洁性和可维护性。...

    Java基础知识-day07【线程池、Lambda表达式】.pdf

    它强调无副作用的纯函数,使得代码易于测试和理解,同时也更适合并行处理。Lambda表达式是函数式编程在Java中的一个重要体现,它使得编写高阶函数和回调函数变得更加简单。 在Java中,等待唤醒机制是多线程间协作的...

    Python代码源码-实操案例-框架案例-利用lambda表达式简化编程.zip

    lambda表达式在这一思想下提供了编写不可变数据和无副作用代码的途径。 7. **Python中的functools模块**:Python标准库中的`functools`模块提供了一些高级函数,如`reduce()`,它接受一个累积函数和一个序列,返回...

    Stream和Lambda表达式最佳实践

    2. **避免副作用**:Lambda表达式应当尽量保持为“纯函数”,即不改变外部状态、只依赖于输入值。这样做的好处是可以更容易地推理代码的行为,并且有助于并行执行时避免共享状态的问题。 3. **类型推断**:Java的...

    C++ 中的Lambda表达式写法

    2. **避免过度复杂的捕获**:尽量减少捕获列表中的变量数量,以减少潜在的副作用和复杂性。 3. **利用类型推导**:如果可能,让编译器自动推导返回类型,以减少代码冗余。 总的来说,Lambda表达式为C++提供了更高效...

    0202年了,还没有用上Java函数式编程!!!——Lambda表达式

    函数式编程是一种编程范式,它强调将计算视为数学函数的求值,并避免可变状态和副作用。与命令式编程(Imperative Programming)不同,后者注重执行步骤,而函数式编程更关注于“要做什么”,而不是“如何去做”。...

    深入学习 Java 中的 Lambda

    Lambda表达式的主要目的是为了方便地表示无状态、无副作用的功能,通常用于回调、事件处理、集合操作等场景。 1. **Lambda表达式的基本结构** Lambda表达式由三部分组成: - 参数列表:定义了传递给Lambda体的...

    java lambda入门

    首先,Lambda表达式是一种简洁的方式来表示无状态、无副作用的函数。它们可以被赋值给变量、作为参数传递给方法或在方法返回中使用。Lambda的语法结构通常由三部分组成:参数列表、箭头符号(-&gt;)和函数体。例如,一...

    Java函数式编程(一):你好,Lambda表达式

    Java函数式编程,尤其是Lambda表达式,为Java开发者带来了全新的编程范式,使得代码更加简洁、易读且高效。在Java 8及更高版本中,Lambda表达式是函数式编程的核心特性之一,它允许我们将函数作为一等公民,即函数...

    Lamda-Practice:Java 8 lambda表达式和功能接口的实践

    函数式编程强调无副作用和纯函数,即函数的输出只依赖于输入,不依赖于程序的其他状态。Java 8中的Lambda表达式和Stream API都深受函数式编程的影响。 9. **实践案例** "Lamda-Practice-main"目录下的源代码文件...

    jdk8函数式编程学习和复习必备

    它鼓励使用纯函数,即无副作用且给定相同输入始终返回相同输出的函数。在这个例子中,通过使用Stream API,我们可以避免传统的循环结构,将复杂的逻辑转化为一系列的函数操作,如`filter()`、`map()`和`distinct()`...

    Java_Bambdas收集打嗝套件专业和社区.zip

    6. **函数式编程概念**:介绍函数式编程的一些核心概念,如纯函数、副作用、高阶函数等,以及它们在Java中的应用。 7. **实战示例**:提供实际项目中的Lambda用例,如事件处理、并发编程、数据库操作等。 8. **...

    lambda Functional_Programming.pdf

    随着Java 8的发布,lambda表达式成为了一个革命性的新特性,极大地改变了Java的编程范式。这本书的目标是帮助开发者利用这一新特性,将函数式编程的思想有效地应用到实际的Java开发中。 在传统的面向过程或面向对象...

    Functional Programming in Java

    纯函数是指函数的输出完全由输入决定,不会产生副作用。高阶函数是指可以接受其他函数作为参数或者返回一个函数的函数。通过这些函数式编程概念,可以提高代码的可读性和模块化,有利于编写出更安全和易于维护的代码...

Global site tag (gtag.js) - Google Analytics