Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Kotlin | 浅谈 Reified 与泛型 的三两事

Kotlin | 浅谈 Reified 与泛型 的三两事

作者头像
Petterp
发布于 2022-09-28 01:41:48
发布于 2022-09-28 01:41:48
56800
代码可运行
举报
文章被收录于专栏:JetPackJetPack
运行总次数:0
代码可运行

背景

在业务中,或者要写某个技术组件时,我们无可避免会经常使用到 泛型 ,从而让代码更具复用性与健壮性。

但相应的,由于Java泛型存在 类型擦除 的实现机制,所以某些情况下就会显得力不从心。而在 Kotlin 中,由于最终也会被编译为java字节码,所以无可避免也存在这上述问题🙂。

什么是类型擦除?

如下例所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Class c1=new ArrayList<Integer>().getClass();
Class c2=new ArrayList<String>().getClass();
// 输出为true
System.out.println(c1==c2);

上述输出结果为什么会true呢?

因为泛型从底层上说是一种语法糖,它只存在于 编译期 。在代码运行期间,jvm会将泛型的相关信息擦除,成功编译后的 class文件 不会包含任何泛型信息。所以在运行时,c1与c2存储的类型都为Object,而 Integer 与 String 已经被擦除。

正是由于类型被擦除,所以就导致一些相关问题,比如不安全的类型转换,模版方法的增多等。

比如下面例子所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ArrayList list = new ArrayList();
list.add(1);
list.add("@");

reified

为了解决上述类型擦除问题,以及更好的使用体验。Kotlin 中存在名为 reified 的关键字,它可以被作用于函数上, 以此做到类型擦除后的再生,便于开发者优雅的使用泛型以及获取方法的泛型类型。

Java 中,如果我们要获取函数的泛型类型,一般会通过给函数中传递类型参数的方式,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public <T extends Activity> void startActivity(Context context, Class<T> c) {
     context.startActivity(new Intent(context, c));
 }

如果上述代码使用 kotlin 来写呢?如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline fun <reified C : Activity> Context.startActivityKtx() {
    startActivity(Intent(this, C::class.java))
}

我们利用 扩展函数 + reified 关键字的方式,减少了模版代码,增强了使用体验。 从而让本该在编译阶段被擦除的Activity类型,能够在运行时获取到。

但需要注意的是,reified 关键字必须和 inline 关键字一起使用(下面会提到为什么)。

inline 关键字是什么呢?

简单理解为:当一个函数被标记为 inline 时,kotlin编译器 会在所有调用这个函数的位置,将方法函数替换为具体的函数体。

解析

通过查看 kotlin 字节码,我们可以得知 reified 的底层实现。

例如下面示例与其对应的字节码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline fun <reified C : Activity> Context.toAct() {
    startActivity(Intent(this, C::class.java))
}

