在Java8之前,我们在匿名内部类中如果使用外部局部变量a,那么变量a必须被声明为final的。但从Java8开始,我们不需要再去显示地声明这个局部变量为final了。

同样的代码例子,图一是Java7编译结果,图二是Java8编译结果。


从Java8开始,我们可以在匿名内部类中直接使用非final变量。不过,这样做是有前提的,就是这个局部变量不能被再被重新赋值

如果代码中的变量out重新赋值了,会怎么样呢?

无法通过编译。编译提示:变量out被内部类访问,所以该变量需要定义成final或者是effectively final

所以在这里得出一个结论:在Java8中,内部类访问外部局部变量时,该变量可以不声明为final的。但是,该变量也不能被重新赋值!所以,在Java中内部类要想访问局部变量,这个变量不可变的原则依然有效。只是,从Java8开始,它不要求程序员在每次使用到这些局部变量的时候都去显式声明为final。只要该变量不被重新赋值就好了。

再看编译提示,将变量定义成finaleffectively final。定义成final,可以理解,就是以前的做法,显示定义成final,不准重新赋值,保证变量为常量。那effectively final是什么意思?

effectively final

effectively final其实是Java8引入的新概念。

一个非final的局部变量或方法参数,其值在初始化后就从未更改,那么该变量就是effectively final。这个effectively finallambda表达式上下文中非常有用。

Java8开始,我们可以使用lambda表达式来编程。lambda表达式中,使用局部变量的时候,也要求该变量必须是final的。lambda表达式在我们的编程中是经常使用到的,而匿名内部类是很少使用的。那么,我们在lambda编程中每一个被使用到的局部变量都去显示定义成final吗?显然这不是一个好的方法。所以,Java的设计者们在Java8的版本中,放开了一些限制。

总结一下,规则没有改变,任何局部变量仍然必须是final的才能在lambda表达式或匿名内部类中使用,只是你不再需要使用final关键字,从而节省了一些敲键盘的时间。

Java8 effectively final相关推荐

  1. java增加final,Java8增加功能--Effectively final 功能

    java8新增了很多功能,可以大大简化代码,这个系列将会一一辅助代码加以介绍. 局部内部类和匿名内部类访问的局部变量必须由final修饰,java8开始,可以不加final修饰符,由系统默认添加.ja ...

  2. 1.20 Java8新特性:Effectively final

    Java 中局部内部类和匿名内部类访问的局部变量必须由 final 修饰,以保证内部类和外部类的数据一致性.但从 Java 8 开始,我们可以不加 final 修饰符,由系统默认添加,当然这在 Jav ...

  3. Java8新特性:等同 final 效果(Effectively Final)

    闭包 Effectively Final 示例 闭包 闭包就是能够读取函数作用域之外的变量的函数. 考虑一个返回复杂的 lambda 的高阶函数,使用了函数作用域之外的变量,返回该函数会发生什么? j ...

  4. java 8新特性之effectively final

    我们平时使用内部类时,如果需要使用外部的变量,只能通过final关键字来修饰该变量,在java8中,有了新的处理方式,如下: 针对于jdk1.8,对于一个变量,如果没有给它加final修饰,而且没有对 ...

  5. java中的final关键字和effectively final

    我们在给lamda传参数时,可能会出现如下情况: Variable used in lambda expression should be final or effectively final 一般情 ...

  6. 深入浅出理解 Variable used in lambda expression should be final or effectively final

    翻译:lambda 表达式中使用的变量应该是 final 或者有效的 final 原因解析:lambda表达式(多用在线程领域),是由匿名内部类演变来的. 匿名内部类产生的对象一般存放在JVM的堆区域 ...

  7. foreach无法给外部变量赋值(Local variable decimal defined in an enclosing scope must be final or effectively )

    报错信息如下: Local variable decimal defined in an enclosing scope must be final or effectively final 原因:在 ...

  8. Java8新特性解析

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

  9. Java8学习笔记(1) -- 从函数式接口说起

    转载自   Java8学习笔记(1) -- 从函数式接口说起 希望本文能够成为Java8 Lambda表达式的快速入门指南. 函数式接口 理解Functional Interface(函数式接口,以下 ...

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

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

最新文章

  1. 实时分析态势感知大数据日志
  2. LPC43xx双核笔记
  3. EntityFramework Core 1.1有哪些新特性呢?我们需要知道
  4. java面试题三_最全的java面试题目三
  5. 学习笔记 - Nginx在多层代理下获取真实客户端IP地址
  6. 对于函数式编程的新理解
  7. property自己实现
  8. 计算机术语翻译的最烂,我国计算机名词的翻译现状和建议
  9. Spring4.3.10 集成 Apache CXF 3.3 详细说明
  10. KEIL5下载并安装STM32包
  11. linux系统如何安装bt5,BT5硬盘安装(多系统linux + win + BT5)
  12. 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制
  13. Elasticsearch入门教程(六):Elasticsearch查询(二)
  14. 麻省理工学院赵明民:能穿墙透视的计算机视觉
  15. 联想TinkPad S3-490 后盖拆机教程
  16. 【论文解读--MPC控制】Dynamic Locomotion in the MIT Cheetah 3 Through Convex Model-Predictive Control
  17. 平凡之路 | 科班小硕的2020年面试小结
  18. [软件人生]IT168年会的一点感受——简评专题的内容和说实话的流氓
  19. Android初学习之四:知晓当前是哪一个活动和随时随地退出程序
  20. Sql Server数据库基础教学

热门文章

  1. php进程间通信 yoc_php 进程间通信 ipc
  2. 关于Palantir——第二部分:本体(Ontology)
  3. 计算机科学相关的期刊,计算机类期刊汇总(核心期刊,国家级期刊)
  4. Mysql的分组函数
  5. 三角网格库Triangle的使用
  6. IP地址子网划分基础知识
  7. Codeforces Round #469(Div.1 D) (Div. 2 F)Curfew(贪心)
  8. 计算机主机自动关机如何设置,WinXP电脑怎么设置自动关机?
  9. 7z 头部错误 数据错误_7z解压软件(7-zip)解压错误怎么办?
  10. github注册,使用方法