codingWang / Issue

private space .Do NOT look at it.
3 stars 0 forks source link

basic-java8-05-LambdaScopes #9

Open codingWang opened 7 years ago

codingWang commented 7 years ago

Lambda 作用域

从lambda表达式内部访问外部变量与访问匿名对象非常相似。你可以从本地外部域访问final变量以及实例字段和静态变量

访问本地变量

我们可以从lambda表达式的外部域读final类型的变量

final int num = 1;
Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num);

stringConverter.convert(2);     // 3

与匿名对象不同的是,num无需声明为final下面的代码仍然奏效

int num = 1;
Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num);

stringConverter.convert(2);     // 3

但是,为了能顺利通过编译num必须隐含的声明为final。下面的代码无法编译

int num = 1;
Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num);
num = 3;

在lambda表达式内部给num赋值是禁止的。

访问成员变量和静态变量

相比于本地变量,从lambda表达式内我们既可以读写实例域也可以读写静态变量。这种行为和匿名对象一样。

class Lambda4 {
    static int outerStaticNum;
    int outerNum;

    void testScopes() {
        Converter<Integer, String> stringConverter1 = (from) -> {
            outerNum = 23;                      //!!
            return String.valueOf(from);
        };

        Converter<Integer, String> stringConverter2 = (from) -> {
            outerStaticNum = 72;                //静态变量
            return String.valueOf(from);
        };
    }
}

访问接口的default方法

还记得第一节中关于formula的例子吗?接口Formula定义了一个default类型的方法sqrt。该方法可被每个formula实例访问,包括匿名对象。但这在lambda表达式中不奏效。 default方法无法在lambda表达式内部被访问。下面的例子无法通过编译。

Formula formula = (a) -> sqrt(a * 100);