lambda表达式/闭包 整理

java中lambda表达式【闭包、匿名函数】——一个方法【函数没有名称,匿名函数】,可以赋值给一个变量,那它是什么类型呢?——一个接口【函数式接口,只能有一个函数的接口】
闭包广泛用于回调函数、函数式编程中。
 
当有字段为函数式接口类型时,此字段可以看做是一个方法,此字段实例化时此方法一定是有方法体的【方法体代码就是数据】。
JAVA8中新特性

 闭包,关闭的是什么?

 

Lambda表达式和匿名内部类很像。在IDEA中,写了一个匿名内部类,IDEA会给你提示为替换Lambda表达式,想一想,为什么呢?
 
java有几种内部类【可以访问外部类变量,外部类不能访问内部类,包含关系】

 

  1. 成员内部类【类大括号里边定义的类】
  2. 静态成员内部类【类大括号里边定义的有static的类】
  3. 匿名内部类【直接new并返回的没有名字的内部类,特殊的局部内部类】
  4. 局部内部类【方法中】

 

匿名类和匿名函数的区别 ——一个是类,一个是函数

 

 

 

 

 

 

 

 

示例代码:

public class Test2 {
    private String text = " world";

    public interface IHello {
        void sayHello();
    }

    private void hello() {
      //
        IHello helloAnonymousClass = new IHello() {
            @Override
            public void sayHello() {
                System.out.print(this + " Hello helloAnonymousClass " + text + "\n");
            }
        };
      //函数
        IHello helloAnonymousFunction = () -> {
            System.out.print(this + " Hello helloAnonymousFunction " + text + "\n");
        };

        helloAnonymousClass.sayHello();
        helloAnonymousFunction.sayHello();
    }

    public static void main(String[] args) {
        Test2 test2 = new Test2();
        test2.hello();
        test2.hello();
    }
}
//运行结果

com.road.talk.entity.Test2$1@19bb089b Hello helloAnonymousClass world
com.road.talk.entity.Test2@4563e9ab Hello helloAnonymousFunction world
com.road.talk.entity.Test2$1@11531931 Hello helloAnonymousClass world
com.road.talk.entity.Test2@4563e9ab Hello helloAnonymousFunction world

 

 

 

 

 

局部变量在Lambda中重新赋值,报错

示例:

 

 

 

 

 

 

  

有一个关键:局部变量是final修饰的引用变量则可以修改,只要不是指向新地址即可。就好像final修饰的变量可以再次修改值,但指向该对象或数组的地址的引用不能修改
本质原因:Lambda 是一个方法,在线程中使用,在执行环境中,可能该局部变量已经被回收了,访问的是一个副本,修改副本没什么意义,且这个副本已经有值【局部变量必须初始化】,因此有了这个限制。相当于final修饰的。封闭起来就是闭包的名字由来。

 

Lambda的——方法引用

 示例:

 

 函数式编程的好处——建议阅读阮一峰《函数式编程初探》一文了解学习

 

 

 

 

在Java 8中有一个函数式接口的包,里面定义了大量可能用到的函数式接口(java.util.function (Java Platform SE 8 ))
 

 其他语言关于闭包的东西:

C#建议38:小心闭包中的陷阱【闭包在局部变量声明的地方产生】
闭包——实质在IL中生成了对应的闭包对象【即匿名类,包括局部变量参数,闭包函数】,闭包的对象产生在参数声明的地方。例如:for循环中的变量

 

 

 

 

 

C#闭包——使用声明的委托类型变量接收 lambda表达式。
 
js闭包:
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁
五、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
 
https://blog.csdn.net/xiangang12202/article/details/122916258
posted @ 2023-02-23 15:44  好Wu赖  阅读(134)  评论(0编辑  收藏  举报