fun test(context: Context) {
    context.toAct<MainActivity>()
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// $FF: synthetic method
public static final void toAct(Context $this$toAct) {
   int $i$f$toAct = 0;
   Intrinsics.checkNotNullParameter($this$toAct, "$this$toAct");
   Intrinsics.reifiedOperationMarker(4, "C");
   $this$toAct.startActivity(new Intent($this$toAct, Activity.class));
}

public static final void test(@NotNull Context context) {
   Intrinsics.checkNotNullParameter(context, "context");
   int $i$f$toAct = false;
   context.startActivity(new Intent(context, MainActivity.class));
}

我们在 test() 方法中调用toAct(),不难发现,toAct()的逻辑已经被移动到了 test() 中,而我们的泛型类型也被替换为实际使用的类型,从而我们可以在方法函数中直接获取相应的泛型类型。

这也就是为什么 reified 必须要增加 inline ,因为其必须内联才能知道具体类型,从而将我们的实际泛型类型更新到具体的调用代码中,从而完成泛型类型再生。

小提示

Java中无法调用

需要注意的是,reified 无法在java中进行调用,为什么呢?

因为 Java 并没有内联的特性,我们使用的 inline 方法在 Java 中会被当做普通方法,而 reified 正是需要内联才可以保证泛型再生,所以自然无法调用。

从源码上来说,对于reified 关键字的方法,相应的字节码生成时会增加 // $FF: synthetic method 的标记。

如下示例所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline fun <reified C : Activity> Context.toAct() {
   ...
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// $FF: synthetic method
public static final void toAct(Context $this$toAct) {
   ...
}

// $FF: synthetic method

如果你经常写组件,肯定见过这段注释。你可以理解这只是一个标记,其作用为告诉编译器 禁止java代码在编译期访问该方法

比如我们在写 kotlin 组件,而且要同时满足 java 调用时,经常会免不了使用 internal ,即 模块可见 。但相应的,该关键字修饰的方法或者字段在Java中却依然可以被调用,甚是让java调用者费解与不优雅。所以相应的,对于方法,我们可以增加 @JvmSynthetic ,从而避免java代码编译期调用。而 reified 也是正是采用了该思路。

当然也可以采用 @JvmName(name=" xxx") 等方式避免java调用,但其并不是很优雅。

性能方面

使用 reified 不会带来任何性能损失,相反还会增强性能(源于inline)。

之所以这里还要提到,主要是因为如果 内联函数过于复杂,则可能会导致性能问题。所以 reified 的使用其实也需要遵循内联函数的最佳实践。

如果查看Kotlin的标准内联函数,你会发现,代码行数大部分只有1-3行,因为inline会增加代码量的生成,内联函数越复杂,相应的代码量也越高,具体的使用方面,可以参见这篇 Kotlin Vocabulary | 内联函数的原理与应用

参考

Kotlin Vocabulary | Reified: 类型擦除后再生计划

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
用代码助力能源行业节能减排,是技术人独有的浪漫
2021年,能源危机席卷全球,芯片短缺、车企减产、拉闸限电、欧洲天然气价格暴涨,多点出现的个例汇集到一起,揭开了当前能源供给的极端失衡。另一方面,伴随着国际能源结构的变革,与我国能源政策的完善,在「碳达峰」与「碳中和」要求下,化石能源的消耗在不断减少,而以风力、水力发电为代表的清洁能源正在迈入高速发展的快车道。能源结构的转型,使得越来越多的能源企业意识到数字化建设的重要性,智慧油田、智慧电网等智慧能源设施的建设脚步也在不断加快。
TVP官方团队
2021/12/14
9450
用代码助力能源行业节能减排,是技术人独有的浪漫
2030年,腾讯将实现全面碳中和!
2021年初,我们启动了碳中和规划,成为首批启动碳中和规划的互联网企业之一。 今天,我们开始“净零行动”! 我们承诺,不晚于2030年,实现自身运营及供应链的全面碳中和。同时,不晚于2030年,实现100%绿色电力。 为什么要做这件事? 气候变化,正影响我们每一个人的生活。 我们一直在探索如何助力实现中国碳中和目标,一起应对气候挑战。 2020年底,腾讯公司董事会主席兼首席执行官马化腾曾在公司员工大会上分享,新冠疫情的到来让他更加关注人和大自然的关系,也让他意识到企业在未来发展中要更加关注企业和环境
云产品技术支持小助手
2022/06/24
5420
2030年,腾讯将实现全面碳中和!
热文回顾|“双碳”目标下物流业的挑战与对策
已经成为国家发展战略的“双碳”目标的提出,必将带来社会经济各个领域低碳转型的重大变革和挑战。其中物流行业既是能源消耗大户,也是碳排放大户,物流行业应对“双碳”目标挑战,实现低碳转型和可持续发展已成为备受关注的重要发展课题。
用户9868602
2023/02/27
7710
热文回顾|“双碳”目标下物流业的挑战与对策
《碳寻2》启动,全球抓捕二氧化碳
2023年3月,我们发起了一项面向未来前沿技术的「碳寻计划」——在全国征集能「捕捉二氧化碳」的创新技术。
小腾资讯君
2024/12/05
960
法国电力“Pulse能创未来”大赛邀你参赛,快来赢取丰富奖金和资源支持!
转载自 中关村创业大街 zgccydj 量子位 编辑 | 公众号 QbitAI 让电动出行更经济便捷的黑科技 统筹房屋能源消耗的AI管家 打造坚强智能电网的数字化方案 …… 如果您的企业有能助力中国与世界实现低碳转型 的创新解决方案 那么我们有一个好消息: 法国电力集团“Pulse能创未来”大赛启动啦! 我们寻找: ✔ 将创新进取、突破前沿刻进DNA的中国初创企业 ✔ “智能电网”、“智慧城市”、“智慧生活”三大赛道上的创新产品/服务 我们为胜者提供: ✔ 10万元人民币! ✔ 与法国电力中国团队共同进行
量子位
2023/03/10
7520
法国电力“Pulse能创未来”大赛邀你参赛,快来赢取丰富奖金和资源支持!
存储资源盘活系统有效降低IDC机房碳排放
国家发改委等四部门印发《贯彻落实碳达峰碳中和目标要求 推动数据中心和5G等新型基础设施绿色高质量发展实施方案》中提出,到2025年,全国新建大型、超大型数据中心平均电能利用效率降到1.3以下,国家枢纽节点进一步降到1.25以下,绿色低碳等级达到4A级以上。当下,通过数字化技术提升能源使用效率,对于大多数企业来说仍是实现可持续发展的最佳途径,随之而来的是庞大的计算量、数据量以及成倍的能耗增长。据统计,我国数据中心整体用电量约占全社会用电量的2.71%;在其供电结构中,火电占比超过70%,双碳改革空间巨大。
存储小白
2022/09/08
8180
建筑建材企业如何突破转型提升管理与生产效益
“十三五”期间,随着共建“一带一路”向高质量发展方向不断推进,中国建筑建材行业开始由规模速度型向质量效益型发展转变,从高增长迈入平台期,建筑建材行业必须要考虑转型升级,不能以不变应万变,不能用30年来成功的想法和做法来应对今天环境的大变化。
数商云市场营销总监
2021/05/27
6320
深圳市生态环境局联合腾讯发布“低碳星球”小程序,腾讯区块链技术助力低碳生活
在12月17日第九届深圳国际低碳城论坛上,由光明日报全媒体、深圳市生态环境局、深圳排放权交易所、腾讯公司联合出品,腾讯区块链提供技术支持的“低碳星球”小程序正式上线。 根据今年11月发布的《深圳碳普惠体系建设工作方案》,深圳市生态环境局将借助互联网科技的力量,探索个人碳账户与碳交易打通。深圳也将率先通过低碳星球小程序试点开通和运营个人碳账户。作为目前深圳碳普惠首个授权运营平台,“低碳星球”可将用户通过腾讯乘车码参与的公共出行行为,科学核算二氧化碳减排量,积累相应碳积分。 依据深圳市生态环境局发布
腾讯TrustSQL
2021/12/20
1.3K0
IBM谢东:2nm芯片可让手机4天一充电,量子计算机大规模应用的未来不会太远|MEET2022
“不久前刚推出127Qubit的量子计算,在2023 年将推出超1000Qubit的量子计算机系统。”
量子位
2022/01/13
2590
IBM谢东:2nm芯片可让手机4天一充电,量子计算机大规模应用的未来不会太远|MEET2022
科技赋能双碳未来 共创绿色软件生态 ——2022年绿色软件基金会中国峰会成功举办
2020年,中国明确提出2030年“碳达峰”与2060年“碳中和”目标,实现“双碳”目标已经成为各行各业的共识。软件行业虽非高碳行业,但随数字化转型的加快,数据中心和技术公司运营等能耗持续增长,探寻行业的绿色减碳之路势在必行。 在这样的趋势之下,为了寻找软件行业的减碳路径,共同推动行业节能减排,全球性软件及咨询公司Thoughtworks发起了2022绿色软件基金会中国峰会。该活动于6月16日成功在线上举办,峰会通过主题演讲、话题分享、小组讨论等形式深入探讨企业该如何通过科技赋能双碳未来。 云上论道 探讨科
ThoughtWorks
2022/06/24
1.1K0
科技赋能双碳未来 共创绿色软件生态 ——2022年绿色软件基金会中国峰会成功举办
视频 | 能源基金会工业节能项目主任何平:G20能效引领计划的商业新机遇
<数据猿导读> 在本次《G20能效引领计划下的能源大数据》活动中,能源基金会工业节能项目主任何平就《G20能效引领计划的商业新机遇》发表了精彩演讲,对近25年里国内外的能效发展做出了剖析,并对未来发展
数据猿
2018/04/20
6930
视频 | 能源基金会工业节能项目主任何平:G20能效引领计划的商业新机遇
「双碳」战略,对智能驾驶场景化落地提出什么新挑战? | M-TECH 2022中国智能驾驶创新峰会
M-TECH 2022中国智能驾驶创新峰会报名火热进行中! 1591.9亿元,这是2021年汽车智能化方向的市场累计融资金额。 该数值,已然创造了历年最高值,也反映出了智能驾驶赛道的“热闹”。 时间进入2022年,仅1月份,国内外就出现了18起重要投融资事件,金额累计超过60亿元人民币。 与此同时,业内也有人表示,智能驾驶正处于行业爆发阶段,因为在技术、厂商、资本及消费者这四个层面上,行业生态肉眼可见的正在完善中。 安全之后,智能驾驶迎来新命题 可以看到,自去年初至今,先是百度、阿里、小米先后宣布进军造车
镁客网
2022/03/04
4470
什么是国之大者?为美丽中国贡献“移动力量”!
严峻的气候变化形势已对人类生存发展构成重大挑战,“走向碳中和”成为当今世界最为关切的课题。全球主要经济体相继承诺在本世纪中叶达成碳中和,中国作为推动全球气候治理进程的重要力量,亦提出了“3060”双碳的宏伟目标。
悲了伤的白犀牛
2022/05/18
6920
什么是国之大者?为美丽中国贡献“移动力量”!
14个碳排放数据库汇总(附链接)
1. 中国碳核算数据库(China Emission Accounts and Datasets, CEADs)
郭好奇同学
2022/04/12
8.6K0
14个碳排放数据库汇总(附链接)
追碳的人:“碳寻计划”首期Top30榜单发布
获奖的团队阵容强大,有来自清华大学、香港科技大学(广州)等高等院校的学者,也有来自自然资源部、中国地质调查局、怀柔实验室等单位的科学家,还有早期初创企业的创业者们。
小腾资讯君
2023/09/22
4510
全球首个“零碳”码头并网发电,天津港绿色港口建设迈出新步伐
能源结构变革和转型是中国实现“双碳”目标的必经之路。大力发展以风电、光伏为主体的新能源,成为绿色电力的基础,力推以电为中心的综合能源服务,打造智慧能源管理平台。
HT小吴
2022/01/18
8410
全球首个“零碳”码头并网发电,天津港绿色港口建设迈出新步伐
2030年前碳达峰行动方案再次强调大力推广新能源汽车
国务院印发《2030年前碳达峰行动方案》(下称《方案》),聚焦2030年前碳达峰目标,对推进碳达峰工作作出总体部署。
恩泽能源
2022/02/10
2920
33 分钟生成 12 万种碳捕捉候选材料,美国阿贡国家实验室发布生成式 AI 框架,加速 MOFs 创新
美国阿贡国家实验室发布生成式 AI 框架 GHP-MOFsassemble,能够随机生成并组装新的 MOFs 结构,筛选出高稳定性的 MOFs 结构,并测试其对二氧化碳的吸附能力。
HyperAI超神经
2024/03/25
2140
33 分钟生成 12 万种碳捕捉候选材料,美国阿贡国家实验室发布生成式 AI 框架,加速 MOFs 创新
「孤岛」日本:被逼出来的低碳大国
去年,中国立下横跨几十年的"双碳"目标。两会上,碳中和被首次写入政府工作报告,并定为2021年八大工作重点之一。
AI掘金志
2022/03/15
3340
「孤岛」日本:被逼出来的低碳大国
碳中和大潮惊涛拍岸,科技企业如何迈入这条大江大河?
碳中和的长潮将连绵不断,在这长潮之上,技术的发展和全球竞争一定会不时掀起拍天巨浪。
科技云报道
2022/12/08
2780
碳中和大潮惊涛拍岸,科技企业如何迈入这条大江大河?
推荐阅读
用代码助力能源行业节能减排,是技术人独有的浪漫
9450
2030年,腾讯将实现全面碳中和!
5420
热文回顾|“双碳”目标下物流业的挑战与对策
7710
《碳寻2》启动,全球抓捕二氧化碳
960
法国电力“Pulse能创未来”大赛邀你参赛,快来赢取丰富奖金和资源支持!
7520
存储资源盘活系统有效降低IDC机房碳排放
8180
建筑建材企业如何突破转型提升管理与生产效益
6320
深圳市生态环境局联合腾讯发布“低碳星球”小程序,腾讯区块链技术助力低碳生活
1.3K0
IBM谢东:2nm芯片可让手机4天一充电,量子计算机大规模应用的未来不会太远|MEET2022
2590
科技赋能双碳未来 共创绿色软件生态 ——2022年绿色软件基金会中国峰会成功举办
1.1K0
视频 | 能源基金会工业节能项目主任何平:G20能效引领计划的商业新机遇
6930
「双碳」战略,对智能驾驶场景化落地提出什么新挑战? | M-TECH 2022中国智能驾驶创新峰会
4470
什么是国之大者?为美丽中国贡献“移动力量”!
6920
14个碳排放数据库汇总(附链接)
8.6K0
追碳的人:“碳寻计划”首期Top30榜单发布
4510
全球首个“零碳”码头并网发电,天津港绿色港口建设迈出新步伐
8410
2030年前碳达峰行动方案再次强调大力推广新能源汽车
2920
33 分钟生成 12 万种碳捕捉候选材料,美国阿贡国家实验室发布生成式 AI 框架,加速 MOFs 创新
2140
「孤岛」日本:被逼出来的低碳大国
3340
碳中和大潮惊涛拍岸,科技企业如何迈入这条大江大河?
2780
相关推荐
用代码助力能源行业节能减排,是技术人独有的浪漫
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验