美文网首页
四、Lambda 访问外部变量及接口默认方法

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

作者: 寂静的春天1988 | 来源:发表于2019-05-09 16:13 被阅读0次
    一、访问局部变量

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

    // 转换器
    @FunctionalInterface
    interface Converter<F, T> {
        T convert(F from);
    }
    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 类型,何为隐式的 final 呢?就是说到编译期为止,num 对象是不能被改变的,如下面这段代码,就不能被编译通过:

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

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

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

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

        @FunctionalInterface
        interface Converter<F, T> {
            T convert(F from);
        }
    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);
                };
            }
        }
    
    三、访问接口的默认方法

    还记得第一章节中定义的那个 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 访问外部变量及接口默认方法

          本文链接:https://www.haomeiwen.com/subject/iyumoqtx.html