前言
Kotlin 正式版已经发布了,优点大致就是解决了Java的一些痛点,写起来很Exciting。我来说说用Kotlin遇到的问题。
Apt(Annotation processing tool) 并不总是起效
Apt 现在可谓是不可缺少的一个工具,有非常多的库钦定了Apt。有人问,“不是说用注解会影响运行效率吗?” 有来自西方代码工作者 JakeWharton 的 ButterKnife, 有来自 Google 官方的 Data Dinding (http://www.jianshu.com/p/b1df61a4df77) 等。
我可以回答一句 “无可奉告”,但是你们又不高兴,我怎么办?我讲的意思是,注解不会影响运行效率,反射才会。我就明确告诉你这一点。
Data Binding 内部也使用了Kotlin
Kotlin 呢,其实也有类似的工具, 叫 Kapt 但是在 Kotlin 1.0.0 RC
之前的版本都是基本不太能用,而之后的版本虽然可以用了,但是总是出现个别注解无法解析的问题。后来发现了出问题的规律:被注解的属性或者字段如果存在名字相同的,就算是其他文件里,也会只有其中的一个可以正常解析。比如使用ButterKnife注入View:
1 | // @ MainActivity.kt |
1 | // @ AnotherActivity.kt |
这种情况下就只有其中的一个可以被解析了。不过,既然发现了这个规律,也能适当修改来规避这个bug了。
1 | // @ MainActivity.kt |
1 | // @ AnotherActivity.kt |
如此,两个View都注入成功。
这个问题也被西方的一些代码工作者提交了,KT-9183,希望能够早日被解决。
另外
要正常使用Kapt,除了配置好 Kotlin 依赖外,需要做一些额外的处理:
1 | // @ app/build.gradle |
generateStubs = true
会先把Kotlin的代码生成 .class
stubs,以处理注解。还有就是要把 apt
改为 kapt
, kapt同样也会对java代码做注解处理,而且不会有上述的问题,这点请放心。
在使用注解的地方:
1 | @Bind(R.id.btn) |
lateinit
关键字 和 @JvmField
注解 会把被修饰的属性变为普通的Java字段,失去Kotlin赋予属性的一些特性。但是为了要注解字段,做这些牺牲也是值得的。
Data Binding 无法和 Kotlin 一起使用
不是说 Kotlin 可以 Kapt 吗?Data Binding 内部也用了 Kotlin ,怎么会不能一起使用?
其实问题就出在 Data Binding 内部也用了 Kotlin。
在 Data Binding Compiler 的 gradle .pom
中发现
1 | <dependency> |
1 | Error:cannot generate view binders java.lang.NoSuchMethodError: kotlin.text.StringsKt.trim(Ljava/lang/String;)Ljava/lang/String; |
唉,等 Google 更新Data Binding的Kotlin版本吧,或者索性移除Kotlin的依赖。每次Kotlin版本更新的时候, 用Kotlin写过第三方库的人懂的都懂…
这个问题也被人反馈到了 KT-8007 和 AOSP。
Kotlin 方法的引用
Kotlin 目前只有 TopLevel 的方法可以使用方法引用
1 | fun fooAtTopLevel() : Int { |
这点还是挺遗憾的,不过 Kotlin 的开发人员说这个特性已经是未来的一个计划了
http://stackoverflow.com/questions/33616464/function-references-and-lambdas
http://stackoverflow.com/questions/32598320/kotlin-method-reference-not-working
还有关于 Anko 的问题
Anko 确实写起来超爽
1 | // 传统的代码中生成视图,Kotlin语法,如果用Java会更加冗长 |
1 | // 同样效果的Anko版本 |
但是,在 xml 中的自定义属性
1 | <View |
该怎么办呢?目前还没有找到处理的法。只能割爱暂时放弃 Anko,等JetBrains钦定了,再去产生。
Kotlin
总体来说,这些小问题瑕不掩瑜,Kotlin 是一个用起来很愉悦的语言,大家对 Java 诟病的地方,很多都在 Kotlin 中被缓解, 而且和 Java 不说 100% 兼容,至少 90% 还是有的,这点还是很重要,有 Java 做背书,有时候 Kotlin 不能用的地方, 换 Java 就好了嘛。
一个语言的命运啊,当然要靠自身的奋斗,但也有考虑到历史的进程。Kotlin他爹 JetBrains 怎么也想不到啊,Kotlin 一个在 Jvm 上跑的好好的,怎么就被 Google 用到 Data Binding 了呢?
不管 Kotlin 现在还有什么问题,至少 Google 也是已经把 Kotlin 用到了自己的库中。这是不是给人一种硬点的感觉?