Kotlin与Java 的互调

Java基础

浏览数:132

2019-8-22

AD:资源代下载服务

kotlin

1、在Java中调用Kotlin的方法

在Util.kt文件中声明了一个echo方法:

package kotlin2java

fun echo(name: String) {
    println("$name")
}

在JavaMain.java中调用:

UtilKt.echo("kotlin");

这里注意的是:echo声明在文件中,而不是class中,所以在Java代码中是通过文件名+kt.方法名

2、Java和Kotlin中调用Kotlin中object修饰的类

在KotlinMain.kt文件中声明:

object KotlinMain{
    fun printObject(){
        println("printObject")
    }
}

在KotlinMain.kt文件中调用:类名+方法名

fun main(args: Array<String>) {
    KotlinMain.printObject()
}

在JavaMain.java文件中调用:类名+INSTANCE+方法名

public class JavaMain {
    public static void main(String[] args){
        UtilKt.echo("kotlin");

        KotlinMain.INSTANCE.printObject();
    }
}

这里的INSTANCE是如何来的?我们将KotlinMain.kt文件转换为Java代码就能清楚的知道,在被编译成Java代码的时候object修饰的类会生成一个静态对象INSTANCE。且看编译后的代码:

public final class KotlinMain {
   public static final KotlinMain INSTANCE;

   public final void printObject() {
      String var1 = "printObject";
      System.out.println(var1);
   }

   static {
      KotlinMain var0 = new KotlinMain();
      INSTANCE = var0;
   }
}

看到这段代码,大家就能轻而易举的明白在Java代码中如何调用printObject方法了。

如何摆脱INSTANCE

Kotlin中被@JvmStatic修饰的方法,编译成Java代码后就变成了一个静态方法,所以在Java中调用是不需要加上INSTANCE的。

// Koltin
package four

object Utils {
    @JvmStatic
    fun sayMessage(msg: String?) {
        println("$msg")
    }
}

// Kotlin编译成Java后
public final class StaticKotlinFun {
   public static final StaticKotlinFun INSTANCE;

   @JvmStatic
   public static final void sout(@Nullable String msg) {
      String var1 = String.valueOf(msg);
      System.out.println(var1);
   }

   static {
      StaticKotlinFun var0 = new StaticKotlinFun();
      INSTANCE = var0;
   }
}

// Java调用
package four;

public class JavaUtil {
    public static void main(String[] args) {
        Utils.sayMessage(null);
    }
}

3、Kotlin中调用class对象(JavaClass和KotlinClass)

fun main(args: Array<String>) {
    testJavaClass(JavaMain::class.java)
    testKotlinClass(KotlinMain::class.java)
}

fun testJavaClass(clazz: Class<JavaMain>) {
    println(clazz.simpleName)
}

fun testKotlinClass(clazz: Class<KotlinMain>) {
    println(clazz.simpleName)
}

// 输出结果:
// JavaMain
// KotlinMain

这里的JavaMain是一个java类,而KotlinMain是一个Kotlin类。

在Kotlin语法中,调用Java的class必须使用类名::class.java

但是如果这个参数是Kotlin的类,我们可以写成和Java一样的,传参的时候传入Class<?>。那么既然是Kotlin调用Kotlin,肯定有更加简单的写法了,在明确自己调用的是Kotlin类,我们就可以写成:

fun testKotlinSimpleClass(clazz: KClass<KotlinMain>){
    println(clazz.simpleName)
}
// 调用
testKotlinSimpleClass(KotlinMain::class)

这里我们传入的不是Class<?>对象了,而是KClass<?>对象,在调用的时候也就不用在后面加上.class,直接使用类名::class就行了。

4、Kotlin调用Java中的变量,此变量名在Kotlin中为关键字:

  1. 如果Java中声明的变量的变量名在Kotlin中不是关键字,那么直接用类名.变量名,如:

    public class JavaMain {
    
        public static String name = "taonce";
        
    }
    // 调用
    println(JavaMain.name)
    
  2. 如果Java中声明的变量的变量名在Kotlin中是关键字,再调用上面的写法编译器就会发出警告”expecting an element”,编译器都期待有这个元素,所以我们得写成这样:

    public class JavaMain {
        
        public static String in = "in";
    
    }
    // 调用
    println(JavaMain.`in`)
    

    使用一对反引号将变量名包围起来,这样编译器就会正确的执行了。

写在最后

每个人不是天生就强大,你若不努力,如何证明自己,加油!

Thank You!

–Taonce

如果你觉得这篇文章对你有所帮助,那么就动动小手指,长按下方的二维码,关注一波吧~~非常期待大家的加入

作者:Taonce