• 闭包
  • Effectively Final
  • 示例

闭包

闭包就是能够读取函数作用域之外的变量的函数。

考虑一个返回复杂的 lambda 的高阶函数,使用了函数作用域之外的变量,返回该函数会发生什么?

java支持闭包,即在词法上限定范围(也使用术语“变量捕获”)。如果一个变量拥有独立的生存周期,那么并且不需要任何特殊的捕获。

从 Lambda 表达式引用的 局部变量,必须是 final 或者是等同 final 效果的。

Effectively Final

这个术语是在 Java 8 才开始出现的,表示虽然没有明确地声明变量是 final 的,但是因变量值没被改变过而实际有了 final 同等的效果。

等同 final 效果意味着可以在变量声明前加上 final 关键字而不用更改任何其余代码。

示例

〇:x作为局部变量,只使用其值,是等同 final 效果。 i 作为局部变量,不能改变 i 的值,因为返回函数 “() -> x + i” 后, i 会被释放,不在内存中,无法在调用时进行修改 i 的值。

public class Closure0 {IntSupplier makeFun(int x) {int i = 0;return () -> x + i;}
}

①:x是局部变量,但是等同 final 效果。 i 作为全局变量,可以改变 i 的值,因为调用 makeFun() 时,几乎必定有一个 Closure1 对象,并将现有的函数 “() -> x + i++” 以这种方式绑定到该对象上。因此,多次用同一个对象的 makeFun() 方法返回的函数,都共享一个 i 。

public class Closure1 {int i;IntSupplier makeFun(int x) {return () -> x + i++;}
}

②:使用 final 修饰 x 和 i。

public class Closure2 {IntSupplier makeFun(final int x) {final int i = 0;return () -> x + i;}
}

③:如果 x 和 i 的值在方法中的其他位置发生改变(但不在返回的函数内部),编译器仍将视其为错误。每个递增操作都会产生错误消息,因为不是等同 final 效果。等同 final 效果意味着可以在变量声明前加上 final 关键字而不用更改任何其余代码。

public class Closure3 {IntSupplier makeFun(int x) {int i = 0;i++;x++;return () -> x + i;}
}

④:应用于对象引用的 final 关键字仅表示不会重新赋值引用。 重新赋值引用会触发错误消息,但是它并不代表你不能修改对象本身。如下 ArrayList 对象 list 可以随意增删元素。

public class Closure4 {Supplier<List<Integer>> makeFun() {final List<Integer> list = new ArrayList<>();list.add(1);return () -> list;}public static void main(String[] args) {//makeFun()只返回函数,还需要get()获得函数返回值List<Integer> list = makeFun().get();}
}

⑤:修改对象本身不会报错,但是基本类型的包装类有所不同,编译器非常智能,它能识别引用 i 的值被更改过了。

//编译失败
public class Closure5 {IntSupplier makeFun(int x) {Integer i = 0;i = i + 1;return () -> x + i;}
}

⑥:作为闭包的内部类。实际上只要有内部类,就会有闭包。在内部类中也要遵守——局部变量必须是 final 或者是等同 final 效果的。

public class AnonymousClosure {IntSupplier makeFun(int x) {return new IntSupplier() {public int getAsInt() { return x; }};}
}

Java8新特性:等同 final 效果(Effectively Final)相关推荐

  1. Java8 新特性:Lambda 表达式、方法和构造器引用、Stream API、新时间与日期API、注解

    Java8新特性:Lambda 表达式.方法和构造器引用.Stream API.新时间与日期API.注解 1.Java8新特性 1.1.主要的新特性: 1.2.编程风格 2.Lambda 表达式 2. ...

  2. Java8 新特性之流式数据处理(转)

    转自:https://www.cnblogs.com/shenlanzhizun/p/6027042.html 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作 ...

  3. java8新特性简述

