资讯专栏INFORMATION COLUMN

认识JDK8新特性之Lambda表达式

awesome23 / 2105人阅读

摘要:说来挺惭愧的,已经出来这么多年,在实际项目中却很少真正使用表达式。举个简单例子对于无参无返回值,可以有如下写法前的一对小括号和后面的一对大括号都不能去掉。表达式不会定义新的作用域表达式的作用域与封闭作用域相同。

说来挺惭愧的,JDK8已经出来这么多年,在实际项目中却很少真正使用Lambda表达式。其实工作中的项目很早就从开发、测试、生产,全面使用JDK8+Tomcat8了。

所以看来是时候要重新认识下这个奇怪的东西。

没错,当第一次看到Lambda表达式时,我就认为这是个奇怪的东西,->写法让我感觉这是在写其它语言,说好的一切皆对象呢?

表达式语法

这是Lambda表达式的基本语法:

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
    statment1;
    statment2;
    //......
    return statmentM;
}

参数列表是一个逗号分隔的形式参数列表,这些参数与功能接口中单一方法的形式参数相对应。指定参数类型是可选项;如果未指定参数类型,将从上下文推断。参数列表必须用括号括起来,但当指定的单一参数不带参数类型时除外;指定单一形式参数时可以不带括号。如果功能接口方法不指定任何形式参数,则必须指定空括号。

语句块必须包含在大括号内,除非语句块是一个方法调用语句。

举个简单例子

对于无参无返回值,可以有如下写法:

public interface TestIntf {
    public void sayHello();
}

// -> 前的一对小括号和后面的一对大括号都不能去掉。
TestIntf intf = () -> {System.out.println("HelloWorld!!!");};
intf.sayHello();

对于有参有返回值,可以有如下写法:

public interface TestIntf {
    public String sayHello(String word);
}

// 完整写法
TestIntf intf = (String word) -> {return "Hello " + word;};

// 参数word的类型可以推断时,可以去掉类型定义:
TestIntf intf = (word) -> {return "Hello " + word;};

// 甚至当参数只有一个时,可以去掉左边的小括号:
TestIntf intf = word -> {return "Hello " + word;};

// 右侧的方法体只有一个表达式时,可以去掉大括号,甚至连return都可以不要:
TestIntf intf = word -> "Hello " + word;
变量作用域

Lambda表达式内部可以访问外部的变量,但需要注意:

局部变量无论是在Lambda表达式主体中声明,还是在封闭作用域中声明,使用之前都必须先初始化。如:

interface TestIntf {
    public String sayHello(String word);
}

public class App {
    public static void main(String[] args) {
        String str;
        TestIntf intf = (String word) -> {
            System.out.println(str); // 编译失败,提示str变量未被初始化。
            return "Hello " + word;
        };
    }
}

Lambda表达式不会定义新的作用域;Lambda表达式的作用域与封闭作用域相同。如:

interface TestIntf {
    public String sayHello(String word);
}

public class App {
    public static void main(String[] args) {
        String str = "word";
        TestIntf intf = (String word) -> {
            String str = ""; // 编译失败,提示str变量重复定义了。
            return "Hello " + word;
        };
    }
}

而且也不能修改外部变量:

interface TestIntf {
    public String sayHello(String word);
}

public class App {
    public static void main(String[] args) {
        String str = "word";
        TestIntf intf = (String word) -> {
            str = "word!!!"; // 编译报错:Local variable str defined in an enclosing scope must be final or effectively final
            return "Hello " + word;
        };
    }
}

当然,引用变量是可以通过内部方法达到数据修改的。

interface TestIntf {
    public String sayHello(StringBuilder word);
}

public class App {
    public static void main(String[] args) {
        StringBuilder str = new StringBuilder("word");
        TestIntf intf = (StringBuilder word) -> {
            word.append("!!!");
            return "Hello " + word;
        };
        System.out.println(intf.sayHello(str)); // Hello word!!!
        System.out.println(str); // word!!!
    }
}
Lambda表达式中的this

在Lambda表达式中this引用的不是Lambda表达式对象,而是声明它的外部对象:

interface TestIntf {
    public String sayHello();
}

public class App {
    
    public void test() {
        TestIntf intf = () -> "Hello " + this.getClass().getSimpleName();
        System.out.println(intf.sayHello());
    }
    
    public static void main(String[] args) {
        App app = new App();
        app.test(); // Hello App
    }
}
参考文章

https://www.oracle.com/techne...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75025.html

相关文章

  • JDK8特性Lambda达式体验

    摘要:的一个大亮点是引入表达式,使用它设计的代码会更加简洁。简介表达式的语法由参数列表箭头符号和函数体组成。表达式示例下面就用一些例子来体验一下表达式。类优惠政策满足的条件,返回接收订单对象,对订单对象进行处理其中接收对象并返回。 Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda...

    curlyCheng 评论0 收藏0
  • 【全栈路】JAVA基础课程十一_JDK8十大特性(20190706v1.2)

    摘要:欢迎进入基础课程博客地址本系列文章将主要针对一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触开发菜鸟还是业界资深人士,都希望对广大同行带来一些帮助。语法是,或者更一般的,要求构造器方法是没有参数静态方法引用。 欢迎进入JAVA基础课程 博客地址:https://blog.csdn.net/houjiyu...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,...

    lcodecorex 评论0 收藏0
  • 【全栈路】JAVA基础课程十一_JDK8十大特性(20190706v1.2)

    摘要:欢迎进入基础课程博客地址本系列文章将主要针对一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触开发菜鸟还是业界资深人士,都希望对广大同行带来一些帮助。语法是,或者更一般的,要求构造器方法是没有参数静态方法引用。 欢迎进入JAVA基础课程 博客地址:https://blog.csdn.net/houjiyu...本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,...

    VPointer 评论0 收藏0
  • 乐字节-Java8特性-Lambda达式

    摘要:很多语言等从设计之初就支持表达式。注意此时外部局部变量将自动变为作为方法返回值例子返回判断字符串是否为空判断字符串是否为空今天关于新特性表达式就讲到这里了,接下来我会继续讲述新特性之函数式接口。 上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式。 Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码...

    gggggggbong 评论0 收藏0
  • 转 | Java8初体验(一)lambda达式语法

    摘要:初体验下面进入本文的正题表达式。接下来展示表达式和其好基友的配合。吐槽一下方法引用表面上看起来方法引用和构造器引用进一步简化了表达式的书写,但是个人觉得这方面没有的下划线语法更加通用。 感谢同事【天锦】的投稿。投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘。因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解偏...

    Lucky_Boy 评论0 收藏0

发表评论

0条评论

awesome23

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<