一、kotlin调用Java
- kotlin空安全与Java可空类型
public class JHava {
public String determineFriendshipLevel(){
return null;
}
@Nullable
public String determineFriendshipLevelWithNullable(){
return null;
}
}
这里定义了一个java
类JHava
,在kotlin
代码中调用,JHava
中定义了两个方法,分别是determineFriendshipLevel()
和determineFriendshipLevelWithNullable()
,区别在于determineFriendshipLevelWithNullable()
增加了@Nullable
注解,当我们在Kotlin
代码中调用determineFriendshipLevel()
时无编译报错,但是会报运行时错误。determineFriendshipLevelWithNullable()
则会直接在编译时报错,需要增加空安全操作符 "?
",让编码更加安全可见,这里建议在Java
代码编写的时候增加@Nullable
注解,同时要在调用的时候多注意kotlin
代码中确认是否存在空安全的运行时报错潜在风险。如下代码示例
fun testJavaOperationKotlin() {
val jhava = JHava()
//level 类型是String! 的平台类型
val level = jhava.determineFriendshipLevel()
//当level 返回null的时候报运行时错误,这里没有给出编译时报错
level.lowercase()
//这里只是知道会有运行时异常增加的判断
level?.lowercase()
//levelSafe 类型是String! 的平台类型
val levelSafe = jhava.determineFriendshipLevelWithNullable()
//levelSafe 为可空类型,这里给出编译时报错,增加?空安全操作符
levelSafe?.lowercase()
}
- 类型映射
public class JHava {
public int hitPoints = 13587;
}
@Test
fun testKotlinOperationJavaClass(){
val jhava = JHava()
println(jhava.hitPoints.javaClass)
println(jhava.javaClass)
println(jhava::class.java)
}
// print result
//int
//class com.example.mydatastructdemo.ktdemo.JHava
//class com.example.mydatastructdemo.ktdemo.JHava
二、Java操作Kotlin
- @JvmName
对要调用的类的名字和方法的名字进行重命名
下边定义了一个Hero.kt的kotlin
文件,包含了makeProclamation()
方法
package com.example.mydatastructdemo.ktdemo
fun makeProclamation() = "Greetings,beast!"
public static void main(String[] args) {
HeroKt.makeProclamation();
}
在Java
代码中直接调用,需要使用HeroKt
引用,调用的时候总要加xxxKt.yyyy(),很不美观方便,我们可以使用@JvmName
优化
注意:@file:JvmName("xxx")
需要用在包名前边,输入的时候不要引用提示的@file:会出现编译上的问题,直接打出来就好了
@file:JvmName(name = "Hero")
package com.example.mydatastructdemo.ktdemo
fun makeProclamation() = "Greetings,beast!"
@JvmName(name="newMethod")
fun oldMethod() = "New"
public static void main(String[] args) {
Hero.makeProclamation();
Hero.newMethod();
}
这样我们就可以直接使用Hero.makeProclamation()
和Hero.newMethod()
- @JvmField
在Java里,不能直接访问属性字段,必须使用getXXX()方法,然而,我们可以给Kotlin属性添加@JvmField
注解,从而避免使用getter方法
如下,定义一个Spellbook.kt
class Spellbook {
@JvmField
val spells = listOf<String>("Magic Ms. L", "Lay on Hans")
val years = listOf<String>("2023", "2024")
}
可以直接使用spellbook.spells
不需要调用getSpells()
,但是没有@JvmField
注解的years
属性只能使用getYears()
方法
public void testKotlin(){
Spellbook spellbook = new Spellbook();
System.out.println(spellbook.spells);
System.out.println(spellbook.getYears());
}
- @JvmOverloads
该注解协助产生kotlin
函数的重载版本,需要默认参数
class CircleView @JvmOverloads constructor( context: Context, attrs:AttributeSet? = null,defStyleAttr: Int = 0) : View( context,attrs,defStyleAttr) {
}
- @JvmStatic和@JvmField
支持Java静态方法和静态常量的调用,
class Spellbook {
@JvmField
val spells = listOf<String>("Magic Ms. L", "Lay on Hans")
val years = listOf<String>("2023", "2024")
companion object {
@JvmField
val MAX_SPELL_COUNT = 10
@JvmStatic
fun getSpellbookGreeting() = println("I am the Great Grimoire!")
}
}
直接调用,无需调用伴生对象Companion
public void testKotlin(){
System.out.println(Spellbook.MAX_SPELL_COUNT);
Spellbook.getSpellbookGreeting();
//System.out.println(Spellbook.Companion.getMAX_SPELL_COUNT());
// Spellbook.Companion.getSpellbookGreeting();
}
- @Throws
抛出一个需要检查的指定异常,Java和Kotlin有关异常检查的差异(运行时异常和编译时异常?)让@Throws
注解给解决掉了。在编写供Java开发者调用的kotlin API时,要考虑使用@Throw
注解
如下Config.kt
class Config {
@Throws(FileNotFoundException::class)
fun loadConfigFile(){
throw FileNotFoundException("The config File not found")
}
}
如下不添加@Throws
注解不会报编译时异常,相当于在Java中loadConfigFile() throws FileNotFoundException
public void testThrows() {
Config config = new Config() ;
try {
//报编译时异常
config.loadConfigFile();
} catch (FileNotFoundException e) {
System.out.println("config load fail!");
}
}
注意:在编写kotlin代码时候,如果调用Java API中的方法 声明了可能抛出异常,即 xxx() throws XxxException
,在kotlin中不一定会在编译时检测到,编码过程中根据实际情况处理异常。
欢迎纠错和建议