jdk1.8新特性之lambda表达式(二):调用外部变量

940 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

上篇文章讲了如何使用lambda表达式实现函数式接口,lambda表达式除了可以实现函数式接口,还可以调用外部变量。但是,这些外部变量有些可以被更改,有些则不能。例如,lambda表达式无法更改局部变量的值,但是却可以更改外部类成员变量的值。

1、无法更改局部变量

局部变量在lambda表达式中默认被定义为final(静态)的,也就是说,lambda表达式只能调用局部变量,却不能改变其值,如:

public interface VariableInterface1{
    void method();
}

public class VariableDemo1{
    public static void main(String[] args){
        int value = 100;
        VariableInterface1 v = ()->{
            int num = value - 90;
            value = 12;
        };
    }
}

在idea中编写玩这段代码后,会看到更改局部变量相关代码被标注编译错误,错误提示如图:

image.png 如上图所示,错误提示表示局部变量在lambda表达式中是以final形式存在的,所以无法获取到并修改。

2、可以更改类成员变量

类成员变量是在lambda表达式中不是被final修饰的,所以lambda表达式可以更改其值。如:

public interface VariableInterface2{
    void method();
}

public class VariableDemo2{
    int value = 100;
    public void action(){
        VariableInterface2 v=()->{
            value = -12;
        };
        System.out.println("运行接口方法前value="+value);
        v.method();
        System.out.println("运行接口方法后value="+value);
    }
    
    public static void main(String[] args){
        VariableDemo2 demo = new VariableDemo2();
        demo.action();
    }
}

运行结果如下:

image.png

可以看到,value的值确实被lambda表达式更改了,这就证明,value这个不被final修饰的成员变量的值,可以被lambda表达式更改值。lambada表达式只是描述了抽象方法是如何实现的,在抽象方法没有调用前,lambda表达式中的代码并没有被执行,所以运行抽象方法之前,类成员变量的值没有发生变化。只要抽象方法被调用,类成员变量的值就被更改了。

总结

lambda表达式无法更改局部变量的值,但可以更改类成员变量的值,是因为,局部变量在lambda表达式中默认被定义为final(静态)的,而成员变量在lambda表达式中定义的不是final修饰的,所以可以修改类成员变量的值而不能修改局部变量的值。