深入kotlin - 与Java互操作:kotlin调用java

Posted 颐和园

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入kotlin - 与Java互操作:kotlin调用java相关的知识,希望对你有一定的参考价值。

Kotlin 调用 Java

比如如下 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() // 编译通过

获取对象的 java 类

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

以上是关于深入kotlin - 与Java互操作:kotlin调用java的主要内容,如果未能解决你的问题,请参考以下文章

深入kotlin - 与Java互操作:kotlin调用java

深入kotlin - 与Java互操作:kotlin调用java

深入kotlin - 与Java互操作:kotlin调用java

深入kotlin - 与Java互操作:java调用kotlin

深入kotlin - 与Java互操作:java调用kotlin

深入kotlin - 与Java互操作:java调用kotlin