Java中的闭包
发布日期:2021-06-30 16:14:26
浏览次数:2
分类:技术文章
本文共 3267 字,大约阅读时间需要 10 分钟。
背景
方法是一堆声明和业务逻辑代码,返回结果给调用者。方法也可以执行特定的逻辑,不返回任何值给调用者。
方法能够复用代码,但是java里面的方法必须属于某个类。
在看闭包之前,我们先复习一下lamada表达式。
lamada表达式是函数式接口的实例。lamda表达式实现了唯一的抽象方法,也就是实现了函数式接口。
如果函数式接口有多个抽象方法定义,就无法用lamada表达式实现多个方法,如下:
函数式接口(functional interface 也叫功能性接口,其实是同一个东西)。简单来说,函数式接口是只包含一个方法的接口。比如Java标准库中的java.lang.Runnable和 java.util.Comparator都是典型的函数式接口。
备注:接口的方法都是抽象的,除非利用default关键字定义方法
interface GreetingService { void sayMessage(String message); default void sayMessage2(String mess){ } }
我们看下面的例子:
package com.java.bitmap;public class Java8Tester { public static void main(String args[]){ Java8Tester tester = new Java8Tester(); // 不用括号 GreetingService greetService1 = message -> System.out.println("Hello " + message); // 用括号 GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("Runoob"); greetService2.sayMessage("Google"); } interface GreetingService { void sayMessage(String message); } }
总结:
- 函数式接口就是仅定义一个抽象方法的接口。
- lamada表达式实现了仅有的抽象方法,也就是实现了函数式接口
lamada表达式作用:
- 能够把方法作为函数参数
- 创建函数不属于任何类
- lamada表达式能够像对象一样传递,按需执行
lamada表达式限制:lamada表达式的引用的外层变量都是final类型,无法改变值,否则会报错。为了解决这个问题,闭包出现了。
闭包
定义
闭包函数:声明在一个函数中的函数,叫做闭包函数。
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
我们来看JS里面的闭包定义,首先看下面的代码:
function init() { var name = 'Mozilla'; // name is a local variable created by init function displayName() { // displayName() is the inner function, a closure alert(name); // use variable declared in the parent function } displayName();}init();
上面代码分析:
- name是init函数的局部变量,displayName方法没有任何变量,但是作为init的内部函数,他可以访问name变量
- 内部函数可以访问外部函数的变量,但是反之,外部函数无法访问内部函数的变量
修改后如下:
function makeFunc() { var name = 'Mozilla'; function displayName() { alert(name); } return displayName;}var myFunc = makeFunc();myFunc();
myFunc
是displayName的引用,在makeFunc执行的时候被创建的- 在makeFunc 执行结束后,我们仍然可以访问name变量,这就是闭包的作用
闭包的作用
- 让外部访问函数内部变量成为可能;
- 局部变量会常驻在内存中;
- 可以避免使用全局变量,防止全局变量污染;
- 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
闭包例子
function funA(){ var a = 10; // funA的活动对象之中; return function(){ //匿名函数的活动对象; alert(a); }}var b = funA();b(); //10
function outerFn(){ var i = 0; function innerFn(){ i++; console.log(i); } return innerFn;}var inner = outerFn(); //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址inner();inner();inner();var inner2 = outerFn();inner2();inner2();inner2(); //1 2 3 1 2 3
var i = 0;function outerFn(){ function innnerFn(){ i++; console.log(i); } return innnerFn;}var inner1 = outerFn();var inner2 = outerFn();inner1();inner2();inner1();inner2(); //1 2 3 4
Java中的闭包实现
(argument_list) -> {func_body}
eeditplay_arrowbrightness_4// Java program to demonstrate // how a closure is implemented // using lambda expressions import java.io.*; // Defining an interface whose // implementation is given in // the lambda expression. // This uses the concept of // closures interface SalutationInterface { public String salHello(); } class GFG { // Driver code public static void main(String[] args) { // Lambda Expression SalutationInterface obj = () -> { return "Hello, GFGians!"; }; // Calling the above interface System.out.println(obj.salHello()); } }
转载地址:https://kerry.blog.csdn.net/article/details/112304888 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月26日 22时18分18秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
logback + Kafka + logstash 集成
2019-05-01
在SpringBoot1.5.x下如何使RedisTokenStore集群化
2019-05-01
Spring Cloud Consul应用下线后,健康检查自动删除无效服务
2019-05-01
spring cloud consul 应用的多实例名的解决
2019-05-01
kafka设置某个topic的数据过期时间
2019-05-01
linux系统编程之信号(五):实时信号与sigqueue函数
2019-05-01
225. 用队列实现栈
2019-05-01
linux系统编程之信号(六):竞态条件与sigsuspend函数
2019-05-01
124. 二叉树中的最大路径和
2019-05-01
LeetCode 148:排序链表 【归并】
2019-05-01
LeetCode 560 和为 k 的子数组
2019-05-01
LeetCode 581 最短无序连续子数组
2019-05-01
Java Stream 使用
2019-05-01
Flink 的DataStream 和 DataSet区别
2019-05-01
Flink源码学习
2019-05-01
MYSQL 表的手动更新统计分析记录
2019-05-01
MYSQL的身体,POSTGRESQL 的头脑
2019-05-01
PostgreSQL 高可用Patroni和学习方法
2019-05-01
业务卡单 与 MongoDB性能记录与分析
2019-05-01