kotlin与Java语言的交互

由于项目中混合了kotlin和java两种语言,所以有时间两种语言交互之间就有些尴尬,由于不太熟练,所以就记录一下。

1. Kotlin调用Java

1.1 kotlin调用Java集合类:
    val kotlinList = listOf(1,2,4,5)

    //这里使用的是Java原生的ArrayList
    val javaList = ArrayList<Double>()

    for(item in kotlinList){
        javaList.add(item.toDouble())
    }
1.2调用Java类的getter和setter方法

kotlin可以看做直接操作Java属性。

class Entity {
	private String name ;
	private int age ;
   
    public void setName(String name){
    	this.name = name ;
	}

   public String getName() {
   		return name ;
   }
}

//kotlin.kt
var p = Person()
p.name = 'steven'
p.age = 24
1.3 Java可变参数
public class Utils {
    public static void print(String ...nameList) {
        for(String item : nameList) {
            System.out.println(item);
         }
       }
    }

在kotlin代码中调用时:

    var list = arrayOf("tom","steven","mary")
    Utils.print(*list)   //这里需要一个 * 号
1.4 关于Exception

Kotlin中所有的Exception都叫做Unchecked Exception,kotlin编辑器不强迫你捕获任何异常,如下面代码:

    public static boolean checkFileExist(String filePath) throws IOException {
        File file = new File(filePath);
        FileWriter fileWriter = new FileWriter(file);
        //do other things
        return file.exists();
    }

直接使用kotlin调用时:

Utils.checkFileExist("/user/")

结果就直接蹦了:

1.5 java.lang.Object方法使用

Java中Object有很多出生就会有的方法:

equals();
hashCode();
wait();
notify();
toString();
getClass() ;

在kotlin中要使用这些方法时,需要将kotlin中Any对象(它实现了toString(),hashCode()和equals()方法)转成Object对象,才能使用wait()和notify()方法。

val p = Person();
(p as java.lang.Object).notify();
(p as java.lang.Object).wait();
1.6 getClass()

这个用的比较多,我们获取对象的Java类,直接在类上使用Java扩展属性,它是Kotlin的反射类kotlin.reflect.KClass的扩展属性.

val clazz = Activity::class.java
//或者
val clazz = Activity.javaClass  (kotlin1.1之后支持的绑定类引用)

非常普遍的例子为,我们启动一个新的Activity:

 startActivity(Intent(this, LayoutActivity::class.java))
 startActivity(Intent(this, LayoutActivity.javaClass))
1.7 clone()接口

kotlin中要调用覆盖java.lang.Object中的clone,需要实现kotlin.Cloneable:

class PJava : Cloneable{
    override fun clone(): Any {
        return super.clone()
    }
}
1.8 java中存在kotlin的关键字:
//java代码
public class TextUtils {
    public static boolean is(String a , String b) {
        return null != a && a.equals(b);
    }
}

is是kotlin中关键字,需要调用时,需要加上'',就像下面的:

TextUtils.`is`("1","3")

不过不用担心,因为编辑器都会给我们帮忙,可以直接帮我们生成需要的代码。

1.9 获取java的反射功能
    val p = PJava()

    var pClazz = p::class.java
    var pClazz1 = PJava::class.java
    var pClazz2 = p.javaClass
    
    println(pClazz === pClazz1)
    println(pClazz1 === pClazz2)

结果为:

true
true

表明三个对象pClazzpClazz1pClazz2是同一个对象。

2. Java调用kotlin

2.1 Java调用Kotlin包级函数

有如下一个kt函数,路径与文件名如下:

然后通过AndoridStudio中Tools -> Kotlin -> show Kotlin byteCode, 然后点击一下Decompile装换成Java代码:

我们发现所写的StringUtils类被转换成了StringUtilsKt.Java对象,其中StringUtils中所有方法都被转成了static final 类型方法,那么在java中调用可以表现为:

System.out.println(StringUtilsKt.verify("hello world"));

另外,加上@file:JvmName注解可以将生成的java改名:

@file:JvmName("HXStringUtils")

package com.xing.java_kotlin

fun print(str:Any) {
    println(str)
}
fun verify(str:Any?) : Boolean =  str?.toString()!!.isNotEmpty()

结果为:
在这里插入图片描述

2.2 kotlin的实例字段

如果我kotlin对象中有个属性我不希望生成setter/getter方法,直接可以使用@JvmField注解即可。

kotlin代码->java代码
在这里插入图片描述   
在这里插入图片描述在这里插入图片描述
2.3 静态字段&静态方法

既然是静态的,那么需要涉及到伴生对象和命名对象,不是很懂的可以google,需要在他们的属性上添加@JvmField,在方法上添加@JvmStatic注解,这样就能生成Java的静态方法。
如下代码:

class KStudent {
    var id:Long = 1

    @JvmField
    var name:String = "mary"

    companion object {
        var schoolName = "school name"

        @JvmField
        var schoolLocation = "SH"
        
        @JvmStatic
        fun printInfo() {
            println("school info: $schoolLocation")
        }
    }
}

可以看到schoolLocation属于伴生对象,已经添加了@JvmField注解,而printInfo()方法也添加了 @JvmStatic注解,我们来看一下对应生成的Java代码:
在这里插入图片描述

我们可以发现schoolLocation已经是public的静态属性了,而printInfo已经是静态方法了,那么我们调用时:

System.out.println(KStudent.schoolLocation);
KStudent.printInfo();
2.5 修饰符的可见性

如下表

Kotlin中修饰符Java中修饰符
privateprivate
protectedprotected
internalpublic
publicpublic
2.6 kotlin中异常

在kotlin中不需要显示Exception的,也没有try catch finally关键字,异常来了就来了,kotlin管不住,像这个:

class KStudent {
  	 companion object {
  	 
        @JvmStatic
        fun tryToThrow() {
            var fileWriter = FileWriter(File("unknown path"))
            fileWriter.write("hello world")
        }
    }
}

直接调用时,没有显示显示效果:
在这里插入图片描述

但是运行时肯定是没戏了,程序直接蹦,那么如果我们需要提示操作者这里有异常,要怎么做呢?
需要用到@Throws(Exception::class)注解

class KStudent {
  	 companion object {
  	 
  	    @Throws(IOException::class)
        @JvmStatic
        fun tryToThrow() {
            var fileWriter = FileWriter(File("unknown path"))
            fileWriter.write("hello world")
        }
    }
}

然后在我们调用时:
在这里插入图片描述

此时就需要我们try…catch了。

还有其他的,在工作中用得多的,以后再记录吧。

参考:
https://www.jianshu.com/p/d8a115427242

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值