Kotlin
中删除了大量须要咱们手写或者由 IDE
、第三方框架生成的模板代码。最好的例子就是 Kotlin
是空安全的,因为这个特性,咱们不须要写空判断语句 if(value != null)
,这是 Kotlin/JVM
中额外添加在 Java
字节码中实现的。因此说好的功能必然须要付出必定的代价来换取。java
下面让咱们一块儿来看看 Kotlin
编译后的字节码,并学习如何下降这种代价。android
示例代码:git
// Sample.kt
fun sample(arg1: String) {
}
复制代码
编译后的 Java
字节码:github
public final class SampleKt {
public static final void sample(@NotNull String arg1) {
Intrinsics.checkParameterIsNotNull(arg1, “arg1”);
}
}
复制代码
在上面的字节码中,能够看到调用了 kotlin.jvm.internal.Intrinsics 类中的 checkParameterIsNotNull
方法进行空检查。可是实际上咱们是否都须要这些代码呢?让咱们看下另外一个例子。安全
Kotlin
中有特定的 types
—[platform type](http://platform type/)。你不能声明这些类型,只能经过其它代码返回。bash
// Utils.java
public class Utils {
public static String getValue() {
throw new RuntimeException();
}
}
// Sample.kt
fun sample() {
val value: String = Utils.getValue()
}
复制代码
编译后的字节码:框架
public final class SampleKt {
public static final void sample() {
Intrinsics.checkExpressionValueIsNotNull(
Utils.getValue(), "Utils.getValue()"
);
}
}
复制代码
能够看到字节码很是精简,若是咱们能将开发期间写的调试代码在 Release
版本中进行移除,这个特性确定很实用。jvm
你能够在你的 ProGuard 文件中添加下面的混淆配置来移除工具类的字节码。ide
// proguard.pro
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
public static void checkExpressionValueIsNotNull(...);
public static void checkNotNullExpressionValue(...);
public static void checkReturnedValueIsNotNull(...);
public static void checkFieldIsNotNull(...);
public static void checkParameterIsNotNull(...);
}
复制代码
-assumenosideeffects
须要你本身保证你所选择的类的方法没有边界效应(简单来讲就是删掉也不会影响程序运行),而后 proguard
会帮你删掉这些方法的调用。函数
经过 kotlin
编译参数配置能够删除一些 assert
。
-Xno-call-assertions
:不对 platform types
的参数生成空检查-Xno-receiver-assertions
:不对 platform types
的接收参数生成空检查-Xno-param-assertions
:不对 Java
方法参数生成非空检查// build.gradle
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile)
.all {
kotlinOptions {
freeCompilerArgs += [
'-Xno-call-assertions',
'-Xno-receiver-assertions',
'-Xno-param-assertions'
]
}
}
复制代码
你能够在这里查看更多关于 Kotlin/JVM
的编译参数信息。
Kotlin
是一门很棒的开发语言,尽管它的一些特性支持须要一些代价。可是那些说 Java
没有添加太多额外字节码的操做,而 Kotlin
添加不少的说法是愚蠢的。例如 Java
中的特性(泛型和 switch
支持 String
)都是经过生成其它的字节码实现的。Kotlin
生成更多的附加字节码,所以您在源代码中写的更少。
同时,你能够经过 ProGuard
/R8
下降这些影响。我建议在发布版本时使用这两种方法。为何只针对发布版本?由于高质量的 Android
应用程序必须速度快,每秒 60 帧,并且体积小。但仅限于终端用户,不要从调试版本中删除任何内容,以得到尽量多的有关应用程序错误行为的信息,从而简化应用程序的调试。