四、Lambda 访问外部变量及接口默认方法

一、访问局部变量

在 Lambda 表达式中,我们可以访问外部的 final 类型变量,如下面的示例代码:

// 转换器
@FunctionalInterface
interface Converter {
    T convert(F from);
}
final int num = 1;
Converter stringConverter =
        (from) -> String.valueOf(from + num);

stringConverter.convert(2);     // 3

与匿名内部类不同的是,我们不必显式声明 num 变量为 final 类型,下面这段代码同样有效:

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

stringConverter.convert(2);     // 3

但是 num 变量必须为隐式的 final 类型,何为隐式的 final 呢?就是说到编译期为止,num 对象是不能被改变的,如下面这段代码,就不能被编译通过:

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

在 lambda 表达式内部改变 num 值同样编译不通过,需要注意, 比如下面的示例代码:

int num = 1;
Converter converter = (from) -> {
    String value = String.valueOf(from + num);
    num = 3;
    return value;
};
二、访问成员变量和静态变量

与局部变量相比,在 Lambda 表达式中对成员变量和静态变量拥有读写权限:

    @FunctionalInterface
    interface Converter {
        T convert(F from);
    }
class Lambda4 {
        // 静态变量
        static int outerStaticNum;
        // 成员变量
        int outerNum;

        void testScopes() {
            Converter stringConverter1 = (from) -> {
                // 对成员变量赋值
                outerNum = 23;
                return String.valueOf(from);
            };

            Converter stringConverter2 = (from) -> {
                // 对静态变量赋值
                outerStaticNum = 72;
                return String.valueOf(from);
            };
        }
    }
三、访问接口的默认方法

还记得第一章节中定义的那个 Formula (公式) 接口吗?

@FunctionalInterface
interface Formula {
    // 计算
    double calculate(int a);

    // 求平方根
    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}

当时,我们在接口中定义了一个带有默认实现的 sqrt 求平方根方法,在匿名内部类中我们可以很方便的访问此方法:

Formula formula = new Formula() {
    @Override
    public double calculate(int a) {
        return sqrt(a * 100);
    }
};

但是在 lambda 表达式中可不行:

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

带有默认实现的接口方法,是不能在 lambda 表达式中访问的,上面这段代码将无法被编译通过。

你可能感兴趣的:(四、Lambda 访问外部变量及接口默认方法)