在第一篇博客中,介绍了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
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[] Array!
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官方文档
















