文 / CoderPig
0x1、原理
@JvmOverloads的作用告知编译器自动生成多个该方法的重载
就是不用自己写重载方法,kt会帮你自动生成,比如下面的代码:
等价于你在Java中声明三个重载方法:
但!底层真的是转换成了这样三个方法吗?实际上并不是!反编译下字节码:
生成了一个的方法,其他方法传参调用此方法。
令人不解的应该是&1、&2、&4,以及传参4,6,7 了,这些数字是干嘛的,还有怎么来的?
加上调用重载方法相关的代码:
反编译下字节码:
传入的第五个参数依次为:6、4、2、5,调用传参少,值反而大,跟下6时searchBook$default走的逻辑:
看到这里,思维敏捷的朋友应该看出端倪了,不急,再试试4时:
还没get√到的同学想想这两个式子:6 = 0 + 2 + 4,4 = 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 -
领取专属 10元无门槛券
私享最新 技术干货