「kotlin兼容java」kotlinnative
本篇文章给大家谈谈kotlin兼容java,以及kotlinnative对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
为什么 Kotlin 调用 java 时可以使用 Lambda
1. Kotlin 中的 Lambda 表达式
如果你已经开始使用 Koltin, 或者对它有过一些了解的话,那么一定对这种写法并不陌生了:
// 代码一:Kotlin 代码view.setOnClickListener{
println("click")
}1234
它跟下面这段 Java 代码是等价的:
// 代码二:java 代码view.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
System.out.println("click");
}
});1234567
和 Java8 一样,Kotlin 是支持 Lambda 表达式的,如代码一所示,就是 Lambda 的一个具体应用。
可见,使用 lambda 减少了很多冗余,使代码写起来更简洁优雅,读起来也更顺畅自然了。
但是,你有没有想过,为什么 Kotlin 可以这样写,这里为什么可以使用 lambda ?
2. 为什么可以这么写?
在 Kotlin 中,一个 Lambda 就是一个匿名函数。
代码一其实是对下面代码三的简写:
// 代码三:Kotlin 代码view.setOnClickListener({
v - println("click")
})1234
之所以简写成代码一的样子,是基于这两点特性:
如果 lambda 是一个函数的唯一参数,那么调用这个函数时可以省略圆括号
如果 lambda 所表示的匿名函数只有一个参数,那么可以省略它的声明以及-符号(默认会用it来给省略的参数名命名)
OK,从代码三的结构中,能够更清晰的看出,这里的 view.setOnClickListener 函数是接收了一个 lambda 作为参数。而在 Kotlin 中,什么样的函数才能把lambda(也即另一个函数)作为参数呢?
—— 对,就是高阶函数。
什么是高阶函数?
高阶函数是将函数用作参数或返回值的函数。
这是 Kotlin 和 Java 的区别之一,java 中并没有高阶函数的支持(java8是有高阶函数的)。当我们在 java 中需要用到类似的概念时,通常的做法是传递一个匿名类作为参数,然后实现其中的某些抽象方法 —— 就比如上面的代码二。
事实上,如果在 Android Studio 中,从 Kotlin 的代码查看 view.setOnClickListener 函数的定义,就会发现,看到的函数签名就是一个高阶函数的定义:
函数签名提示
如上图,所看到函数签名是:
public final fun setOnClickListener(l: ((v:View!)-Unit)!): Unit
当然,因为方法是在 Java 中定义的,所以它也列出了 Java 的声明,是这样:
public void setOnClickListener(OnClickListener l)
我们知道,Kotlin 跟 Java 的很多类型都有差异,所以它们在互相调用的时,会有一个按照对应关系的转换。
对于上面的对 setOnClickListener 方法的转换,别的地方都好理解,比较难懂的是,为什么会把参数从 OnClickListener 类型转换成了 (View) - Unit。
(View) - Unit 是一个函数类型,它表示这样一个函数:接收1个View类型的参数,返回Unit。
正是这个对参数类型的转换,使得 setOnClickListener 方法在 Kotlin 中变成了一个高阶函数,这样正是它之所以能够使用 lambda 作为参数的原因。
而这种转换,就是我们题目中所说到这篇文章的主角 —— SAM 转换 (Single Abstract Method Conversions)。
3. 什么是 SAM 转换?
好吧,说了这么多,终于到正题了。
SAM 转换,即 Single Abstract Method Conversions,就是对于只有单个非默认抽象方法接口的转换 —— 对于符合这个条件的接口(称之为 SAM Type ),在 Kotlin 中可以直接用 Lambda 来表示 —— 当然前提是 Lambda 的所表示函数类型能够跟接口的中方法相匹配。
而 OnClickListener 在 java 中的定义是这样的:
// 代码四:OnClickListener 接口在 java 中的定义public interface OnClickListener { void onClick(View v);
}1234
—— 恰好它就是一个符合条件的 SAM Type,onClick 函数的类型即是 (View) - Unit。所以,在 Kotlin 中,能够用 lambda 表达式 { println("click")} 来代替 OnClickListener 作为 setOnClickListener 函数的参数。
4. SAM 转换的歧义消除
SAM 转换的存在,使得我们在 Kotlin 中调用 java 的时候能够更得心应手了,它在大部分的时间都能工作的很好。
当然,也偶尔会有例外,比如,考虑下面的这段代码:
// 代码五public class TestSAM {
SamType1 sam1,;
SamType2 sam2,; public void setSam(SamType1 sam1) { this.sam1 = sam1;
} public void setSam(SamType2 sam2) { this.sam2 = sam2;
} public interface SamType1 { void doSomething(int value);
} public interface SamType2 { void doSomething2(int value);
}
}123456789101112131415161718
—— TestSAM 有两个重载的 setSam 方法,
—— 并且它们的参数( SamType1、SamType2 )都是 SAM Type 的接口。
—— 并且 SamType1 跟 SamType2 的唯一抽象方法的函数类型都是 (Int) - Unit 。
o(╯□╰)o
这种情况比较吊轨,但是还有有可能会出现的。这时候,如果在 Kotlin 中直接使用代码一类似的方式,就会报错了:
// 代码六:kotlin中调用,这段代码是编译不过的TestSAM().setSam {
println("dodo")
}1234
会提示这里歧义,编译器不知道这个 Lambda 代表是 SamType1 跟 SamType2 中的哪一个接口。
解决的办法就是手动标明 Lambda 需要代替的接口类型,有两种方式可以来标明:
// 代码七: 歧义消除// 方式一TestSAM().setSam (SamType1 { println("dodo") })
// 方式二TestSAM().setSam ({ println("dodo") } as SamType1)12345
当然,也还有一种方法是不再使用 SAM 转换的机制,而是直接使用一个 SamType1 的实例作为参数:
// 代码八: 使用一个实现接口的匿名类作为参数TestSAM().setSam(object : TestSAM.SamType1 { override fun doSomething(value: Int) {
println("dodo")
}
})123456
这种方法当然也是可以的,只是跟 lambda 相比起来,就显得不那么优雅了(优雅很重要!!!)。
5. SAM 转换的限制
SAM 转换的限制主要有两点 :
5.1 只支持 java
即只适用与 Kotlin 中对 java 的调用,而不支持对 Kotlin 的调用
官方的解释是 Kotlin 本身已经有了函数类型和高阶函数等支持,所以不需要了再去转换了。
如果你想使用类似的需要用 lambda 做参数的操作,应该自己去定义需要指定函数类型的高阶函数。
5.2 只支持接口,不支持抽象类。
这个官方没有多做解释。
我想大概是为了避免混乱吧,毕竟如果支持抽象类的话,需要做强转的地方就太多了。而且抽象类本身是允许有很多逻辑代码在内部的,直接简写成一个 Lambda 的话,如果出了问题去定位错误的难度也加大了很多。
6. 总结
OK,讲完了。
总结起来就是 SAM 转换就是 kotlin 在调用 java 代码时能使用 Lambda 的原因。了解了其原理,能够让我们在写代码更自如,在偶尔出问题的时候也能更好更快地解决。
kotlin真的会代替java吗?
暂时来说不会。kotlin是兼容java,没有java他什么都不是。
后面的话说不准。
kotlin教程 kotlin教程简介
1、Kotlin是一门很新的编程语言,由JetBrains公司开发,JetBrains估计大部分开发者都认识,是专业开发IDE的,旗下的PyCharm和IDEA都是现在很热门的编辑器。
2、Kotlin的来历:Java代码臃肿,开发效率不够高,JetBrains开发的kotlin,目的是兼容并替代java,可以运行在jvm上,而且语法简洁,可以大量降低程序员的工作量。
3、主要时间线:kotlin是2010年推出,2011年开源,谷歌在2017年I/O大会宣布,kotlin成为安卓支持的一级官方语言,Android-Studio 3.0正式支持kotlin(此前版本可以通过安装插件实现支持)。
4、开源:kotlin是通过Apache协议开源的,Apache是一个非盈利的开源组织,可以下载kotlin的源码进行深入研究。
5、可以运行在jvm,100%兼容java:java曾经占开发语言的三分一活跃度,曾经用java写的功能,累计下来已经不计其数,kotlin可以兼容java,说明即使用kotlin作为开发语言,也可以调用以前用java写的程序。
kotlin-反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
常用API
使用demo
Kotlin 的反射需要集成 org.jetbrains.kotlin:kotlin-reflect 仓库,版本保持与 kotlin 一致 。
在Kotlin中,字节码对应的类是kotlin.reflect.KClass,因为Kotlin百分之百兼容Java,所以Kotlin中可以使用Java中的反射,但是由于Kotlin中字节码.class对应的是KClass类,所以如果想要使用Java中的反射,需要首先获取Class的实例,在Kotlin中可以通过以下两种方式来获取Class实例。
获取了Class实例,就可以调用上面介绍的方法,获取各种在Java中定义的类的信息了。
当然Kotlin中除了可以使用Java中的反射以外,还可以使用Kotlin中声明的一些方法,当然同Java中反射一样,想要使用这些方法,先要获取Kclass对象,在Kotlin中可以通过以下两种方式获取Kclass实例。
常用API
使用demo
详细demo跳转此处观看
关于kotlin兼容java和kotlinnative的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。