下面我们来详细地一一介绍下。
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
4
1
2
3
4
5
OK,该方案是可行的。
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
4
1
2
3
4
5
OK,该方案也是可行的。
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
4
1
2
3
4
5
OK,该方案也是可行的。
03、Lambda 和 this 关键字
Lambda 表达式并不会引入新的作用域,这一点和匿名内部类是不同的。也就是说,Lambda 表达式主体内使用的 this 关键字和其所在的类实例相同。
来看下面这个示例。
public class LamadaTest { public static void main(String[] args) { new LamadaTest().work(); } public void work() { System.out.printf("this = %s%n", this); Runnable r = new Runnable() { @Override public void run() { System.out.printf("this = %s%n", this); } }; new Thread(r).start(); new Thread(() -> System.out.printf("this = %s%n", this)).start(); } }
Tips:%s 代表当前位置输出字符串,%n 代表换行符,也可以使用 \n 代替,但 %n 是跨平台的。
work() 方法中的代码可以分为 3 个部分:
1)单独的 this 关键字
System.out.printf("this = %s%n", this);
其中 this 为 main() 方法中通过 new 关键字创建的 LamadaTest 对象——new LamadaTest()。
2)匿名内部类中的 this 关键字
Runnable r = new Runnable() { @Override public void run() { System.out.printf("this = %s%n", this); } };
其中 this 为 work() 方法中通过 new 关键字创建的 Runnable 对象——new Runnable(){...}。
3)Lambda 表达式中的 this 关键字
其中 this 关键字和 1)中的相同。
我们来看一下程序的输出结果:
this = com.cmower.java_demo.journal.LamadaTest@3feba861
this = com.cmower.java_demo.journal.LamadaTest$1@64f033cb
this = com.cmower.java_demo.journal.LamadaTest@3feba861
符合我们分析的预期。
04、最后
尽管 Lambda 表达式在简化 Java 编程方面做了很多令人惊讶的努力,但在某些情况下,不当的使用仍然会导致不必要的混乱,大家伙慎用。
好了,我亲爱的读者朋友们,以上就是本文的全部内容了。能在疫情期间坚持看技术文,二哥必须要伸出大拇指为你点个赞👍。原创不易,如果觉得有点用的话,请不要吝啬你手中点赞的权力——因为这将是我写作的最强动力。