Kotlin注解整理

  • Kotlin注解之JvmName

我们首先定义给 Int定义一个扩展函数。

 

fun Int.compare(num: Int): Int {
    return if (this > num) {
        this
    } else num
}

在Kotlin代码中我们可以直接调用:

 

println(2.compare(1))

但是在 Java代码中我们的调用方式变为:

 

public static void main(String[] args) {
    int num = TestAnotionKt.compare(2, 1);
    System.out.println(num);
}

其实通过观察Kotlin转换为Java的代码就可以比较容易理解Java中的调用方式了,可以发现扩展被转换成了一个静态方法。类名变为:Koltin文件名+Kt

 

public final class TestAnotionKt {
   public static final int compare(int $this$compare, int num) {
      return $this$compare > num ? $this$compare : num;
   }
}

其实上述的方法类似于一个工具类:这个时候我们就可以使用JvmName注解来给Java的调用方式重新取一个名字。

 

@file:JvmName("IntUtils")

package com.example.annotation


fun Int.compare(num: Int): Int {
    return if (this > num) {
        this
    } else num
}

则在Java中可以进行如下调用:

 

int num = IntUtils.compare(1, 2);
System.out.println(num);

通过将Kotlin代码转换成 Java代码,可以看出JvmName注解的作用:可以修改静态方法所在的类名。

 

public final class IntUtils {
   public static final int compare(int $this$compare, int num) {
      return $this$compare > num ? $this$compare : num;
   }
}

 

  • Kotlin注解之 JvmMultifileClass

JvmMultifileClass的作用是可以将多个个kt文件里面的代码合并到一个Javaclass文件中。

文件TestAnotionFunA.kt

@file:JvmName("CommonUtils")
@file:JvmMultifileClass

package com.example.annotation

fun functionA() {

}

文件TestAnotionFunB.kt

 

@file:JvmName("CommonUtils")
@file:JvmMultifileClass

package com.example.annotation

fun functionB() {

}

 

 

TestAnotionFunA.kt转换成Java

 

final class CommonUtils__TestAnotionFunAKt {
   public static final void functionA() {
   }
}

public final class CommonUtils {
   public static final void functionA() {
      CommonUtils__TestAnotionFunAKt.functionA();
   }
}

TestAnotionFunB.kt转换成Java

 

final class CommonUtils__TestAnotionFunBKt {
   public static final void functionB() {
   }
}

public final class CommonUtils {
   public static final void functionB() {
      CommonUtils__TestAnotionFunBKt.functionB();
   }
}

 

java中调用

 

CommonUtils.functionA();
CommonUtils.functionB();

如果不使用JvmMultifileClass,编译会报错。

Duplicate JVM class name 'com/example/annotation/CommonUtils' generated from: package-fragment com.example.annotation, package-fragment com.example.annotation

 

  • Kotlin注解之JvmField

我们首先定义一个Koltin的Person类

 

class Person(var name: String, var age: Int)

 

转换成Java如下:

 

public final class Person {
   @NotNull
   private String name;
   private int age;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.name = var1;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public Person(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
      this.age = age;
   }
}

 

在Java中使用这个Person类:

 

Person p1 = new Person("haha", 18);
p1.setName("XiXi");
p1.setAge(16);

 

而在Kotlin中可以直接使用:

 

val person = Person("haha", 18)
person.name = "xixi"
person.age = 16

 

如果希望在Java中 的使用方式与在Kotlin中相同,应该如何处理呢?

 

在Kotlin代码中加上@JvmField

 

class Person(@JvmField var name: String, var age: Int)

 

转换成对应的Java文件为:

 

public final class Person {
   @JvmField
   @NotNull
   public String name;
   private int age;

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public Person(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
      this.age = age;
   }
}

在Java文件中就可以以相同的方式调用:

 

Person p1 = new Person("haha", 18);
p1.name = "xixi";
  • Kotlin  注解之JvmStatic
public final class TestJvmStatic {
   public static final int a = 1;
   private static final int b = 2;
   private static int c = 3;
   @JvmField
   public static int d = 4;
   @JvmField
   public static final int e = 5;
   public static final TestJvmStatic.Companion Companion = new TestJvmStatic.Companion((DefaultConstructorMarker)null);

   @JvmStatic
   public static final void doOperateA() {
      Companion.doOperateA();
   }

   
   public static final class Companion {
      public final int getB() {
         return TestJvmStatic.b;
      }

      public final int getC() {
         return TestJvmStatic.c;
      }

      public final void setC(int var1) {
         TestJvmStatic.c = var1;
      }

      @JvmStatic
      public final void doOperateA() {
      }

      public final void doOperateB() {
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

在Java文件中调用:

 

TestJvmStatic.doOperateA();
TestJvmStatic.Companion.doOperateB();
int a = TestJvmStatic.a;
int e = TestJvmStatic.e;
int d = TestJvmStatic.d;
TestJvmStatic.Companion.getB();
TestJvmStatic.Companion.getC();

通过对比可以发现:@JvmStatic 和 @JvmField 注解,才能使方法或者字段暴露为静态方法或静态字段,这样Java调用方式和正常的Java静态方法的调用方式一样了。

 

  • Koltin注解之JvmSynthetic

如果想一个函数给kotlin代码调用 而不给java的代码调用 ,函数上面加上这个注解即可。

 

@file:JvmName("IntUtils")

package com.example.annotation

@JvmSynthetic
fun Int.compare(num: Int): Int {
    return if (this > num) {
        this
    } else num
}

fun main() {
   print(2.compare(3))
}

 

转换成Java 代码如下:

 

@JvmName(
   name = "IntUtils"
)
public final class IntUtils {
   // $FF: synthetic method
   public static final int compare(int $this$compare, int num) {
      return $this$compare > num ? $this$compare : num;
   }
}

可以发现:加上@JvmSynthetic注解后,该方法只能在Kotlin中调用了,在Java中会找不到这个方法 。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值