Kotlin 与 Java 相互调用

目录

    • 一、Kotlin 调用 Java
      • 1. kotlin 关键字转义
      • 2. kotlin 可将数组传给 java 的可变数量参数
      • 3. kotlin 获取对象的 java 类
    • 二、Java 调用 Kotlin
      • 1. java 调用 kotlin 类的属性和方法
      • 2. java 调用 kotlin 的顶级属性和顶级函数
      • 3. java 调用生成指定类名的 kotlin 属性和函数
      • 4. java 调用 kotlin 的伴生对象的方法和静态方法
      • 5. java 调用 kotlin 单例类的方法
      • 6. java 调用 kotlin 含有 lambda 表达式参数的方法
      • 7. kotlin 使用 @JvmOverloads 注解强制生成重载方法
    • 附 Github 源码:

一、Kotlin 调用 Java

1. kotlin 关键字转义

java 中的方法或变量 是 kotlin 的关键字时,使用反引号 `` 对关键字进行转义

// java
public class JavaDemo {

    String is;

    public String getIs() {
        return is;
    }

    public void setIs(String is) {
        this.is = is;
    }

    public void in() {
        System.out.println("call java method in");
    }
    
	public void multiParams(int... params) {
        System.out.println(Arrays.toString(params));
    }
}
// kotlin
fun main() {
    // 1. java 中的方法或变量 是kotlin 的关键字时,使用反引号 `` 对关键字进行转义
    val demo = JavaDemo()

    // 调用 java 的 is 属性,is 是 kotlin 的关键字,使用反引号转义
    demo.`is` = "call java field"
    println(demo.`is`) // call java field

    // 调用 java 的 in 方法,in 是 kotlin 的关键字,使用反引号转义
    demo.`in`() // call java method in
}


2. kotlin 可将数组传给 java 的可变数量参数

// kotlin
// 使用 * 号将 kotlin 的 数组 传给 java 的 可变数量参数
fun main() {
	val arrayInt = intArrayOf(1, 2, 3)
	demo.multiParams(*arrayInt) // [1, 2, 3]
}

3. kotlin 获取对象的 java 类

// kotlin
fun main() {
 	demo::class.java
    demo.javaClass
}

二、Java 调用 Kotlin

1. java 调用 kotlin 类的属性和方法

// kotlin
class KotlinDemo {
    var field: String = "kotlin field"

    fun method() {
        println("call kotlin method")
    }
}

// java
public static void main(String[] args) {
	KotlinDemo demo = new KotlinDemo();
    System.out.println(demo.getField()); // kotlin field
    demo.method(); // call kotlin method
}


2. java 调用 kotlin 的顶级属性和顶级函数

// kotlin
val topLevelField: Int
    get() {
        println("call kotlin top level field")
        return 1
    }

fun topLevelFunc() {
    println("call kotlin top level function")
}
// java
public static void main(String[] args) {
	TestCallEachOtherKt.getTopLevelField(); // call kotlin top level field
    TestCallEachOtherKt.topLevelFunc(); // call kotlin top level function
}
        

3. java 调用生成指定类名的 kotlin 属性和函数

// kotlin
// 指定文件生成的 Java 类或方法的名称。
@file:JvmName("CallKtDemo")

package com.william.testkt

var field: Int = 100

fun method() {
    println("call CallKtDemo method")
}

// java
public static void main(String[] args) {
	System.out.println(CallKtDemo.getField());
    CallKtDemo.method();
}

4. java 调用 kotlin 的伴生对象的方法和静态方法

// kotlin
class TestCallKotlin {

    companion object {
    	// 模拟静态方法
        fun method1() {
            println("call method1")
        }

		// 静态方法
        @JvmStatic 
        fun method2() {
            println("call method2")
        }
    }
}
// java
public static void main(String[] args) {
	TestCallKotlin.Companion.method1();
	TestCallKotlin.method2();
}

5. java 调用 kotlin 单例类的方法

// kotlin
object KotlinObject {

    fun method1() {
        println("call method1")
    }

    @JvmStatic
    fun method2() {
        println("call method2")
    }
}

// java
public static void main(String[] args) {
	KotlinObject.INSTANCE.method1();
    KotlinObject.method2();
}

