Kotlin学习笔记(五)-kotlin与Java互操作

kotlin与Java互操作

在Kotlin中调用Java

数组的互操作性

与java不同,Kotlin中数组是非型变得,即Kotlin不允许我们把一个Array赋值给一个Array。

// Kotlin
var arrayAny = arrayOf(1, "2", true)
val arrayString = arrayOf(1, 2, 3)
//    arrayAny= arrayString // error, Type mismatch
// Java
String[] arrayString = new String[]{"1", "2", "3"};
Object[] arrayAny;
System.out.println(arrayAny = arrayString); //[Ljava.lang.String;@4dc63996

检查Java中的异常

Kotlin中,所有异常都是非受检的(Non-Checked Exception,编译器异常),这意味着编辑器不会强迫你捕获其中的任何一个,但是可能会有运行时异常,所以终归要处理。

// Java中JSONObject,编译期异常
 JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("key1", "key");
                    jsonObject.get("none_key")

            jsonObject.get("none_key")
        } catch (JSONException e) {
            e.printStackTrace();
        }
// Kotlin,并没有强制。
val jsonObject = JSONObject()
jsonObject.put("key1", "key")

// 此句运行时异常,如下log。
jsonObject.get("none_key")
01-31 16:26:29.923 18281-18281/com.autodesk.shejijia.consumer E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.autodesk.shejijia.consumer, PID: 18281
    java.lang.RuntimeException: Unable to start activity 
     Caused by: org.json.JSONException: No value for none_key
        at org.json.JSONObject.get(JSONObject.java:389)
        at com.autodesk.shejijia.consumer.designer.project.activity.DesignerProjectActivity.initView(DesignerProjectActivity.kt:40)
        at com.autodesk.shejijia.shared.framework.base.BaseActivity.onCreate(BaseActivity.java:46)
        at android.app.Activity.performCreate(Activity.java:6910)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)

调用Java的Object方法

getClass() 获取对象的Java类。

val product = Product()
val simpleName = product.javaClass.simpleName
val simpleName1 = product::class.java.simpleName 

println(simpleName) //Product
println(simpleName1) //Product

关键字冲突

一些Kotlin的关键字是Java中的有效标识符,比如in,object、is等,使用反引号(’)字符转义,一般IDE自动添加了。

Kotlin中调用:

fun main(args: Array<String>) {
    JavaDemo.`is`()
}

Java中方法:

public static boolean is() {
    return true;
}

Nothing类型

Kotlin的Nothing是一个特殊类型,在Java中没有对应的类型。在使用时Nothing参数的地方会生成一个原始类型。

Kotlin中:

fun emptyList(): List<Nothing> = listOf()

Java中:

List list = JavaKotlinKt.emptyList();
System.out.println(list); // []

在Java中调用Kotlin

包级函数

package com.liuhe.kotlin内的JavaKotlin.kt源文件中声明了所有函数和属性,包括扩展函数,都将编译成一个名为
com.liuhe.kotlin.JavaKotlinKt的Java类中的静态方法。

访问Kotlin属性

class KotlinClass {
    var id: Long = -1L
    var name: String = "kotlin"
    var isOpen: Boolean = true
    var isBig: String = "Y"

    @JvmField var no = 0
}

在Java中,一般字段会映射成set/get方法,以is开头的对应的规则(以isBig为例)是setXx,isXx。

调用实例字段

@JvmField注解对Kotlin属性字段标注,表示这是一个实例字段(Instance Field),Kotlin在编译时,不会给此字段生成Getters/Setters方法。

调用静态字段和方法

class KotlinClass {
    companion object {
        var innerId = "x001" // private

        @JvmField
        var innerName = "ABC" // public

        fun getClassInnerId() = "x001"

        @JvmStatic
        fun getClassInnerName() = "ABC"
    }
}
public class JavaDemo {
    public static final void main(String[] args) {
        String innerId = KotlinClass.Companion.getInnerId();
//        String innerId = KotlinClass.getInnerId();// error
        String innerName = KotlinClass.innerName;
//        String innerName = KotlinClass.Companion.getInnerName(); // error

        KotlinClass.getClassInnerName(); // ok
        KotlinClass.Companion.getClassInnerName(); //ok

//        KotlinClass.getClassInnerId(); //error
        KotlinClass.Companion.getClassInnerId(); // 唯一的调用方式
    }
}

Kotlin与Java的可见性

可见性修饰符

KotlinJava备注
privateprivate它只会在声明它的文件内可见
protectedprotected
internalpublic它会在相同模块内随处可见
publicpublic默认修饰符,意味着你的声明将随处可见

一个模块是编译在一起的一套 Kotlin 文件,可以认为是一个module。

Java访问权限

Kotlin类内部本包子类外部包
publicvvvv
protectedvvvx
defaultvvxx
privatevxxx

生成默认参数函数的重载

在kotlin中,一个函数中的参数如果设置了默认值,就可以重载调用,但是在Java中只能调用全参数的。如果在Java中也想重载调用,需要在Kotlin函数上加注解@JvmOverloads,这样编译器会针对此函数做特殊处理,生成多个重载函数。

Kotlin中:可以重载调用

fun f1(name: String = "name", age: Int = 10) {}

@JvmOverloads
fun f2(name: String = "name", age: Int = 10) {}

fun main(args: Array<String>) {
    f1()
    f1("xiaoming")
    f1("xiaoming", 15)
}

Java中:未加@JvmOverloads, 只能调用全参数的

JavaKotlinKt.f1("xiaoming", 12);
// JavaKotlinKt.f1("xiaoming"); // error!! 
JavaKotlinKt.f2("xiaoming");//ok

显示声明Kotlin中的异常

Kotlin中没有受检异常,比如下边定义的异常,虽然编译时未抛出异常,但是运行时候回抛异常。

object CheckKotlinException {
    fun thisIsException() {
        throw Exception("I am a Exception")
    }
}

Java中调用:

public static final void main(String[] args) {
    CheckKotlinException.INSTANCE.thisIsException();
}
Exception in thread "main" java.lang.Exception: I am a Exception
     at CheckKotlinException.thisIsException(JavaKotlin.kt:39)
     at JavaDemo.main(JavaDemo.java:23)

解决:使用注解@Throws(Exception::class),这样Java编译器就会检查此异常。

object CheckKotlinException {

    @Throws(Exception::class)
    fun thisIsException() {
        throw Exception("I am a Exception")
    }
}

Kotlin与Java简单实例对比

  1. for 循环

Java

for(String item : items)
for(Map.Entry<String,String> entry:map.entrySet())

Kotlin

for(item in items)
for((key,value) in map)
  1. 遍历

Java

HashMap<Integer, String> map = new HashMap<>(); 
map.put(1,"One"); 
map.put(2,"Two");
// Java7
for (String str : lists) {
    System.out.println(str);
}
// Java 8+
list.forEach(aa -> System.out.println(aa));

Kotlin

val map = mapOf(1 to "One", 2 to "Two")

listOf.forEach { println(it) }
  1. 函数定义

Java

void doSomething(int... numbers){
    // 实现
}

Kotlin

fun doSomething(vararg numbers:Int){
    // 实现   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值