对Kotlin的一次小调研
本文主要内容
1,Kotlin简单介绍一下
2,Android Developer意见了解一下
3,Android Stuido Kotlin Plugins环境搭建及配置
4,Kotlin常见语法糖(这个糖有点儿甜)
5,Kotlin与Java的相互调用
1,什么是Kotlin
Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。
Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。
JetBrains,作为目前广受欢迎的Java IDE IntelliJ 的提供商,在 Apache 许可下已经开源其Kotlin 编程语言。
Kotlin已正式成为Android官方支持开发语言。
(节选自百度百科)
2,Android Developer关于Kotlin的看法
此前,我在"开源中国"上看到过一篇关于国外Developer对于Kotlin的看法的文章,感觉里面很多大神分析的挺有道理的,虽然是基于Kotlin早起的版本,但是其中的一些观点挺值得我们去了解一下.
17 位谷歌 Android 开发专家是如何看待 Kotlin 的?
(不知道为什么link的链接被简书添加了 link.jianshu.com导致无法跳转,地址如下:
https://www.oschina.net/news/85468/what-do-17-google-developers-experts-for-kotlin)
但是,我们是在国内,更多的时候要考虑国内Developer的一些看法,对此,我请教了技术群中的一些朋友,他们其中有的人正在用,有的人正在考虑用,有的人在观望,以下,是他们的一些看法,考虑到隐私相关,涉及到公司名称部分的已经隐去,排名不分先后
深圳市Android开发工程师-Arthas·李(谨慎观望):
我觉得吧,相比Java而言,代码更简洁,清晰,会有一阵子的新鲜,但是实际上.只是非常少一部分人会用吧。�也许再过个一年半载,热度就下去了,具体要看谷歌爸爸给不给力推。
广州市Android开发工程师-Terenas Menethil 颜(看好):
Kotlin能简化大量的无用代码,有效的避免的空指针。
代码可读性高,方便了团队成员维护,降低了成本。
计划在下个项目中引用,但是还是要看实际情况(人员,三方库支持)。
上海市Android开发工程师-flyinbed(在用)
Kotlin具有现代化静态编程语言的很多特点,并大大的减少了重复代码,提高了编程效率,让代码逻辑更加清晰。
我就觉得 Java 这样“冗长”的语言应该慢慢退出历史舞台了,本来几行代码就能写出了逻辑,换成java可以写出20多行左右。
历史的巨轮滚滚向前,终究我们编码会是越来越简洁,工作量越来越少。
3 AS Kotlin Plusgins配置
(基于AS 3.0+)
①新建项目:
直接选中include Kotlin support即可
一路Next->Finish之后,就可以看到新建的MainActivity已经是.kt格式了
②已有Java项目的转换
直接在Tools菜单中config
选中对应的module或All modules
IDE会自动生成对应的code(module中的.gradlew也会自动配置)
更简单的做法
直接在java code下创建一个.kt文件,AS会提示需要configure,之后的流程就跟之前一样
③java文件转换成kotlin文件
AS中,自带了可以转换.java文件到.kt文件的插件,部分Java代码是可以直接通过这个转换替换成.kt的Code,但是,其中也会有很多坑,需要具体情况具体分析才行
④查看Kotlin代码生成的字节码文件和编译成的.java文件(仅供参考)
点击即可生成.java文件(反编译得到,有时候看不懂Kotlin代码可以参考一下)
4 Kotlin常见方言
①不再需要的findViewById
告别findViewById,kotlin会自动生成View相关的code(名称为布局的id),不再需要我们手动findViewById了(实现可看反编译的.java文件),同时点击变量可以自动跳转到布局,不局限于Activity,自定义View中也可以这样使用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
main_btn_hw.setOnClickListener(this)
main_btn_basic1.setOnClickListener(this)
main_btn_basic2.setOnClickListener(this)
}
②更灵活的字符串
直接通过$号引用属性或${}区间引用对象方法,通过反编译代码可以看到,这一实现过程的拼接是通过StringBuild实现,不需要担心产生额外多的对象问题
fun visibleStrCode() {
val a = "a"
val b = "b"
val c = "c"
val d = "d"
val v = arrayListOf<String>()
val alphabet = "a : $a -b : $b - c : $c - d : $d -- ${returnStr()}"
val sizeStr = "size is ${v.size}"
}
③Null Pointer Exception
只要一个对象或变量没有被显式的声明可以为null,那么之后所有null的赋值都被视作是非法的,无法通过编译,对非null值做判空,会有warning提示
fun visibleNPEMethod() {
var nullA2: A? = null
var notNullA1 = A()
notNullA1 = nullA2 //不可被赋予一个null对象
notNullA1 = null //不可赋值为null
if(notNullA1 == null){//warning
}
println(notNullA1.myStr)
//使用一个null对象,需要显式的做空判断,否则会视作是非法的,无法通过编译
println(nullA2.myStr)
//可以通过字面值? Elvis 运算符来表示,赋值给一个不能为null的属性,
//在此时要显示指定一个默认值
//赋值给一个不能为null的值,
val a3: A = nullA2 ?: A()
//但是不能这样访问属性
val str: String = nullA2?.myStr : "null"
//!! 忽略这个空判断,有空指针危险
val str2 : String = nullA2!!.myStr
//判空后会视作不为null的对象
if (nullA2 != null) {
println(nullA2.myStr)
//①
if (nullA2 != null) {//后续无需判空,会有warning警告
//do something
}
//②使用let函数,这样保证其中不为null
nullA2.let {
//这里it指向的就是nullA2
it.myStr
}
}
}
对于一个可能为null的对象,在上面的代码,是有一些需要注意的细节
④更方便的类型转换
is 关键字,当某个对象通过is关键字进行类型判断后,可以在之后的区间内直接当做对应对象类型做处理,例如使用相关的方法
搭配When关键字会更好用
fun classCastMethod(superClz: SuperClz) {
when (superClz) {
is A -> {
superClz.getA()
}
is B -> superClz.getB()
is C -> superClz.getC()
}
if (superClz is A) {
superClz.getA()
}
}
这里的ABC,分别是一个类,类中独有的方法就是getX()
⑤更实用的Bean(data数据类)
使用data关键字修饰的class类
会自动生成set,get,copy,equals等方法
不用再像java一样显式的重写
同时还可以方便的使用组成方法
当然,如果有需求也可以重写进行覆盖
data class Thai(val name: String, var sex: Int)
就这样一个简单的类,在我们使用可以很方便的获取一些信息:
@Test
fun testDataClz() {
val man = 1
val woMan = 2
val unknow = 3
//有一个泰国人,性别男
var aTiChaSir = Thai("阿提查*春娜依", man)
//转换一下
val aTiChaLady = aTiChaSir.copy(sex = woMan)
//快速获取属性
val (name1, sex1) = aTiChaLady//这里获取的属性不是通过名字,而是属性顺序
println("sex:$name1 --name:$sex1")
}
⑥延迟加载lazy
Kotlin允许对一个属性进行延迟加载,使用by操作符+lazy函数可以进行
值得注意的是,这一操作只允许对val修饰的属性
可选:可以指定是否线程安全(默认)
NOTE:PUBLICATION:允许多个结果的可能返回,但只取第一个结果
//延迟加载,必须是val修饰
//只会执行一次,
//可选:线程是否安全
val lazyStr: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
println("lazy init method")
"I'm a lazyStr"
}
Test结果:
@Test
fun testLazyMethod() {
println(ClassCastClz.lazyStr)
println(ClassCastClz.lazyStr)
}
⑦With关键字,更方便的方法调用
使用该关键字可以在一定区间,可以很方便的调用该对象的方法和属性,就像在这个方法中一样
@Test
fun testKeywordWith() {
val withClzObj = KeyWith()
with(withClzObj) {
println(numberProperty + 100)
preper()
onCreate()
onStart()
onResume()
}
}
⑧lambda表达式
fun lambdaMethod() {
//显式指定名称
val viewClickListener = View.OnClickListener {
// myView: View? -> //可选,重写对应的参数,指定名称,默认为it
// if(myView != null){
// println(myView.id)
// }
println(it.id)
}
//不指定名称,交给编译器去解析
val anonymityClickListener = { v: View? ->
if (v != null) {
println(v.id)
}
}
val v = View(null)
v.setOnClickListener(anonymityClickListener)
}
}
这里用View.onClickListener做示例
主要写法有两种,�①显式的指定lambad表达式类型
②交给编译器去推断,需要注意的是,交给编译期,需要参数对应,类型一致否则无法正确的解析
⑨类扩展方法
Kotlin支持对一个类进行额外的方法拓展,这使得你在使用该类可以不用再创建额外的子类来扩展其方法,无缝使用,更方便(当然,也支持类的属性扩展)
接收者是可以为?,表示可以为null的类型,这样的话,在设计扩展方法时,能有更灵活的code编写
我这里写了几个简单的栗子
/**
* 拿到文本的高度
*/
fun TextView.getTextHeight(): Float {
//可以直接获取到该类的属性
val fontMetrics = paint.fontMetrics
return fontMetrics.bottom - fontMetrics.top;
}
/**
* 字符串是否是null
*/
fun String?.isNullStr(): Boolean {
return this == null || "" == this || "null" == this
}
/**
* 集合是否是空
*/
fun List<*>?.isNullEmpty(): Boolean {
return this == null || this.isEmpty()
}
/**
* 通过Context直接拿Dimension
*/
fun Context.getDimension(resId : Int):Float{
return this.resources.getDimension(resId)
}
5,Kotlin与Java代码的相互调用
这可是Kotlin的一大卖点!!!
这里简单介绍一下Java调用Kotlin,前文中Kotlin调用Java已经出现过很多次,不再累赘了
基本可以做到无缝调用
但是值得注意的是,在java代码中调用Kotlin代码,部分特性会不再支持
比如:空安全
public void method() {
//扩展方法可以直接看做一个 static final修饰的方法
boolean isNull = ExtendMethodListKt.isNullStr("aabb");
//对象可以直接创建
LambdaClaz ccc = new LambdaClaz();
//调用属性需要调用对应的set,get方法
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
}
};
ccc.setMyClickListener(clickListener);
View.OnClickListener runnableInherit = ccc.getMyClickListener();
//伴生对象可以直接看做一个静态对象
LambdaClaz.Companion.lambdaMethod();
}
6小结
以上就是我这段时间关于Kotlin的一次小小的调查,文中很多代码比较简单,随心写的一些code,就没有传项目到GitHub上了,如果有所疑问,欢迎在评论区中留言探讨.
对于Kotlin,我个人的看法:
五级评分,Level4,看好,如果在项目有机会,我会考虑使用