Java调用Kotlin的包级函数

package com.easy.kotlin 包内的 KotlinExample.kt 源文件中声明的所有的函数和属性,包括扩展函数,都将编译成一个名为 com.easy.kotlin.KotlinExampleKt 的 Java 类中的静态方法。

代码示例:

Kotlin的包级属性、函数代码:

  1. package com.easy.kotlin
  2. fun f1() {
  3. println("I am f1")
  4. }
  5. fun f2() {
  6. println("I am f2")
  7. }
  8. val p: String = "PPP"
  9. fun String.swap(index1: Int, index2: Int): String {
  10. val strArray = this.toCharArray()
  11. val tmp = strArray[index1]
  12. strArray[index1] = strArray[index2]
  13. strArray[index2] = tmp
  14. var result = ""
  15. strArray.forEach { result += it }
  16. return result
  17. }
  18. fun main(args: Array<String>) {
  19. println("abc".swap(0, 2))
  20. }

编译成对应的Java的代码:

  1. public final class KotlinExampleKt {
  2. @NotNull
  3. private static final String p = "PPP";
  4. public static final void f1() {
  5. String var0 = "I am f1";
  6. System.out.println(var0);
  7. }
  8. public static final void f2() {
  9. String var0 = "I am f2";
  10. System.out.println(var0);
  11. }
  12. @NotNull
  13. public static final String getP() {
  14. return p;
  15. }
  16. @NotNull
  17. public static final String swap(@NotNull String $receiver, int index1, int index2) {
  18. Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
  19. char[] var10000 = $receiver.toCharArray();
  20. Intrinsics.checkExpressionValueIsNotNull(var10000, "(this as java.lang.String).toCharArray()");
  21. char[] strArray = var10000;
  22. char tmp = strArray[index1];
  23. strArray[index1] = strArray[index2];
  24. strArray[index2] = tmp;
  25. Object result = "";
  26. char[] $receiver$iv = strArray;
  27. for(int var7 = 0; var7 < $receiver$iv.length; ++var7) {
  28. char element$iv = $receiver$iv[var7];
  29. result = result + element$iv;
  30. }
  31. return result;
  32. }
  33. public static final void main(@NotNull String[] args) {
  34. Intrinsics.checkParameterIsNotNull(args, "args");
  35. String var1 = swap("abc", 0, 2);
  36. System.out.println(var1);
  37. }
  38. }

我们可以看到,Kotlin中的扩展函数

  1. fun String.swap(index1: Int, index2: Int): String

被编译成

  1. public static final String swap(@NotNull String $receiver, int index1, int index2)

Kotlin中的String. 接收者被当做Java方法中的第一个参数传入。

Java调用Kotlin包级属性、函数的测试代码:

  1. @Test
  2. public void testPackageFun() {
  3. KotlinExampleKt.f1();
  4. KotlinExampleKt.f2();
  5. System.out.println(KotlinExampleKt.getP());
  6. KotlinExampleKt.swap("abc",0,1);
  7. }

运行输出:

  1. I am f1
  2. I am f2
  3. PPP
  4. bac

另外,要注意的这里生成的类KotlinExampleKt,我们不能使用new来创建实例对象:

  1. KotlinExampleKt example = new KotlinExampleKt();// 报错

报如下错误:

  1. error: cannot find symbol
  2. KotlinExampleKt example = new KotlinExampleKt();
  3. ^
  4. symbol: constructor KotlinExampleKt()
  5. location: class KotlinExampleKt
  6. 1 error

在编程中,我们推荐使用Kotlin默认的命名生成规则。如果确实有特殊场景需要自定义Kotlin包级函数对应的生成Java类的名字,我们可以使用 @JvmName 注解修改生成的 Java 类的类名:

  1. @file:JvmName("MyKotlinExample")
  2. package com.easy.kotlin
  3. fun f3() {
  4. println("I am f3")
  5. }
  6. fun f4() {
  7. println("I am f4")
  8. }
  9. val p2: String = "PPP"

测试代码:

  1. MyKotlinExample.f3();
  2. MyKotlinExample.f4();