Kotlin 反射你敢用吗?

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_23626713/article/details/90698516

其实一直想写一篇详细介绍 Kotlin 反射的文章,但问题就在于,现阶段的 Kotlin 反射还真不如直接用 Java 反射来的愉快。

你问我原因?那我们就来简单说说。

本文结论基于 Kotlin 1.1.51,相信在未来的版本,本文提到的问题都将被一一解决。

1 一个 2.5M 大小的 jar 包

Java 反射直接内置在 Java 标准库当中,而 Kotlin 的反射需要单独引入,原因也很简单,Kotlin 反射库居然有 2.5M。如果不混淆,这 2.5M 的 class 文件都将最终打包到你的应用程序中,如果恰好你的程序对于体积还比较敏感,那么这将是一个值得考虑的问题。比如 Android,我们做个简单的实验,引用了反射库编译 debug 包之后大小如下:

0?wx_fmt=jpeg

如果不带反射包,如下:

0?wx_fmt=jpeg

我们看到 classes.dex 的下载大小前后差到 0.6M,当然混淆了之后会小一些。

我们再看下同样的工程,在简单的引用了某一个类的 member 之后(这样做目的是混淆之后反射包不至于被剔除掉)进行混淆,包含反射包的大小是多少:

0?wx_fmt=jpeg

不包含反射包的混淆后大小为:

0?wx_fmt=jpeg

尽管混淆之后整体体积会小一些,但 Kotlin 的反射包造成的影响却不会小很多。

2 不支持的 built-in Kotlin types

如果你尝试用 Kotlin 反射访问下 String,你会发现 Boom,你的代码 crash 了。这是怎么回事呢?

  1. String::class.memberFunctions

错误信息很明确的说了,内置的 Kotlin 类型暂时没有被完全支持。

  1. Exception in thread "main" kotlin.reflect.jvm.internal.KotlinReflectionInternalError:

  2. Reflection on built-in Kotlin types is not yet fully supported.

  3. No metadata found for public open val length:

  4. kotlin.Int defined in kotlin.String[DeserializedPropertyDescriptor@1018bde2]

  • 那么什么是 Kotlin 内置的类型呢?

    在 Kotlin 当中,存在不少并非真实存在,而是编译期映射的类型,例如 kotlin.Int 等数值类型,实际上是映射到了 Java 虚拟机类型中的基本类型和装箱类型; kotlin.collections.Set 等集合类型,或通过编译实现映射,或直接通过类型别名映射,也都对应到了 Java 虚拟机类型中的集合框架。这样的类型,我们就可以认为是 Kotlin 的内置类型。


  • 那么既然是不完全支持,那么哪些类型有上述问题呢?

    StringMapSetArray 等这些类都会触发上述问题。


  • 如何针对这些类使用反射呢?

    考虑到这些类比较特殊,都是 Java 的原生类型,在 Kotlin 反射尚不能完全支持之前,建议使用 Java 反射。


3 还没来得及优化的性能

曾经在 Kotlin 的官方论坛上面看到有开发者抱怨 Kotlin 反射 API 耗时比 Java 反射长,官方开发者给出的答复是:目前在 Kotlin 反射框架上还没有花太多精力进行性能优化。

那么 Kotlin 反射究竟有多慢呢?我们对比下 Java 反射和 Kotlin 反射访问属性、修改属性、调用方法、构造对象以及前面提到的获取泛型参数的例子的耗时情况,如下(仅供参考):

单位:微秒 μs


构造对象访问属性修改属性调用方法
Java 反射12.725.212.218.8
Kotlin 反射14938.085247.51316.7326.3

以上数据在我的 MacBook Pro 上面运行所得,结果因设备有差异,但我们可以看到,Java 反射基本在 μs 级别,而 Kotlin 反射基本耗时在 ms 级别。

4 小结

整体来看,Kotlin 反射仍处于一个不太成熟的阶段,无论从体积还是从性能上考虑,现阶段使用 Kotlin 反射都应该保持一种谨慎的态度。当然,这不应该成为你排斥 Kotlin 的理由,毕竟 Kotlin 标准库已经非常成熟,并且绝大多数开发者是用不到反射的。


欢迎关注微信公众号 Kotlin

0?wx_fmt=jpeg


展开阅读全文

这样的MSN,还能用吗?还敢用吗?

05-02

rnrn唉~ 真是太伤心了 这样的MSN还能用吗!rn天天的我就跟我那MSN折腾。要不是我有超乎常人的忍耐力,铁定被这MSN气得进医院吸氧了。rn有一回一个陌生人加了我,起先也没多想只是觉得能知道我邮件地址的都是熟人,聊的云山雾罩的,过了八百年之后,才猛然发现原来压根就不认识!rn原来人家要加的另外一个人,邮件地址只跟我的差一个字母!!!rn还有,MSN不能改名字加标记,要是人家换名字,我根本就反映不过来这个人是谁,害得我好几次硬着头皮问人家是谁。最后没折,新建了一个EXCEL表格,把人名和MSN邮箱相对应,一旦人家签名变了我就得上来查。这不是逼着用户当弱智么?rn对了,还有那个服务器的问题,三天两头的上不去,明明网速好的没话说,再怎么说也是1MB宽带,结果,光登陆就费了10分钟,然后才慢慢悠悠地被告诉说服务器故障,我急我急我急急急!!!rnrn屋漏偏逢连夜雨,船迟又遇打头风。rn听说去年MSN Messenger的安全漏洞代码已经被公开了,黑客很有可能会对此加以利用,从而向数百万MSN用户发起攻击。rn还有被强制升级的事情,简直是强买强卖了吧。rn还有个人隐私问题,还得成天担心怕被盗走个人信息。rn这糟心的东西还能用吗?!号召大家都不用MSN!坚决打倒垃圾MSN! 论坛

没有更多推荐了,返回首页