Kotlin与Java 的互调

作者: Taonce | 来源:发表于2018-10-25 22:30 被阅读31次
    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

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

    专注Kotlin知识的公众号

    相关文章

      网友评论

        本文标题:Kotlin与Java 的互调

        本文链接:https://www.haomeiwen.com/subject/malhtqtx.html