参考链接
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 {
}