Kotlin学习笔记 第四章Kotlin调用Java

2021/9/17 22:06:35

本文主要是介绍Kotlin学习笔记 第四章Kotlin调用Java,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

参考链接

Kotlin官方文档

https://kotlinlang.org/docs/home.html

中文网站

https://www.kotlincn.net/docs/reference/properties.html

pdf也可以在这里下载

https://www.kotlincn.net/docs/kotlin-docs.pdf

大部分示例来自bilibili Kotlin语言深入解析 张龙老师的视频

Kotlin调用Java

Part1

知识点

1 调用Java model类

2 平台类型

3 Kotlin调用Java时的空检查变得松动

笔记

Java类:

public class People {
    private String name;
    private int age;
    private boolean married;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMarried() {
        return married;
    }

    public void setMarried(boolean married) {
        this.married = married;
    }
}

Kotlin类

// Kotlin调用Java
fun main() {
    val list = ArrayList<Any>();
    list.add("hello")
    list.add("world")
    list.add("hello world")

    for (item in list) {
        println(item)
    }
    println("-----------")
    for (i in 0 until list.size) {
        println(list[i])
    }
    println("-----------")

    // 调用Java model类
    val people = People()
    people.age = 25
    people.isMarried = false
    people.name = "zhangsan"
    println(people.age)
    println(people.isMarried)
    println(people.name)
    println("-----------")
    /**
     * Kotlin调用Java代码时 Kotlin的空检查可能会失效
     *
     * 在Java中 所有引用都可能为null 在Kotlin中 对null有着严格限制
     * 在Kotlin中 将来自Java的声明类型称为平台类型(Platform Types)
     * 对于这种类型(平台类型)来说 Kotlin的null检查会变得缓和 不再那么严格.
     * 这么做的目的是使得空安全的语义在Java和Kotlin中保持一致
     * 当我们调用平台类型引用的方法时 Kotlin就不会在编译期间施加空安全检测 使得编译可以通过
     * 但是在运行时可能抛出异常 因为平台类型的引用值可能为空
     */

    // 当我们调用平台类型引用的方法时 Kotlin就不会在编译期间施加空安全检测 demo
    // ArrayList是一个平台类型 可以看它的定义 不过是Java ArrayList的一个别名
    // ArrayList是一个平台类型 Kotlin不会对其施加严格的空检查 list2[0]可能报错
    val list2 = ArrayList<String>()
    //list2.add("hello")
    val size = list2.size
    val item = list2[0] //数组越界
    // 是否是平台类型由Kotlin编译器自己识别 无法主动创建一个平台类型

    val s: String? = item // 允许
    // 为什么s2是一个非空类型的String 却可以将其赋值为一个可能为空的item? 因为这是一个平台类型 Kotlin的检查不再严格
    val s2: String = item // 允许 但是运行时可能报错(如果item为空)

    // kotlin 非空检查的原理: 如果声明一个非空类型 则会在该变量赋值时产生一个断言 断言赋值不为空 如果断言失败 则编译期就报错
    /**
     * 如果我们使用了不可空的类型 编译器会在赋值时生成一个断言。这会防止Kotlin的不可空变量持有一个null值;这一点也适用于方法的参数传递
     * 我们在一个平台类型值传递到不可空的参数或方法参数时 也同样会生成这个断言 但是该断言只能检测明显空的情况
     *
     * 总体来说 Kotlin会竭尽所能防止null赋值蔓延到程序的其他地方 而是在问题发生时就立刻通过断言来解决
     */
}

class D0508KotlinCallJava {
}

Part2

知识点

1 对比Java与Kotlin的数组

详情参见Java类MyTest 与Kotlin类 D0508KotlinCallJava2种 objects的定义

2 Kotlin类调用Java的普通方法

3 使用下标访问数组更快捷

4 Kotlin类调用Java的可变参数的方法

笔记

Java class *2

// 配套在D0508KotlinCallJava2
public class MyArray {
    public void myArrayMethod(int[] args) {
        for (int a : args) {
            System.out.println(a);
        }
    }

    public void myArrayMethod2(String... strings) {
        for (String a : strings) {
            System.out.println(a);
        }
    }
}

public class MyTest {
    public static void main(String[] args) {
        Object [] objects = new String[3];
        // Java的数组设计的是有问题的
        // 这里声明的是Object数组 因此可以放入任意类型
        // 然而它实际指向的是一个String数组 因此运行时报错
        objects[0] = 1;
        objects[1] = "aaa";
    }
}

Kotlin class

/**
 * Java与Kotlin在数组 上的区别
 * Kotlin中的数组是不变的(相对于协变和逆变) 这一点和Java不同(Java是协变的)
 * 因此 Java的数组设计是有问题的
 * 这意味着 我们无法将Array<String> 赋值给Array<Any> 可以避免运行时异常
 *
 * Kotlin提供了原生类型数组来比卖你自动装修拆箱带来的成本:IntArray,DoubleArray,CharArray...
 */
fun main() {
    // 1 对比Java与Kotlin的数组
//    val objects:Array<Any> = Array<String>(4,{_-> "AA"})//Type mismatch.
    val objects: Array<Any> = Array<Any>(4, { _ -> "AA" })//Type mismatch.
    objects.forEach { println(it) }

    // Array相当于Java里面的ArrayList<xx>
    // 而IntArray DoubleArray CharArray等相当于Java里面的int [], double[], char[]等等
    // An array of ints. When targeting the JVM, instances of this class are represented as int[].
    val intArr = IntArray(4) { 0 }
    println("-------1 end-------")

    // 2 调用Java的方法
    val intArr2 = intArrayOf(1, 2, 3, 4)
    val myArray = MyArray()
    // 注意这里的需求类型是平台参数类型 args : IntArray!
    myArray.myArrayMethod(intArr2)
    println("-------2 end-------")

    // 3 使用下标访问数组更快捷
    val array = arrayOf(1, 2, 3, 4, 5)
    array[0] = array[0] * 2 // 使用下标访问数组 不会调用数组的get set方法 使得访问更快捷
    array.forEach { println(it) }
    println("-------3 end-------")

    // 4 调用Java的可变参数方法
    val myVarargs = MyArray()
    val stringArray = arrayOf("hello","world","hello world")
    myVarargs.myArrayMethod2(*stringArray)
}

class D0508KotlinCallJava2 {

}

Part3

知识点

1 调用Java异常的方法

2 打印Java Class

笔记

Java class

import java.io.IOException;

public class MyException {
    public void myMethod() throws IOException{
        throw new IOException("I/O 异常");
    }

    // 可以看到在Java内部调用会抛出异常的Java方法 需要对异常进行处理
    public void callExceptionMethod(){
        try {
            this.myMethod();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Kotlin class

fun main() {
    // 1 Kotlin调用Java 异常
    val exception = MyException()
    // 取消如下可以看到 调用Java的需要处理异常的方法 Kotlin不需要对异常进行处理
    // exception.myMethod()

    // 2 查看Java class类的2种方式
    println(MyException()::class.java)
    println(MyException().javaClass)
}

class D0508KotlinCallJava3 {

}



这篇关于Kotlin学习笔记 第四章Kotlin调用Java的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程