Kotlin是啥

Kotlin是一门JVM上的,与Java完美互操作,简洁、易读、安全、通用为设计目标,同时支持面向对象和函数式两种编程范式,高质量的现代静态类型语言。或者换一句话,是集成了Java(面向对象,强大生态),C#(美妙的扩展方法),Ruby(魔法般的Code Block),Scala(函数式编程,克制的运算符重载,易用版Trait)等众多语言优点的高性能的美妙语言。

Kotlin「简历」

  • 来自于著名的IntelliJ IDEA的软件开发公司 JetBrains (位于东欧捷克)
  • 起源来自 JetBrains 的圣彼得堡团队,名称取自圣彼得堡附近的一个小岛 (Kotlin Island)
  • 一种基于 JVM 的静态类型编程语言

增长情况

有啥亮点

安身立命之本--互操作性和Java生态

  • 无缝引入到现有java项目
  • java -> kotlin ✔️
  • kotlin -> java ✔️

安卓阵营的拯救者

  • 谷歌和Oracle的Java侵权案
  • 安卓Dalvik虚拟机智能使用jdk7以下api
  • kotlin被谷歌钦定官方推荐语言

编写更安全、易读的代码

var a: String = “abc”; // 定义个一个非null的字符串变量a
a = null; // 编译直接失败

var b: String? = “abc”; // 定义一个可为null的字符串变量b
b = null; // 编译通过

val l = b.length; // 编译失败,因为b可能为null
l = b?.length ?: -1 // 如b为null,就返回-1
l = b?.length; // 如b为null,就返回null
l = b!!.length; // 如b为null,就会直接抛NPE错误
b?.let { println(b) } // 如b为null,就不执行let后面的代码块

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull() // 过滤出列表中所有不为null的数据,组成新的队列intList

// 可以通过lateinit var(不可为val),定义一个无需在申明时初始化的non-nullable的参数,这个参数不允许被赋值为空,并且在调用时如果没有初始化会抛异常
lateinit var lateInitValue : String

// 通过by lazy { ... } 表达式,让所定义的参数在第一次访问(get)的时候执行{...}这段代码块,并赋值
val lazyValue: String by lazy {
  doAnything()
  "build lazy value"
}

// 可以直接在赋值中使用表达式,甚至内嵌执行语句
val max = if (a > b) a else b	// 三元表达式
val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

// 支持when的表达式
println(when (language) {
    "EN" -> "Hello!"
    "FR" -> "Salut!"
    else -> "Sorry, I can't greet you in $language yet"
})

// 支持in,表达在一定的范围内作为条件
when (x) {
    in 1..10 -> print("x is in the range")
    in validNumberArray -> print("x is valid")
    else -> print("none of the above")
}

数据类

一行代码搞定 pojo, 自动生成 get/set/toString, 类似 lombok 插件

data class User(val name: String, val age: Int)

更好用的函数式编程

  • 原生支持的不可变对象
  • 更好用的lambda表达式,且性能更高(提升30%)
  • 比jdk8 stream api更好用的集合操作
val numbers = arrayListOf(-42, 17, 13, -9, 12) //创建一个List,并给定值
val nonNegative = numbers.filter { it >= 0 } //从numbers中过滤出>=0的队列

listOf(1, 2, 3, 4) // 列出 1, 2, 3, 4
.map { it * 10 } // 所有值乘以10 10, 20, 30, 40
.filter { it > 20 } // 过滤出>20的值 30, 40
.forEach { print(it) } // 打印出每个值 30, 40

非受检异常

unchecked exception,可以自己决定在调用栈的某一层 catch 和处理,不必到处 try-catch

字符串模板

val s = "abc"
val str = "$s.length is ${s.length}" // 结果为 "abc.length is 3"

val x = 4
val y = 7
print("sum of $x and $y is ${x + y}")  // sum of 4 and 7 is 11

类似一个更智能、更易读的Java版本的String.format()

类扩展

fun MutableList<Int>.swap(index1: Int, index2: Int) { 
    val tmp = this[index1] // 'this' 对应该列表 
    this[index1] = this[index2]
    this[index2] = tmp
    }
}
//使用
val l = mutableListOf(1, 2, 3)
l.swap(0, 2) // 'swap()' 内部的 'this' 得到 'l' 的值

免费的午餐--性能无损

Kotlin增加特性的同时,没有降低性能,部分benchmark中相比java还有微弱的性能提升,马儿跑得更快还吃的更少。

Kotlin运行时性能

DSL——去敌人的地盘吃鸡

Kotlin因为其灵活的语法(比如可以重定义运算符),适合用来写DSL,比如:用Kotlin写HTML模板,anko 安卓绑定控件类库。

kotlin协程

  • kotlin 1.3发布了稳定版的协程
  • 让原本需要异步+回调的才能获得高性能的场景,可以通过使用看似同步的方式来编写代码
  • java平台上,在loom项目推出之前,最容易体验到协程遍历的途径

Coroutine的四大金刚操作:launch, runBlocking, async和await。

  • launch。launch最简单,只负责启动,启动完就不管了,既不等待结束,也不关心结果。
  • runBlocking。runBlocking在运行代码块之后会阻塞当前coroutine,直到代码块运行完成,然后获取结果。
  • async和await。launch和runBlocking都相对简单,如果我要启动coroutine,然后立马返回,但是又想关心结果怎么办呢,用async。async会返回一个Deferred,T是结果类型,然后你可以做别的,需要的时候,用Deferred上的await()函数来等待结果。注意await()本身也是suspend函数,你需要把它放在coroutine里面(launch,runBlocking,async调用的代码块)里面,或者将代码所在的函数标为suspend。

四大金刚操作的比较:

回调 vs 响应式编程 vs 协程

  • node.js
  • reactive
  • coroutine

如何在项目中使用kotlin

  • idea(或eclipse)较新的版本+kotlin插件
  • 添加kotlin依赖
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jdk8</artifactId>
    <version>${kotlin.version}</version>
</dependency>
  • 混合编程

现阶段的不足

  • ide代码提示还会有些卡顿
  • 与lombok不兼容(看不到lombok增强后的方法)

相关资料

代码review

  • 正反向关系表同步,逆向表查询索引,根据id回主表查询。(新加坡vpc有精卫环境)
  • lombok标记Data类,另外可选kotlin的data对象
  • 使用pandora boot。定制了一个消费多个topic的MultiMetaqListener
  • jdk8新特性,stream
  • kotlin混合编程
  • 改良版geo hash简单介绍
  • lwp、hsf接口测试方案