在Java中应用函数式编程请小心!
2019独角兽企业重金招聘Python工程师标准>>>
这并不是要对令人畏惧的函数式编程进行谴责,而是对编程中很容易发生的一些错误进行警醒。
高阶函数是函数式编程的关键,因此,谈论它们会帮助你在派对上成为关注的焦点。
如果你正在写 JavaScript ,实际上一直在做的就是高阶函数。例如:
1 2 3 |
|
上面的 setTimeout() 函数就是一个高阶函数。它的参数是一个匿名函数。10秒后,它将会用这个匿名函数作为参数来调用。
我们可以编写另一个简单的高阶函数,作为结果提供给上面的函数:
1 2 3 4 5 6 7 |
|
如果运行上面的程序,将会执行message() 函数,并返回一个匿名函数,这个匿名函数将会输出传递给 message() 函数的text参数。
在函数式编程中,上面是很常见的做法。由高阶函数返回的函数被调用时,将会捕捉外部作用域,并且能够在这个作用域上进行操作。
为什么在 Java 中这种做法很危险?
出于同样的原因。高阶函数(方法)返回的函数(lambda函数)被调用的时候,会捕捉外部作用域,并且能够在这个作用域上进行操作。
这里给出一个最简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
在上面的逻辑中,如果在 runnable.run() 方法调用处做一个断点,可以看到在堆栈上无害的lambda实例。生成的一个简单类,提供了函数式接口的实现:
现在,把这个例子转换成普通的企业应用程序(注意注解)。为了方便博客的书写,我们做了很大的简化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
断点仍放在原来的地方。那么我们在堆栈中又能看到什么呢?
仍然是一个无害的lambda实例:
好吧,为了调试,我们现在添加一些日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
哦哦!
意外地,一个毫无影响的 this 引用强迫Java 编译器封装返回的Runnable 类中 EnterpriseBean 的外部类实例:
而且,同时返回的还有 enterpriseStateObject 。这个对象现在不会被垃圾回收,直到调用点释放 Runnable后才会释放。
好吧,现在这并不是什么新鲜事,不是吗?
确实,这并不是什么新鲜事。Java 8 没有一流的函数,没关系。通过虚拟的 SAM 类型支持匿名表达式的想法就相当的巧妙,因为在 Java系统中它允许对所有现有的库更新和lambda-y-fy而并不改变它们。
而且,用一个匿名类,这整件事情就不会那么令人惊讶了。由于良好的Swing 1.0风格ActionListener等,下面的编码风格通过内部类已经暴露了内部的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
这里有什么心东西?匿名风格会鼓励在 Java 中所有地方使用高阶函数。一般情况下是挺好的。但是,仅仅当高阶函数是一个静态方法时,其产生的类型不会封装任何状态。
然而,通过上面的例子,我们可以看到,在不久的将来,当我们开始拥抱 Java 8 函数式编程风格时,我们在调试过程中将会时不时碰到一些内存泄露等问题。
所以,请谨慎使用并遵循以下规则:
1 |
|
延伸阅读
以前封闭实例(enclosing instance)会出现一些问题。可以解了一下可怕的双花括号反模式在前20年是怎么给Java开发者带来痛苦和磨难的。
原文链接: jaxenter 翻译: ImportNew.com - santhy
译文链接: http://www.importnew.com/17292.html
[ 转载请保留原文出处、译者和译文链接。]
转载于:https://my.oschina.net/newchaos/blog/1648816
在Java中应用函数式编程请小心!相关推荐
- Java 中的函数式编程
1. 概述 在本教程中,我们将了解函数式编程范式的核心原则以及如何在 Java 编程语言中使用它们. 我们还将介绍一些高级函数式编程技术.这将帮助我们了解 Java 中的函数式编程的好处. 2. 什么 ...
- c++返回指针时候注意提防_提防Java中的函数式编程!
c++返回指针时候注意提防 这对函数式编程并不会造成太大的影响,这真棒. 这是关于某些实践的警告,您很可能会将其应用于您的代码,而这是完全错误的! . 高阶函数对于函数式编程是必不可少的,因此,谈论它 ...
- 提防Java中的函数式编程!
这对函数式编程并不会造成太大的影响,这真棒. 这是关于某些实践的警告,您很可能会将其应用于您的代码,而这完全是错误的! . 高阶函数对于函数式编程是必不可少的,因此,谈论它们将帮助您成为聚会中的焦点. ...
- 这个类库可以帮助你理解Java中的函数式编程
每当JDK发布了新版本就有同学说"你发任你发,我用Java 8",可在工作中有不少人依然不太擅长使用Java8的新特性,而这些特性往往让Java不再"臃肿".不 ...
- Java中的函数式编程(二)函数式接口Functional Interface
写在前面 前面说过,判断一门语言是否支持函数式编程,一个重要的判断标准就是:它是否将函数看做是"第一等公民(first-class citizens)". 函数是"第一等 ...
- java函数式编程入口_Java中的函数式编程
前言 JDK8引入的Lambda表达式和Stream为Java平台提供了函数式编程的支持,极大地提高了开发效率.本文结合网络资源和自身使用经验,介绍下Java中的函数式编程 Java中的函数式编程 出 ...
- 用通俗易懂的大白话搞明白Java里的函数式编程和Lambda表达式
今天,用通俗易懂的大白话来彻底搞明白Java里的函数式编程和Lambda表达式 为什么引入函数式编程,lambda表达式? 大家都知道,JDK1.8引入了函数式编程,lambda表达式. 那有没有想过 ...
- 【Java】23 函数式编程
函数式接口(Functional Interface)是 JDK 1.8 对一类特殊类型的接口的称呼. 这类接口有且仅有一个抽象方法,并且这类接口使用了 @FunctionalInterface 进行 ...
- wpf绑定 dictionary 给定关键字不再字典中_为什么要在 JavaScript 中学习函数式编程?...
请忘掉你认为你知道的有关 JavaScript 的任何东西,以初学者心态来接触这份资料. 为帮助你这样做,我们打算从头开始复习 JavaScript 的基础知识, 就好像你以前从来没有看到过 Java ...
最新文章
- 数据结构 - 静态单链表的实行(C语言)
- Shiro + JWT + Spring Boot Restful 简易教程
- OpenCV学习笔记十一-findcounters函数
- 收到一个机器人txt微盘_经阁-第一章 吞了个机器人-爱阅小说网
- 以太坊PoA共识引擎算法介绍(1)
- windows 10 应用商店无法下载安装应用的解决
- 无线ap ntp服务器,我有一优科 ZoneFlex 7982 的无线AP,怎样可以进AP系统进行设置...
- Delta对冲:模拟实验
- elementUI中upload上传组件点击上传按钮,选择文件框弹出前进行提示点击确定则继续弹框选择文件上传
- 开源爱好者李涛:三人行必有我师
- git中提交显示!rejected,如何解决?
- RSA加密解密及制作软件license
- excel表格筛选某一列重复数据
- Hello, CTF WP
- Flink任务失败,检查点失效:Exceeded checkpoint tolerable failure threshold.
- 【本人秃顶程序员】求求你别再写 bug 了,秃顶程序员告诉你避免空指针的 5 个案例!
- Jstate JVM分析
- 用Chrome浏览器模拟手机,andriord,iphone,ipad访问网站
- ASP.NET 缓存技术(一)——启用页面输出缓存
- 安霸入伙,“开放视觉”ADAS 俱乐部再迎新成员