我在Java 8中使用lambda,我遇到警告,从lambda表达式引用的局部变量必须是final或有效的final。我知道当我在匿名类中使用变量时,它们在外部类中必须是final,但final和有效final之间的区别是什么?
当前回答
如果可以将最后一个修饰符添加到局部变量,那么就是 有效的决赛。
Lambda表达式可以访问
静态变量, 实例变量, 有效的最终 方法参数,以及 有效的最终 局部变量。
来源:OCP: Oracle认证专业Java SE 8程序员II学习指南,Jeanne Boyarsky, Scott Selikoff
此外,
有效最终变量是一个值为never的变量 更改了,但没有使用final关键字声明。
来源:从Java开始:从控制结构到对象(第6版),Tony Gaddis
此外,不要忘记final的含义,它在第一次使用之前只初始化一次。
其他回答
Final是一个用关键字Final声明的变量,示例:
final double pi = 3.14 ;
它在整个程序中都是最终的,在这一行之后改变PI是不允许的。
有效的最终的:任何局部变量或参数,现在只被赋值一次(或只更新一次)。在整个项目中,它可能不是有效的最终结果。这意味着有效最终变量可能会在被分配/更新至少一次赋值后立即失去其有效最终属性。例子:
class EffectivelyFinal {
public static void main(String[] args) {
calculate(124,53);
}
public static void calculate( int operand1, int operand2){
int rem = 0; // operand1, operand2 and rem are effectively final here
rem = operand1%2 // rem lost its effectively final property here because it gets its second assignment
// operand1, operand2 are still effectively final here
class operators{
void setNum(){
operand1 = operand2%2; // operand1 lost its effectively final property here because it gets its second assignment
}
int add(){
return rem + operand2; // does not compile because rem is not effectively final
}
int multiply(){
return rem * operand1; // does not compile because both rem and operand1 are not effectively final
}
}
}
}
effective final变量是一个局部变量,即:
未定义为最终 只分配一次。
final变量是这样的变量:
用final关键字声明。
... 从Java SE 8开始,局部类可以访问封闭块的final或有效final的局部变量和参数。在初始化后值从未改变的变量或参数实际上是final。
例如,假设变量numberLength没有声明为final,并且在PhoneNumber构造函数中添加了标记的赋值语句:
public class OutterClass {
int numberLength; // <== not *final*
class PhoneNumber {
PhoneNumber(String phoneNumber) {
numberLength = 7; // <== assignment to numberLength
String currentNumber = phoneNumber.replaceAll(
regularExpression, "");
if (currentNumber.length() == numberLength)
formattedPhoneNumber = currentNumber;
else
formattedPhoneNumber = null;
}
...
}
...
}
由于这个赋值语句,变量numberLength不再是有效的final。结果,Java编译器生成一个类似于“内部类引用的局部变量必须是final或有效的final”的错误消息,其中内部类PhoneNumber试图访问numberLength变量:
http://codeinventions.blogspot.in/2014/07/difference-between-final-and.html
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
下面这个变量是最终的,所以我们不能改变它的值一旦初始化。如果我们尝试,我们会得到一个编译错误…
final int variable = 123;
但是如果我们创建一个这样的变量,我们可以改变它的值…
int variable = 123;
variable = 456;
但是在Java 8中,默认情况下所有变量都是final。但是代码中第二行的存在使得它不是最终的。因此,如果我们从上面的代码中删除第二行,我们的变量现在是“有效的final”…
int variable = 123;
所以. .任何赋值一次且仅一次的变量都是“有效的最终变量”。
有效的最后一个主题在JLS 4.12.4中进行了描述,最后一段包含了明确的解释:
如果变量实际上是final,在其声明中添加final修饰符将不会引入任何编译时错误。相反,在有效程序中声明为final的局部变量或参数,如果final修饰符被移除,则变为有效的final。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- 在c#中,什么是单子?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder