在上一篇中,主要讲解了Kotlin对应的函数式编程。在这一篇中,将会讲解Kotlin与Java之间的相互调用!
话不多说,直接开始!
1、Kotlin调用Java 1.1 属性读写 *** 作进入TestJava
public class TestJava { public int getHitPoints() { return hitPoints; } public void setHitPoints(int hitPoints) { this.hitPoints = hitPoints; } private int hitPoints = 3232320; }
这没啥可说的,现在进入对应Kotlin文件
fun main{ val testJava = TestJava() val hitPoints = testJava.hitPoints println(hitPoints.dec()) println(hitPoints.javaClass.name) }
运行效果
3232319 int
只要java实体类里面对应属性有get/set方法,在Kotlin这边就能直接访问以及修改对应值。
几乎没任何难度,直接看下一个!
1.2 方法访问 *** 作进入TestJava
public class TestJava { private final String TAG = this.getClass().getSimpleName(); public String utterGreeting() { return TAG + "_utterGreeting"; } public String determineFriendShipLevel() { return null; } public void javaException() throws IOException { throw new IOException("java 异常"); } public static int getTestInt() { return testInt; } public static void setTestInt(int testInt) { TestJava.testInt = testInt; } private static int testInt; }
对应Kotlin
//定义私有扩展 private fun String?.default(default: String): String { if (this == null) { println("该变量为空,返回默认值") return default } return this } fun main() { val testJava = TestJava() println(testJava.utterGreeting()) val level = testJava.determineFriendShipLevel() level.default("null").toUpperCase().run(::println) TestJava.setTestInt(11111) //测试java对应的静态方法是否能访问 println(TestJava.getTestInt()) try { testJava.javaException() }catch (a:Exception){ println(a.message) } }
运行效果
TestJava_utterGreeting 该变量为空,返回默认值 NULL 11111 java 异常
运行发现,Kotlin依然能够直接调用Java对应的方法、静态以及对应Java方的异常捕获!Java不需要做任何事
不过注意的是:在Java里,会有出现空的情况,所以在不确定对应Java对应的属性以及方法返回值是否为空的话,最好在Kotlin这边提前处理好,以免报错!
现在看完了Kotlin调用Java的,那看看Java调用Kotlin的?
2、Java调用Kotlin 2.1 Kotlin非伴生调用先进入目标Kotlin类Spellbook.kt
class Spellbook { fun add(num1: Int, num2: Int): Int { return num1 + num2 } var list = listOf("Magic Ms.L", "Lay on hans") fun acceptApology() { throw IOException() } }
对应java调用
public class TestJava { public static void main(String[] args) { Spellbook spellbook = new Spellbook(); int sum = spellbook.add(12, 32); System.out.println("sum:" + sum); ArrayListlistStr = new ArrayList<>(); listStr.add("hello I'm Java"); listStr.add("hello I'm Java"); System.out.println("list " + spellbook.getList()); spellbook.setList(listStr); System.out.println("list " + spellbook.getList()); spellbook.acceptApology(); //调用Kotlin那边的自定义异常 } }
运行效果
sum:44 list [Magic Ms.L, Lay on hans] list [hello I'm Java, hello I'm Java] Exception in thread "main" java.io.IOException at Spellbook.acceptApology(Spellbook.kt:15) at TestJava.main(TestJava.java:51)
狠简单,没啥可说的!直接下一个!
2.2 Kotlin伴生调用先进入目标Kotlin类Spellbook.kt
class Spellbook { companion object { val spells = listOf("Magic Ms.L", "Lay on hans") val MAX_SPELL_COUNT = 10 fun add(num1: Int, num2: Int): Int { return num1 + num2 } fun acceptApology() { throw IOException() } } }
在之前讲解里,提到过 companion object表示对象Spellbook对应的伴生对象。它的意思就和Java的Static类似,表示在Kotlin里,里面的元素以及对应方法可以直接通过类名.出来。
那么看看Java是怎样调用Kotlin伴生对象里的方法与属性呢?
public class TestJava { public static void main(String[] args) { ArrayListlistStr = new ArrayList<>(); listStr.add("hello Companion I'm Java"); listStr.add("hello Companion I'm Java"); int sum = Spellbook.Companion.add(12, 12); System.out.println(sum); System.out.println("list " + Spellbook.Companion.getSpells()); Spellbook.Companion.setSpells(listStr); System.out.println("list " + Spellbook.Companion.getSpells()); Spellbook.Companion.acceptApology(); } }
运行效果
24 list [Magic Ms.L, Lay on hans] list [hello Companion I'm Java, hello Companion I'm Java] Exception in thread "main" java.io.IOException at Spellbook$Companion.acceptApology(Spellbook.kt:47) at TestJava.main(TestJava.java:63)
我们看到,通过.Companion这个关键字来间歇性访问了Kotlin对应伴生对象里的属性和方法!那如果说,不想通过这个方法呢?有没有好的方法?
既然这样问了,那就肯定有的,重新改造对应Kotlin里的内容:
class Spellbook { companion object { @JvmField val spells = listOf("Magic Ms.L", "Lay on hans") @JvmField val MAX_SPELL_COUNT = 10 @JvmStatic fun add(num1: Int, num2: Int): Int { return num1 + num2 } @JvmStatic @Throws(IOException::class) fun acceptApology() { throw IOException() } } }
我们看到对应的Kotlin里面的属性以及方法都加上了对应的注解,并且acceptApology额外加了@Throws注解,这个注解表示java方调用这个方法必须要进行异常捕获,类似于在java方法后加了在这里插入add Throws。
现在来看看Java使用!
public class TestJava { public static void main(String[] args) { ArrayListlistStr = new ArrayList<>(); listStr.add("hello Companion I'm Java"); listStr.add("hello Companion I'm Java"); int sum = Spellbook.add(12, 12); System.out.println(sum); System.out.println("list " + Spellbook.spells); Spellbook.spells = listStr; System.out.println("list " + Spellbook.spells); try { Spellbook.acceptApology(); //这里不进行try catch的话就直接报错! } catch (IOException e) { e.printStackTrace(); } } }
运行效果
24 list [Magic Ms.L, Lay on hans] list [hello Companion I'm Java, hello Companion I'm Java]
这里我们看到,之前的那个“中间商”没有了,现在java可以直接通过类名.的方式直接访问对应的方法和属性了!
那是不是就这样没了?伴生与非伴生都讲完了!Kotlin还有啥Java不能调的?或者说不能完全发挥方法特性的?
Kotlin能够给方法形参赋初始值,Java调对应的方法能赋初始值么?
来试试看:
2.3 调用形参带默认值的方法class Spellbook { companion object { @JvmStatic fun getSpellbookGreeting(leftHand: String = "berries", rightHand: String = "beef") = println("Mmmm... you hand over some delicious $leftHand and $rightHand") } } fun main(){ Spellbook.getSpellbookGreeting() }
先看看对应Kotlin运行效果:
Mmmm... you hand over some delicious berries and beef
从这个运行效果上看,当Kotlin方法里对应形参带有初始值的情况下,调用对应方法,可以不用传对应参数。那用java来调调这个方法:
如图所示
在Java使用这个方法时,却没有使用到Kotlin对应特性。想要使用那个方法只能传入两个参数。
那如果说Java就是想体验对应特性呢?
也不是不可以,现在改造一下对应Kotlin代码:
class Spellbook { companion object { // @JvmStatic //表示 该方法 在java 层 可通过 static 静态访问,也可通过实例对象访问 @JvmOverloads //表示该方法 在java 层 已对该函数进行了重载,可不传,可传变量1或者两者都传 fun getSpellbookGreeting(leftHand: String = "berries", rightHand: String = "beef") = println("Mmmm... you hand over some delicious $leftHand and $rightHand") } } fun main(){ Spellbook.getSpellbookGreeting() }
在这额外加了新的注解:@JvmOverloads,现在回到Java试试看哇:
如图所示
到Java这边也体验到了Kotlin对应的特性。是不是很简单哇。
结束语好了,本篇到这里就结束了!同时Kotlin对应的基础教程到这也结束了!相信看到这里的小伙伴,已经具备了Java转Kotlin的基础能力!读者也可尝试将Java项目逐步转移至Kotlin!反正它俩能够相互调用!
从下一篇开始,将会开启Kotlin进阶教程——协成!编译器也将从Idea转向我们熟悉的AS!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)