注解
JvmName
@file:JvmName("KKK26")
放在类的最顶层,给当前类换一个名字,jvm 在编译时会替换, 修改 Java类文件名字
@JvmName("XXX")
可以替换方法的名字
JvmField
@JvmField
给成员添加该标签,剔除私有代码,之后就可以直接调用了。
使 Kotlin 编译器不再对该字段生成 getter/setter 并将其作为公开字段
JvmOverloads
告诉Kotlin编译器为此函数生成替换默认参数值的重载
使用场景如下:
@JvmOverloads
fun goToActivity(
context: Context?,
url: String?,
bundle: Bundle? = null,
requestCode: Int = -1
) {
}
对应的Java代码
public final class AKt {
@JvmOverloads
public static final void goToActivity(@Nullable Context context, @Nullable String url, @Nullable Bundle bundle, int requestCode) {
}
// $FF: synthetic method
// $FF: bridge method
@JvmOverloads
public static void goToActivity$default(Context var0, String var1, Bundle var2, int var3, int var4, Object var5) {
if ((var4 & 4) != 0) {
var2 = (Bundle)null;
}
if ((var4 & 8) != 0) {
var3 = -1;
}
goToActivity(var0, var1, var2, var3);
}
@JvmOverloads
public static final void goToActivity(@Nullable Context context, @Nullable String url, @Nullable Bundle bundle) {
goToActivity$default(context, url, bundle, 0, 8, (Object)null);
}
@JvmOverloads
public static final void goToActivity(@Nullable Context context, @Nullable String url) {
goToActivity$default(context, url, (Bundle)null, 0, 12, (Object)null);
}
我们可以看到为了能让Java享受到Koltin的默认参数的特性,使用此注解来生成对应的重载方法。
重载的规则是顺序重载,只有有默认值的参数会参与重载.
JvmStatic
@JvmStatic
给对象的成员添加属性, 变成静态可以直接调用,在KT的半生类companion中,实际生成的是一个静态内部类,
你如果给一个方法添加该标签,实际上外面会生成一个静态方法,但是最终方法里面还是会调用回companion里面,JVM没那么傻生成两个方法
Volatile
//不能对val变量加注解
@Volatile
var volatileStr: String = "volatile"
将带注释属性的JVM支持字段标记为 Volatile,这意味着对此字段的写入立即对其他线程可见.
对应Java中的volatile关键字
Synchronized
kotlin lazy 加载的方法里有线程安全模式 SYNCHRONIZED
val instance: ApkTool by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ApkTool() }
//一般不这样直接修饰在方法上, 一般使用代码块的方式
@Synchronized
fun getSynString(): String = "test"
fun setSynString(str:String){
//注意这里使用的是内敛函数来实现的对代码块加锁
synchronized(this){
println(str)
}
}
Transient
将带注释的属性的JVM支持字段标记为transient,表示它不是对象的默认序列化形式的一部分。
对应Java中的transient关键字
//:Serializable
data class XBean(
val name: String?,
val age: Int?,
//不参与序列化
@Transient
val male: Boolean = true
): Serializable
//Parcelize(目前还是实验性功能 需要在gradle中配置开启 experimental = true)
@Parcelize
data class XBean(
val name: String?,
val age: Int?,
//不参与序列化
@Transient
val male: Boolean = true
)
Throws
@Throws(IOException::class)
fun getData(){
throw IOException("这是一个测试Exception")
}
JvmMultifileClass
用于标记一个类为多文件的一部分。
这意味着一个类的定义被分散在多个 Kotlin 文件中。这种特性允许你将一个大型类拆分到多个文件中,以提高可读性和管理性。
一般配合 JvmName 定义类的名字
/*** KotlinAnn1.kt ***/
@file:JvmName("KAnn")
@file:JvmMultifileClass
package com.example.kotlinlearning_zlz.zhujie10.ann
fun test1() {
println("这是 KotlinAnn 1")
}
/*** KotlinAnn2.kt ***/
@file:JvmName("KAnn")
@file:JvmMultifileClass
package com.example.kotlinlearning_zlz.zhujie10.ann
fun test2() {
println("这是 KotlinAnn 2")
}
/*** KT.kt ***/
package com.example.kotlinlearning_zlz.zhujie10.ann
fun main(){
test1()
test2()
}
KotlinAnn1.kt 和 KotlinAnn2.kt 生成时会合并为一个 KAnn.kt