lambda表达式:变量作用域

时间:2021-01-16 19:13:57

如下代码中的变量count和text,没有在lambda表达式中被定义,而是repeatMessage方法的参数变量

    public void repeatMessage(String text, int count){
        Runnable r = () -> {
            for (int i=0; i<count; i++){
                System.out.println(text);
                Thread.yield();
            }
        };
        new Thread(r).start();
    }

一个lambda表达式包括三部分:

1.一段代码。

2.参数。

3.只有变量的值。(“*”指的是那些不是参数并且没有在代码中定义的变量)


在lambda表达式中,被引用的变量的值不可以被更改,如下代码:

    public void repeatMessage(String text, int count){
        Runnable r = () -> {
            while (count > 0){
                count --; //错误,不能更改
                System.out.println(text);
                Thread.yield();
            };
        };
        new Thread(r).start();
    }
原因:更改lambda表达式中的变量不是线程安全的,自增、自减操作不是原子性的。


内部类也会捕获闭合作用域中的值。在Java8前,内部类只允许访问final的局部变量。为了适应lambda表达式,这条规则现在放宽了。一个内部类可以访问任何有效的final局部变量,即任何值不会发生变化的变量。


在lambda表达式中不允许声明一个与局部变量同名的参数或者局部变量,如下代码:

Path first = Paths.get("/usr/bin");
        Comparator<String> comparator =
                (first, second) -> Integer.compare(first.length(), second.length());
        //错误:变量first已经被定义了

lambda表达式中的this关键字的意义,如下代码:

class Application {
    public void doWork(){
        Runnable runner = () -> {
            System.out.println(this.toString());
        };
    }
}
this.toString()会调用Application对象的toString方法,而不是Runnable实例的toString方法