    Java8发布时间是2014年3月19日,距离今日已经很久了,那么Java8新特性你了解吗? java8是Java的一次重大升级,巨大的里程碑式的改进!! Java语言新特性: 1.与传统结合 -- ...

  4. Java8新特性解析

    Java 8中的新特性有: 接口中默认方法,lambda 表达式,方法引用,重复注解,流.函数.接口.map扩展.日期中的新变化等,接下来一一介绍 1. Default Methods for Int ...

  5. 【java8新特性】——lambda表达式与函数式接口详解(一)

    一.简介 java8于2014年发布,相比于java7,java8新增了非常多的特性,如lambda表达式.函数式接口.方法引用.默认方法.新工具(编译工具).Stream API.Date Time ...

  6. Java8新特性之空指针异常的克星Optional类

    Java8新特性系列我们已经介绍了Stream.Lambda表达式.DateTime日期时间处理,最后以"NullPointerException" 的克星Optional类的讲解 ...

  7. java8新特性stream流

    参考自深蓝至尊的Java8 新特性之流式数据处理 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式 ...

  8. 【小家java】java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势

    [小家java]java5新特性(简述十大新特性) 重要一跃 [小家java]java6新特性(简述十大新特性) 鸡肋升级 [小家java]java7新特性(简述八大新特性) 不温不火 [小家java ...

  9. 放大招了,肝了一篇8万字的Java8新特性总结,赶快收藏

    大家好,我是冰河~~ 说实话,肝这篇文章花了我一个月的时间,关于Java8的新特性全在这儿了,建议先收藏后阅读. Java8有哪些新特性? 简单来说,Java8新特性如下所示: Lambda表达式 函 ...

最新文章

  1. 【VB】学生信息管理系统6——错误调试
  2. 将矩阵转为一行_矩阵与矩阵乘积简介
  3. [Hbase]Hbase章2 Hbase读写过程解析
  4. C语言编程规范--常用缩写词
  5. python多版本控制操作方法
  6. 第七章节 类的抽象(抽象类和接口的区别)
  7. Html图片懒加载动画,带加载进度的Web图片懒加载组件Lazyload
  8. Atitit 软件的俩大要点 提升可读性 提升扩展性 目录 1. 命名可读性 1 2. 提升扩展性法 1 3. 项目常见扩展法 2 1.结构可读性 表驱动代替if else 减少层次 Dsl
  9. 传奇开服架设之地图索引编辑器以及安装问题排查教程
  10. 如何使用MATLAB绘制出好看的火山图
  11. Python中的爬虫
  12. 摩斯密码基础知识介绍
  13. Java栈,队列和循环队列的实现
  14. bootstrap3 文件上传插件fileinput中文说明文档
  15. 电脑任务栏卡死,解决办法
  16. UNIX 标准化 --ISO C标准 IEEE POSIX 标准 Single Unix Specification(SUS)
  17. 地图中的矢量POI兴趣点
  18. 钉钉企业内部应用 - 初始化配置
  19. 谁说程序员不懂浪漫,表白代码来啦~
  20. CCF-集合竞价(开盘价定为买价,1e8*5000--long long)

热门文章

  1. 两种方式建立Vsftpd虚拟用户
  2. 「项目管理」如何使用甘特图分解项目?
  3. Unable to negotiate with 192.168.XX.XX port XXXX: no matching key exchange method found.
  4. 内存函数-----Memcmp
  5. html页面字体缩小模糊怎么解决,如何解决网页字体模糊的问题
  6. 微信小程序超级占内存_实测:微信小程序究竟会占用多少内存?结果竟然
  7. 用 Dev-C++ 编写简单的走迷宫小游戏
  8. ndn-tools:dissect-wireshark的使用
  9. 遇到Process finished with exit code -1073740791 (0xC0000409)实在不能解决的时候要注意
  10. 【一起入门NLP】中科院自然语言处理作业五:BiLSTM+Attention实现SemEval-2010 Task 8上的关系抽取(Pytorch)【代码+报告】