🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 在Java中调用Kotlin #### 调用Kotlin中的包级函数 在Kotlin的包中直接声明的函数被称为包级函数,这些函数在编译时最终会生成一个静态的函数,在Java中调用该函数有两种形式,具体如下。 * 在编译时,包级函数会生成一个静态函数,包级函数所在的文件会生成一个名为“文件名Kt”的类,因此调用包级函数通过“文件名Kt.函数名()”的形式即可。 * 如果想要编译包级函数的类名(改成与Java类名类似),则需要在Kotlin文件中上方添加@file:JvmName("类名")注解。括号中的类名可以自己定义。 接下来我们通过一个案例来演示如何在Java中调用Kotlin中的包级函数。 1. 创建PacketFunction.kt 创建一个PackageFunction.kt文件,在该文件中创建一个包级函数add(),具体代码如【文件12-9】所示。 【文件12-9】PackageFunction.kt ``` @file:JvmName("Function") fun add(a: Int, b: Int): Int = a + b //包级函数(顶层函数) ``` 在上述代码中,第1行代码中的注解表示将该文件的类名设置为Function,同时在该文件中创建了一个包级函数add(),该函数返回两个参数的和。 >[info] **注意** 带有@file:JvmName("类名")注解的kotlin文件不能放到包目录中,否则会出现this annotation is not applicable to target 'top level function' and use site target"@file"的错误信息。 2. 创建PacketFunction.java 在PackageFunction.kt文件的同级目录中创建一个PacketFunction.java文件,在该文件中调用【文件12-9】中的包级函数add(),具体代码如【文件12-10】所示。 【文件12-10】PacketFunction.java ``` public class PacketFunction { public static void main(String[] args) { //PackageFunction.kt 文件未添加注解时,调用add()函数 //int result = PackageFunctionKt.add(10, 20); //PackageFunction.kt 文件添加注解时,调用add()函数 int result = Function.add(10, 20); System.out.println(result); } } ``` 运行结果: ``` 30 ``` 如果【文件12-9】中不添加@file:JvmName("Function")注解,则PacketFunction.kt文件在编译时会生成一个PackageFunctionKt类,该文件中的包级函数add()在编译时会生成一个静态函数add(),因此在Java中可以通过上述第4行代码的方式来调用add()函数。如果【文件12-9】中添加@file:JvmName("Function")注解,则需要通过上述第6行代码来调用add()函数。 >[info] **注意** 在Java中不能通过new关键字来创建Kotlin中编译后生成的PackageFunctionKt类的对象。 #### 调用Kotlin中的实例字段 在Kotlin中,调用某个类的字段时,都需要通过点的方式来调用。对于Java来说,则需要通过getXX()方法和setXX()方法来获取与设置字段的值,这是因为在Kotlin类中的字段编译时最终会生成Java代码中的getXX()方法和setXX()方法。如果想要Kotlin类中的字段编译后生成的字段不用private关键字来修饰而是通过public关键字来修饰,则需要在Kotlin类中的该字段上方添加@JvmField注解,此时在Java代码中可以通过点的方式来访问Kotlin中类的字段。接下来我们通过一个案例来演示一下在Java代码中调用Kotlin中的字段。 1. 创建Field.kt 创建一个Field.kt文件,在该文件中创建一个Person类,并在该类中创建两个字段,分别是name和age。具体代码如【文件12-11】所示。 【文件12-11】Field.kt ``` class People { @JvmField var name = "张三" var age = 20 } ``` 上述代码中,给name字段添加了@JvmField注解,这个注解主要可以使name字段在Java中以点的方式进行访问。 2. 创建Field.java 创建名为Field的Java文件,在该类中的main()函数中来调用【文件12-11】中的字段。具体代码如【文件12-12】所示。 【文件12-12】Field.java ``` public class Field { public static void main(String[] args) { People people = new People(); people.name = "李四"; people.setAge(10); System.out.println("姓名:"+people.name); System.out.println("年龄:"+people.getAge()); } } ``` 运行结果: ``` 姓名:李四 年龄:10 ``` 从上述代码可以看出,第5行代码是通过person.name的形式访问Kotlin中字段的,而访问age字段时,必须要通过setAge()与getAge()的方式。 #### 调用Kotlin中的静态字段和方法 在Java中,静态方法和字段可以通过static关键字来修饰,调用时直接通过“类名.成员名”的方式进行访问。在Kotlin中没有static关键字,只能通过伴生对象的方式将字段或者方法设置为静态的。如果想要将Kotlin对象中的一些属性和方法设置为静态的,则可以将它放入伴生对象中,在Java中调用时可以通过“类型.成员”或者“类名.伴生对象.成员”的方式进行访问。接下来我们通过一个案例来演示如何在Kotlin中调用静态字段和方法,并在Java中通过一定的方式进行调用这些字段和方法。 1. 创建Static.kt 创建一个Static.kt文件,在该文件中创建一个Department类并在这个类中创建一个名为Fruit的伴生对象,在该伴生对象中创建一个静态字段name。具体代码如【文件12-13】所示。 【文件12-13】Static.kt ``` class Department { companion object Fruit { var name = "Apple" //静态的 @JvmStatic fun sayHello() { println(name) } } } ``` 上述代码中,在伴生对象Fruit中创建了一个静态字段name,同时也通过@JvmStatic注解创建了一个静态方法sayHello()。在Kotlin中,可以将命名对象(Object对象)或伴生对象中定义的方法通过@JvmStatic注解生成一个静态方法。 2. 创建Static.java 创建一个Static.java文件,在该文件中调用【文件12-13】中的静态字段和方法。具体代码如【文件12-14】所示。 【文件12-14】Static.java ``` public class Static { public static void main(String[] args) { Department.Fruit.setName("Pea"); //设置Kotlin中的静态字段 Department.Fruit.getName(); //获取Kotlin中的静态字段 Department.Fruit.sayHello(); //调用Kotlin中的静态函数 Department.sayHello(); //调用Kotlin中的静态函数 } } ``` 运行结果: ``` Pea Pea ``` 从上述代码可以看出,在Java中可以通过“类名.伴生对象名.getXX()/setXX()”的方式来访问Kotlin中的静态字段,通过“类名.伴生对象.静态方法”或“类名.静态方法”的方式来访问Kotlin中的静态方法。 #### 调用Kotlin中的集合类 Kotlin中List和MutableList是映射到Java中的List,同样Map和Set也是一样的,需要注意的是Kotlin中通过listof()方法创建的集合是不能添加和删除元素的。接下来我们通过一个案例来演示在Java中调用Kotlin中创建的一个List集合并修改集合中的元素。 1. 创建List.kt 创建一个List.kt文件,在该文件中创建一个getList()方法,该方法的返回值是一个集合,这个集合是通过listof()方法创建的。具体代码如【文件12-15】所示。 【文件12-15】List.kt ``` fun getList():List<String>{ return listOf("张三","李四","王五") } ``` 2. 创建ModifyList.java 创建一个ModifyList.java文件,在该文件中的main()方法中通过调用Kotlin中创建的getList()方法来获取List集合并修改集合中的元素。具体代码如【文件12-16】所示。 【文件12-16】ModifyList.java ``` import java.util.List; public class ModifyList { public static void main(String[] args) { List<String> list = ListKt.getList();//映射到Java的List list.set(2, "周七"); //修改集合中索引为2的元素值为周七 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } } ``` 运行结果: ``` 张三 李四 周七 ``` 在上述代码中,通过set()方法将list集合中的索引为2的元素修改为周七,从运行结果可以看出已经修改成功。 需要注意的是,Java中可以通过add()方法向集合中添加或修改元素,但这里不能这样写,否则在运行时会报错。 #### 显式申明Kotlin中的异常 在Kotlin中抛出一个异常,在Java中调用该异常所在的方法时,编译器不会提示有异常需要处理。如果想要在Java编译器中提示有异常,则需要在Kotlin中抛出异常的方法上方添加一个@Throws(Exception::class)注解。接下来我们通过一个案例来演示显示申明Kotlin中的异常。 1. 创建Exception.kt 创建一个Exception.kt文件,在该文件中创建一个Calculation类,在该类中定义一个divide()方法实现两个数的除法运算。具体代码如【文件12-17】0所示。 【文件12-17】Calculation.kt ``` class Calculation { // 提示处理Kotlin 异常 @Throws(Exception::class) fun divide(a: Int, b: Int) { if (b == 0) { throw Exception(" 出现了异常") } val result = a / b println(result) } } ``` 上述代码中,当divide()方法中传递的参数b为0时,程序会抛出一个异常,同时在该方法的上方添加了@Throws(Exception::class)注解,添加这个注解是为了在Java中调用这个方法时编译器会提示有异常。 2. 创建ExceptionDemo.java 创建一个Exception.java文件,在该文件中调用【文件12-17】中的divide()方法,具体代码如【文件12-18】所示。 【文件12-18】Exception.java ``` public class Exception extends Throwable { public static void main(String[] args) { Calculation calc = new Calculation(); try { calc.divide(10, 0); } catch (Exception e) { e.printStackTrace(); } } } ``` 运行结果: ``` Exception in thread"main"java.lang.Exception:出现了异常 at com.itheima.chapter12.Calculation.divide(Exception.kt:7) at com.itheima.chapter12.Exception.main(Exception.java:6) ``` 在上述代码中,调用divide()方法时,由于编译器提示此处需要处理一个异常,因此添加了try…catch语句。如果【文件12-17】中的divide()方法上方不添加@Throws(Exception::class)注解,此时调用divide()方法,编译器不会提示这个异常,但是在程序运行时会抛出这个异常。 #### 关键字冲突的互操作 一些Kotlin关键字在Java中是最优先的标识符,例如in、Object、is等。如果在Java中使用了Kotlin中的关键字作为一个方法的名称,则可以通过反引号字符转义来调用。接下来我们通过一个案例来演示在Kotlin中如何处理关键字冲突的互操作。 1. 创建Keyword.java 创建一个Keyword.java文件,在该文件中创建一个is()方法。具体代码如【文件12-19】所示。 【文件12-19】Keyword.java ``` public class Keyword { public boolean is(Object o) { return true; } } ``` 2. 创建Keyword.kt 创建一个Keyword.kt文件,在该文件中调用Java中创建的is()方法。具体代码如【文件12-20】所示。 【文件12-20】Keyword.kt ``` fun main(args: Array<String>) { var key = Keyword() var result = key.`is`("Hello") //通过反引号调用is()方法 println(result) } ``` 运行结果: ``` true ``` 在上述代码中,由于在Kotlin中is是关键字,如果想要调用is()方法,则需要通过反引号来实现。