Java lambda表达式理解
简介
lambda表达式作为java8的新特性,面向函数式编程,使代码更加简洁,同时也提高编程效率;我们作为开发者,不仅要学会用,还要理解其背后的运作原理
lambda一般使用
lambda使用的规则大致为:
( 参 数 ) − > { 代 码 主 体 } (参数) -> \{ 代码主体 \} (参数)−>{代码主体}
左边括号不是必须的,当只有一个参数时可以省略;右侧大括号也不是必须的,如果只有一行代码,可以省略
在MainActivity页面获取权限的小例子:
private void getPermission(){RxPermissions permissions = new RxPermissions(this);permissions.request(Manifest.permission.CAMERA,Manifest.permission.INTERNET,).subscribe(aBoolean -> {if(!aBoolean){Toast.makeText(this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();}});
}
-> 左侧参数aBoolean,右侧是执行的代码主体;
确实比以前代码少了很多,如果按照以前的代码来实现的话,就像下面这样:
.subscribe(new Consumer<Boolean>() {@Overridepublic void accept(Boolean aBoolean) throws Exception {Toast.makeText(MainActivity.this, "....", Toast.LENGTH_SHORT).show();}
});
那这个lambda表达式是如何实现的?
我从逆向的角度来看看,将apk使用apktool工具逆向破解查看其smali代码:
在getPermission方法内:
.method private getPermission()V.locals 4.line 116new-instance v0, Lcom/tbruyelle/rxpermissions2/RxPermissions;invoke-direct {v0, p0}, Lcom/tbruyelle/rxpermissions2/RxPermissions;-><init>(Landroid/support/v4/app/FragmentActivity;)V#部分省略...# 这里new了一个内部类-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIcnew-instance v2, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;invoke-direct {v2, p0}, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;-><init>(Lcom/iot/chinamobile/MainActivity;)V.line 120# 订阅传入了v2,也就是上面创建的内部类invoke-virtual {v1, v2}, Lio/reactivex/Observable;->subscribe(Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable;.line 125return-void
.end method
上面smali代码大致意思是,创建了一个内部类-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc,并且最后这个内部类订阅了权限的监听回调;那我们进入这个内部类看看
.class public final synthetic Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;
.super Ljava/lang/Object;
.source "lambda"# interfaces
//实现了Consumer接口
.implements Lio/reactivex/functions/Consumer;# virtual methods
//重写了accept方法
.method public final accept(Ljava/lang/Object;)V.locals 1iget-object v0, p0, Lcom/iot/chinamobile/-$$Lambda$MainActivity$ccTQ_-iN8ZWh9xOrzs2GmyGpyIc;->f$0:Lcom/iot/chinamobile/MainActivity;check-cast p1, Ljava/lang/Boolean;# 又去掉了MainActivity里面的方法lambda$getPermission$0invoke-static {v0, p1}, Lcom/iot/chinamobile/MainActivity;->lambda$getPermission$0(Lcom/iot/chinamobile/MainActivity;Ljava/lang/Boolean;)Vreturn-void
.end method
上述代码大致意思是在当前内部类实现了Comsumer接口,这也是为什么权限订阅者可以订阅成功原因,最后又回去调用了MainActivity的lambda$getPermission$0方法;这个方法是什么呢?不要怕麻烦,最后一步了,在看看:
也就是java代码的这块:
if(!aBoolean){Toast.makeText(this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();
原理总结
lambda底层实质就是创建了一个内部类,同时在使用lambda表达式的类中生产一个静态方法,这个静态方法就是lambda的代码主题;由生产的内部类在重写接口方法中去调用;而这个内部类就传递给使用lambda的调用者;如下图
以上就是lambda的内部实现原理,其实现手段和第二种自己去new Comsumer一样的;在代码编写程面帮我们减少了很多工作,底层帮我们自动实现;其实比自己去new内部类还多了一个步骤,自己new时,在上图不会有第2步骤,因为会把第2个步骤的方法中代码移动到内部类的accept方法中去,减少一步调用逻辑
最终,如何取舍,仁者见仁,智者见智!
Java lambda表达式理解相关推荐
- Lambda表达式的生动理解以及Java Lambda表达式常见使用场景
本篇承接上一篇 Java Lambda 表达式快速学习 , 对Lambda 表达式的语法格式进行演化说明, 并对Java 中Lambda表达式的常见使用场景进行说明. Lambda 表达式怎么来的? ...
- 深入理解Java Lambda表达式,匿名函数,闭包
前言 对于Lambda表达式一直是知其然不知其所以然,为了搞清楚什么是Lambda表达式,以及Lambda表达式的用法和作用,本文应运而生当做学习笔记分享出来,欢迎指正交流. 什么是Lambda 让我 ...
- Java Lambda表达式的箭头理解总结
Java Lambda表达式的箭头理解总结 文章目录 Java Lambda表达式的箭头理解总结 一.简单的Lambda的基础知识点: 二.Lambda 表达式示例 1.实现方法没有参数,无返回值的情 ...
- Java Lambda表达式初探
前言 本文受启发于Trisha Gee在JavaOne 2016的主题演讲Refactoring to Java 8. Java 8已经发行两年多,但很多人仍然在使用JDK7.对企业来说,技术上谨慎未 ...
- Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记
Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记 根据 JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭包或者匿名函数. ...
- Java——Lambda表达式
目录 lambda表达式 lambda表达式 1.什么是lambda? Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简 ...
- Java Lambda表达式入门 1
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/53930569 文章出自:薛瑄博客 我对Java 8发布非常激动,尤其是lambda ...
- Java Lambda表达式入门
本文转自:http://blog.csdn.net/renfufei... 转载请注明出处 原文链接: Start Using Java Lambda Expressions 下载示例程序 Examp ...
- java拉姆达表达式事例,Java Lambda表达式详解和实例
简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体( ...
最新文章
- 博三才发文章,打破学校零记录,华科博士入职华为年薪201万
- R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(输出多个分组)实战
- 记账本开发进程第一天
- Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 't
- 一篇文章彻底了解清楚什么是负载均衡
- cocos2dx中使用iconv转码(win32,iOS,Android)
- 推销计算机英语作文,如何自我推销英语作文
- Gradle编译spring3.x报错找不到itextpdf4.2.2解决方案
- 计算机投影仪的作用是什么,解开无屏电脑投影仪的神秘面纱,看看可以用它来做什么...
- 电脑运行c语言时错误,电脑出现microsoft visual c++ runtime error 解决方法(多图)
- 【正点原子MP157连载】第二章 STM32MP1简介-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南
- 示波器的实时采样和等效采样
- 表贴电阻尺寸与什么有关_贴片电阻、贴片电容规格、封装、尺寸、功率(转)
- Eclipse中添加外部Web浏览器
- 引爆点---绝对内行
- 基于ThinkPHP的图书馆管理系统 毕业设计-附源码311833
- 用Python带大家写个自动生成艺术签名的小工具哟~
- 一款功能超级强大的AI驱动自动一键抠图软件,可一键扣人物商品衣服动物婚纱图章签名logo
- 设计一个高精度的ADC采样电路思路
- win10进入不了系统修复方法
热门文章
- 平安金融壹帐通面试总结
- 世链投研| Gala Games横空出世,被高赞“做出了链游该有的样子”。
- 学Python不知从何下手?Python技能树助力一臂之力|Python技能树测评
- Prometheus+Springboot2.x实用实战——Timer(一)之@Timed初探
- 自回归滑动平均模型ARMA
- 重写highlighted改变按钮的按下状态、
- 传真服务器进驻主流软件市场
- 看看职业选手如何应对炉石新版本黄金赛
- 第 27 讲 SpringBoot提交表单信息
- 大气 html5 企业网站,高端大气HTML5科技企业网站响应式网站带后台