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方法

  1. getClass()

获取对象的Java类。

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

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

### 关键字冲突
> 一些Kotlin的关键字是Java中的有效标识符,比如inobjectis等,使用反引号(')字符转义,一般IDE自动添加了。

Kotlin中调用:

fun main(args: Array) {
JavaDemo.is()
}

Java中方法:

public static boolean is() {
return true;
}

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

Kotlin中:

fun emptyList(): List = 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的可见性

[可见性修饰符](https://www.kotlincn.net/docs/reference/visibility-modifiers.html)
Kotlin  | Java | 备注
---|---|--
private | private |它只会在声明它的文件内可见
protected | protected |
internal | public | 它会在相同模块内随处可见
public | public |默认修饰符,意味着你的声明将随处可见


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

Java访问权限

Kotlin  | 类内部 | 本包 | 子类 | 外部包
---|---|---|---|---
public |v|v|v|v
protected|v|v|v|x
default|v|v|x|x
private|v|x|x|x


### 生成默认参数函数的重载
在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) {
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){
    // 实现   
}

猜你喜欢

转载自blog.csdn.net/liuhedev/article/details/80081853