kotlin调用java

来源:互联网 发布:java redis队列使用 编辑:程序博客网 时间:2024/05/29 08:17

在第一篇博客中,介绍了kotlin的入门,这次介绍kotliin与java的交互。

Jetbrains公司在设计kotlin时就将其设计成与java互操作性良好的语言。现有的java代码能够很自然地被kotlin调用,反过来kotlin代码也能够顺利被java调用。

import java.util.*fun demo(source: List<Int>) {    val list = ArrayList<Int>()    // for循环对于java集合也同样奏效    for (item in source) {        list.add(item)    } // 赋值操作也能起作用    for (i in 0..source.size - 1) {        list[i] = source[i] // get和set方法被调用    }}

Getter和Setter方法

遵守java语法规范的getter和setter方法在kotlin中被当做属性。

import java.util.Calendar fun calendarDemo() {     val calendar = Calendar.getInstance()     if (calendar.firstDayOfWeek == Calendar.SUNDAY) { //调用getFirstDay()方法        calendar.firstDayOfWeek = Calendar.MONDAY  //调用setFirstDay()方法    } }

注意,如果java类只有一个setter,那么其不会被当作一个可见属性,因为目前kotlin不支持单set属性。

没有返回值的方法

如果一个java方法返回void,那么当kotlin调用时会返回Unit。如果偶然有人用到了那个返回值,kotlin编译器会在调用方就为其赋值,因为它就是Unit。

某些kotlin中的关键字是java的合法标识符,例如in,object,is等.如果一个java类库用到了kotlin关键字作为方法名,你仍然可以通过“符号包住方法名来调用该方法

foo.`is`(bar)

java中的任何引用都可能为null,这使得kotlin对空值安全的严格检查对于来自java的对象来说并不适用。java中声明的类型在kotlin中被特别对待,称为平台类型(platform types)。空值检查对于这种类型比较宽松。

当调用平台类型的变量或方法时,kotlin在编译阶段不会报空值错误,但是在运行阶段可能会失败,因为kotlin产生的空值异常,即断言防止空值继续传播:

item.substring(1) //编译通过,如果item==null会抛出异常

kotlin对待某些java类型很特殊。有些类型并不是从java装载时的那样,而是映射成了对应的kotlin类型。这种映射只在编译阶段起到作用,在运行阶段仍然不发生改变。java的基础类型被映射为对应的kotlin类型。

  java类型      kotlin类型     short        kotlin.Short   int          kotlin.Int    long         kotlin.Long    char         kotlin.Char    float        kotlin.Float   double       kotlin.Double   byte         kotlin.Byte    boolean      kotlin.Boolean

一些不是基本类型的内置类型也同样被映射:

        java类型                  kotlin类型         java.lang.Object            kotlin.Any!        java.lang.Cloneable         kotlin.Cloneable     java.lang.Comparable        kotlin.Comparable!    java.lang.Enum              kotlin.Enum!       java.lang.Annotation        kotlin.Annotation!    java.lang.Deprecated        kotlin.Deprecated!    java.lang.CharSequence      kotlin.CharSequence!   java.lang.String            kotlin.String!      java.lang.Number            kotlin.Number!      java.lang.Throwable         kotlin.Throwable! 

java的数组被映射为以下类型:

   java类型            kotlin类型             int[]         kotlin.IntArray!        String[]    kotlin.Array<(out) String>!

kotlin中的java泛型

kotlin的泛型和java有一点区别.

-java的通配符(wildcards)被转换为类型投影:

-Foo<? extends Bar>成为 Foo<out Bar!>!-Foo<? super Bar>成为 Foo<in Bar!>!

-java的原生类型(raw types)被转换为星号投影:

-List成为List<*>

和java类型,kotlin的泛型在运行时刻不再保留,例如,对象不再携带传入他们构造器中的实际类型信息,因此ArrayList()和ArrayList()没有区别。因此带入泛型的is检查不能实现,kotlin只允许对星号投影泛型类型的is检查

if (a is List<Int>) //错误:不能检查是否是Int的列表if (a is List<*>) //允许:但是不保证列表的内容

java的变长参数

java类有时候使用可变长的方法参数

public class JavaArrayExample {       public void removeIndices(int... indices) {          //实现代码    }   }

在这种情况下需要实用展开运算符*来传递int数组:

val javaObk=JavaArray()val array=intArrayOf(0,1,2,3)javaObj.removeIndicesVarArg(*array)

目前还不能将null传入带用可变长度参数的方法中

受检异常

在kotlin中,所有的异常都是非受检的,这意味着编译器不强迫你去捕获他们。当你调用一个声明受检异常的java方法时,kotlin不会强迫你做任何事:

fun render(list:List<*>,to:Appendable){  for(item in list){    to.append(item.toString()) //java代码在这里要求捕获IO异常  }}

在kotlin中使用JNI

声明一个利用c或c++实现的本地方法,你需要用external标识符标注:

external fun foo(x:Int):Double

剩下的流程和java一样的方式进行

参考链接:kotlin官方文档

原创粉丝点击