比如如下 Java 类:
public class Person{
private String name;
private boolean married;
private int age;
......
}
在 kotlin 中调用 Person:
fun main(args:Array<String>){
val list = ArrayList<String>// 调用 Java 类 array list
list.add("hello")
list.add("world")
for(item in list){ // 快速迭代
println(item)
}
for(i in 0 until list.size){ // Range
println(list[i])
}
val person = Person()
person.age = 20 // 调用 Person 的 set 方法
person.isMarried = false // Boolean 属性的 set 方法稍有区别
person.name = "zhangsan"
println(person.age) // 调用 get 方法
println(person.isMarried) // Boolean 的 get 方法
println(person.name)
}
在 kotlin 中为了解决 Java 中所有引用类都是可空类型的问题,将所有来自于 java 的类型称为平台类型(platform types)。对这种类型kotlin 不再执行严格的非空检查。
val list = ArrayList<String>() // ArrayList 属于“平台类型”
list.add("victor") // 如果没有此句,则 list[0] 会导致下标越界
val size= list.size
val item = list[0] // item 的类型依赖于类型推断
val str: String? = item // item 可以为空
var str1: String = item // item 是一个平台类型,在编译期 Kotlin 放弃非空检查,所以不会报错,但是运行期有可能把 null赋给 str1从而出错
数组在 kotlin 中是不变
,即不支持协变/逆变(out/in)。但 java 不同:
public class MyTest{
public static void main(String[] args){
Object[] objects = new String[2]; // 产生协变。将一个 子类 赋给了父类。
objects[0] = 1; // 编译通过,但运行时异常。
objects[1] = 2;
}
}
Kotlin 中的数组更加安全,它不允许协变/逆变,你无法将一个 Array 赋给 Array(编译不通过)。数组参数也是如此。Java 中,允许将一个String[] 作为参数传给方法中的 Object[] 参数,而 kotlin 不行。除非这个方法是一个 Java 方法,这个时候可以将 Ar ray 传参给 Object[]。
在 java 中,原生类型数组,比如 int[] 可以降低装箱操作的性能开销。为了和 java 兼容,kotlin 提供了 IntArray,DoubleArray,CharArray 等原生类型数组(它们跟 Array 没有任何继承关系)来达到同样的目的。
Java 类:
public class MyArray {
public void myArrayMethod(int[] args){ // 原生数组
}
}
Kotlin 代码
fun main(args: Array<String>){
// 调用 java 方法
val myArray = MyArray()
val intArray = intArrayOf(1,2,3) // 返回一个 IntArray,避免装箱拆箱操作
val a = arrayOf(1,3,5) // Array<Int> 类型,对应 Java 的 Integer[]
myArray.myArrayMethod(intArray) // 用 IntArray 对应 java 的 int[]
array[0] = array[0]*2
}
kotlin 编译器会优化数组访问,从而降低性能开销。比如上面 array[0] = array[0]*2 这句并不会调用 get/set 方法,而是直接通过索引访问元素。
java 中可变参数实质上就是数组,即可以通过数组方式传参,也可以通过列表方式传参。
public class MyClass {
public void method( String... strings){}
}
在 kotlin 中调用这个方法必须要使用特殊的写法:
val myClass = MyClass()
val stringArrays = arrayOf("No 1", "over world")
myClass.method(*stringArrays)// java 的 String... 对应为 kotlin 的 String!
*
操作符叫做打散
操作,将一个String数组转变成 String! 类型。
Java 中存在两种异常:运行时异常和非运行时异常,但在 kotlin 中,只有运行时异常。如果 java 方法抛出了一个非运行期异常,
public class MyException {
public void method() throws IOException {
throw new IOException("I/O 异常");
}
}
在 kotlin 中调用该方法时,kotlin 不会强制要求你捕获这个异常:
val myException = MyException()
myException.mothod() // 编译通过
val clazz = MyException()::class.java // 获得实例对象对应的 java class
println(clazz) // 打印:class com.xxxx.yyy.MyException
另外一种方式:
val clazz = MyException().javaClass // 获得某实例对象对应的 java class
println(clazz) // 打印:class com.xxxx.yyy.MyException