6. java 调用 kotlin 含有 lambda 表达式参数的方法

当在 java 中赋值 kotlin 的 lambda 表达式时,用 FunctionN 指代,N:表达式入参的数量,尖括号最后一个类型:表达式返回值的类型

// kotlin
object KotlinObject {

    // 参数为 lambda 表达式,入参为 Int,返回值为 Unit,在定义时,也可以不写等号后面的表达式
    @JvmStatic
    fun method3(param: (Int) -> Unit = {}) {
        param.invoke(101)
    }

    // 参数为 lambda 表达式,入参为 Boolean,返回值为 String,在定义时,也可以不写等号后面的表达式
    @JvmStatic
    fun method4(param: (Boolean) -> String = { "" }) {
        param.invoke(true)
    }

    // 参数为 lambda 表达式,无入参,返回值为 Unit
    @JvmStatic
    fun method5(param: () -> Unit) {
        param.invoke()
    }

    // 参数为 lambda 表达式,入参为 Int, String,返回值为 Boolean
    @JvmStatic
    fun method6(param: (Int, String) -> Boolean) {
        param.invoke(100, "string value")
    }
}

// java
public static void main(String[] args) {

	// 参数为 lambda 表达式,入参为 Int,返回值为 Unit
	KotlinObject.method3(new Function1<Integer, Unit>() {
     	@Override
        public Unit invoke(Integer integer) {
            System.out.println(integer);
            return null;
        }
    });

	// 参数为 lambda 表达式,入参为 Boolean,返回值为 String
    KotlinObject.method4(new Function1<Boolean, String>() {
        @Override
        public String invoke(Boolean param) {
            System.out.println("invoke param: " + param);
            return param ? "success" : "failed";
        }
    });
    
	// 参数为 lambda 表达式,无入参,返回值为 Unit
    KotlinObject.method5(new Function0<Unit>() {
         @Override
         public Unit invoke() {
             System.out.println("invoke method5 no params");
             return null;
         }
     });

     // 参数为 lambda 表达式,入参为 Int, String,返回值为 Boolean
     KotlinObject.method6(new Function2<Integer, String, Boolean>() {
         @Override
         public Boolean invoke(Integer integer, String s) {
             System.out.println("invoke method6 params:integer=" + integer + ", s=" + s);
             return integer > 0;
         }
     });
}

7. kotlin 使用 @JvmOverloads 注解强制生成重载方法

对于有默认值的函数或方法,可以使用 @JvmOverloads 注解强制生成多个重载方法,以方便其在 java 中调用

// kotlin
class KotlinDemo {
    /**
     * @JvmOverloads 注解会生成以下重载方法:
     * 当参数有默认值时,会生成对应的重载方法。注意 p0 没有默认值
     *
     * void overloadMethod1(int p0)
     * void overloadMethod1(int p0, int p1)
     * void overloadMethod1(int p0, int p1, String p2)
     */
    @JvmOverloads
    fun overloadMethod1(p0: Int, p1: Int = 1, p2: String = "") {
    }

    /**
     * @JvmOverloads 注解会生成以下重载方法:
     *
     * void overloadMethod2()
     * void overloadMethod2(int p0)
     * void overloadMethod2(int p0, int p1)
     * void overloadMethod2(int p0, int p1, String p2)
     */
    @JvmOverloads
    fun overloadMethod2(p0: Int = 0, p1: Int = 1, p2: String = "") {
    }
}
// java
public static void main(String[] args) {
 	KotlinDemo demo = new KotlinDemo();
 	
	// 调用 kotlin 的重载方法
    demo.overloadMethod1(0);
    demo.overloadMethod1(0, 1);
    demo.overloadMethod1(0, 1, "p2");

	// 调用 kotlin 的重载方法
    demo.overloadMethod2();
    demo.overloadMethod2(0);
    demo.overloadMethod2(0, 1);
    demo.overloadMethod2(0, 1, "p2");
}

附 Github 源码:

  • JavaDemo.java
  • TestCallKotlin.kt
  • TestCallEachOther.kt

你可能感兴趣的:(Kotlin,kotlin,java,开发语言,android)