概述
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
英文原文链接
分享到:
相关推荐
Lambda表达式引入了函数式编程思想,使Java开发者能更好地利用函数式编程的优点,如高度抽象、避免副作用等。 总结,Java8的Lambda表达式是现代Java开发的重要工具,它为开发者提供了更灵活、简洁的代码实现方式,...
Lambda表达式是Java 8中的一种语法糖,它允许开发者以更简洁的方式定义无状态、无副作用的函数。在描述中提到的代码示例中,对比了使用匿名类和Lambda表达式实现相同功能的方法。 首先,让我们看看匿名类的使用。在...
函数式编程强调无副作用和纯函数,Lambda表达式是这一思想在Java中的体现。通过避免对状态的修改,可以更容易地理解和测试代码,同时减少并发编程中的错误来源。 6. **方法引用和构造器引用** Lambda表达式还可以...
总之,Lambda表达式是C#中的一个重要特性,它使得代码更加简洁、可读性更强,特别是在处理数据查询和编写无状态、无副作用的函数时。通过Lambda表达式,开发者能够更好地利用函数式编程的思想,提高代码的灵活性和可...
总的来说,Lambda表达式是Python语言的一个强大特性,它提供了简洁的代码表示方式,尤其适用于编写简短、无副作用的函数。然而,过度使用Lambda可能会降低代码的可读性,因此在实际应用中需要权衡简洁性和可维护性。...
它强调无副作用的纯函数,使得代码易于测试和理解,同时也更适合并行处理。Lambda表达式是函数式编程在Java中的一个重要体现,它使得编写高阶函数和回调函数变得更加简单。 在Java中,等待唤醒机制是多线程间协作的...
lambda表达式在这一思想下提供了编写不可变数据和无副作用代码的途径。 7. **Python中的functools模块**:Python标准库中的`functools`模块提供了一些高级函数,如`reduce()`,它接受一个累积函数和一个序列,返回...
2. **避免副作用**:Lambda表达式应当尽量保持为“纯函数”,即不改变外部状态、只依赖于输入值。这样做的好处是可以更容易地推理代码的行为,并且有助于并行执行时避免共享状态的问题。 3. **类型推断**:Java的...
2. **避免过度复杂的捕获**:尽量减少捕获列表中的变量数量,以减少潜在的副作用和复杂性。 3. **利用类型推导**:如果可能,让编译器自动推导返回类型,以减少代码冗余。 总的来说,Lambda表达式为C++提供了更高效...
函数式编程是一种编程范式,它强调将计算视为数学函数的求值,并避免可变状态和副作用。与命令式编程(Imperative Programming)不同,后者注重执行步骤,而函数式编程更关注于“要做什么”,而不是“如何去做”。...
Lambda表达式的主要目的是为了方便地表示无状态、无副作用的功能,通常用于回调、事件处理、集合操作等场景。 1. **Lambda表达式的基本结构** Lambda表达式由三部分组成: - 参数列表:定义了传递给Lambda体的...
首先,Lambda表达式是一种简洁的方式来表示无状态、无副作用的函数。它们可以被赋值给变量、作为参数传递给方法或在方法返回中使用。Lambda的语法结构通常由三部分组成:参数列表、箭头符号(->)和函数体。例如,一...
Java函数式编程,尤其是Lambda表达式,为Java开发者带来了全新的编程范式,使得代码更加简洁、易读且高效。在Java 8及更高版本中,Lambda表达式是函数式编程的核心特性之一,它允许我们将函数作为一等公民,即函数...
函数式编程强调无副作用和纯函数,即函数的输出只依赖于输入,不依赖于程序的其他状态。Java 8中的Lambda表达式和Stream API都深受函数式编程的影响。 9. **实践案例** "Lamda-Practice-main"目录下的源代码文件...
它鼓励使用纯函数,即无副作用且给定相同输入始终返回相同输出的函数。在这个例子中,通过使用Stream API,我们可以避免传统的循环结构,将复杂的逻辑转化为一系列的函数操作,如`filter()`、`map()`和`distinct()`...
6. **函数式编程概念**:介绍函数式编程的一些核心概念,如纯函数、副作用、高阶函数等,以及它们在Java中的应用。 7. **实战示例**:提供实际项目中的Lambda用例,如事件处理、并发编程、数据库操作等。 8. **...
随着Java 8的发布,lambda表达式成为了一个革命性的新特性,极大地改变了Java的编程范式。这本书的目标是帮助开发者利用这一新特性,将函数式编程的思想有效地应用到实际的Java开发中。 在传统的面向过程或面向对象...
纯函数是指函数的输出完全由输入决定,不会产生副作用。高阶函数是指可以接受其他函数作为参数或者返回一个函数的函数。通过这些函数式编程概念,可以提高代码的可读性和模块化,有利于编写出更安全和易于维护的代码...