江门门户网站,lnmp wordpress 后台没有主题,wordpress固定连接静态,英文购物网站建设偶尔#xff0c;我们需要在 Lambda 表达式中修改变量的值#xff0c;但如果直接尝试修改的话#xff0c;编译器不会视而不见听而不闻#xff0c;它会警告我们说#xff1a;“variable used in lambda expression should be final or effectively final”。 这个问题发生的…偶尔我们需要在 Lambda 表达式中修改变量的值但如果直接尝试修改的话编译器不会视而不见听而不闻它会警告我们说“variable used in lambda expression should be final or effectively final”。 这个问题发生的原因是因为 Java 规范中是这样规定的 Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted. 大致的意思就是说Lambda 表达式中要用到的但又未在 Lambda 表达式中声明的变量必须声明为 final 或者是 effectively final否则就会出现编译错误。
关于 final 和 effectively final 的区别可能有些小伙伴不太清楚这里多说两句。
final int a;
a 1;
// a 2;
// 由于 a 是 final 的所以不能被重新赋值int b;
b 1;
// b 此后再未更改
// b 就是 effectively finalint c;
c 1;
// c 先被赋值为 1随后又被重新赋值为 2
c 2;
// c 就不是 effectively final明白了 final 和 effectively final 的区别后我们了解到如果把 limit 定义为 final那就无法在 Lambda 表达式中修改变量的值。那有什么好的解决办法呢既能让编译器不发出警告又能修改变量的值。
思前想后试来试去我终于找到了 3 个可行的解决方案
1把 limit 变量声明为 static。
2把 limit 变量声明为 AtomicInteger。
3使用数组。
下面我们来详细地一一介绍下。
01、把 limit 变量声明为 static
要想把 limit 变量声明为 static就必须将 limit 变量放在 main() 方法外部因为 main() 方法本身是 static 的。完整的代码示例如下所示。
public class ModifyVariable2StaticInsideLambda {static int limit 10;public static void main(String[] args) {Runnable r () - {limit 5;for (int i 0; i limit; i) {System.out.println(i);}};new Thread(r).start();}
}来看一下程序输出的结果
0
1
2
3
4OK该方案是可行的。
02、把 limit 变量声明为 AtomicInteger
AtomicInteger 可以确保 int 值的修改是原子性的可以使用 set() 方法设置一个新的 int 值get() 方法获取当前的 int 值。
public class ModifyVariable2AtomicInsideLambda {public static void main(String[] args) {final AtomicInteger limit new AtomicInteger(10);Runnable r () - {limit.set(5);for (int i 0; i limit.get(); i) {System.out.println(i);}};new Thread(r).start();}
}来看一下程序输出的结果
0
1
2
3
4OK该方案也是可行的。
03、使用数组
使用数组的方式略带一些欺骗的性质在声明数组的时候设置为 final但更改 int 的值时却修改的是数组的一个元素。
public class ModifyVariable2ArrayInsideLambda {public static void main(String[] args) {final int [] limits {10};Runnable r () - {limits[0] 5;for (int i 0; i limits[0]; i) {System.out.println(i);}};new Thread(r).start();}
}来看一下程序输出的结果
0
1
2
3
4OK该方案也是可行的。
04、鸣谢
好了亲爱的读者朋友以上就是本文的全部内容了是不是感觉挺有意思的编译器告诉我们要用 final 修饰 Lambda 表达式外的变量但我们却找到了其他的解决方案还一找就是 3 个是不是感觉技能包又升级了有没有伸出小手给自己点个赞吧。