首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

刨下Kotlin|9.@JvmOverloads 原理&一个小细节

文 / CoderPig

0x1、原理

@JvmOverloads的作用告知编译器自动生成多个该方法的重载

就是不用自己写重载方法,kt会帮你自动生成,比如下面的代码:

等价于你在Java中声明三个重载方法:

但!底层真的是转换成了这样三个方法吗?实际上并不是!反编译下字节码:

生成了一个的方法,其他方法传参调用此方法。

令人不解的应该是&1、&2、&4,以及传参4,6,7 了,这些数字是干嘛的,还有怎么来的?

加上调用重载方法相关的代码:

反编译下字节码:

传入的第五个参数依次为:6、4、2、5,调用传参少,值反而大,跟下6时searchBook$default走的逻辑:

看到这里,思维敏捷的朋友应该看出端倪了,不急,再试试4时:

还没get√到的同学想想这两个式子:6 = 0 + 2 + 44 = 0 + 0 + 4

懂了吧,就是每个参数对应一个值 ,有传这个参数就不加,没传就加上。

不信?再加个参数试试:

看下反编译效果:

不难看出:

根据这个值来判断某位置的参数是否传参,没有直接赋初值,减少了非必要重载方法的生成,妙啊!!!

0x2、一个小细节

在实际开发中,@JvmOverloads最常用的场景莫过于自定义View时偷懒不用写这三个构造方法:

当你继承一个View,AS会贴心的提醒你,要不要加上这个@JvmOverloads:

点击之后自动加上,很香~

看着还行,当我们在布局文件中引用这个自定义的EditText,会发现,根本拿不到焦点,没办法输入???

其实跟下源码就知道了:

这个默认的值可不是0,应该是R.attr.editTextStyle,所以解决方法也很简单,把0改成这个值就好了:

其他控件也可能存在这种情况,当自定义View实现样式问题时,用到了@JvmOverloads,可以试着排查看看~

参考文献

有点意思的Kotlin的默认参数与JVMOverloads

https://droidyue.com/blog/2018/10/14/dive-into-kotlin-default-arguments-and-jvmoverloads/

Do not always trust @JvmOverloads

https://medium.com/@mmlodawski/https-medium-com-mmlodawski-do-not-always-trust-jvmoverloads-5251f1ad2cfe

- EOF -

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20211207A09P0A00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券