Java8 effectively final

在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关键字,从而节省了一些敲键盘的时间。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值