- 首先个人认为最重要的一点是能够和
Java100%的兼容.
例如下面有一段 Java 代码
/**
* Created by dongyayun on 2016/11/29.
*/
public class CustomerJava {
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int id;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomerJava that = (CustomerJava) o;
if (id != that.id) return false;
return name != null ? name.equals(that.name) : that.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "CustomerJava{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public CustomerJava(int id, String name) {
this.id = id;
this.name = name;
}
}
下面我们在 Kotlin 代码里可以直接调用 Java 代码
/**
* Created by dongyayun on 2016/11/29.
*/
fun main(args: Array<String>) {
println(CustomerJava(1, "Java").toString())
}
输出如下结果 
接下来, 我们用Kotlin写一段同样功能的Customer类, 看看只需要多少行代码.
data class CustomerKotlin(val id: Int, var name: String)
是的, 只需要这一行就可以达到和Java五十多行一样的效果.
运行结果如下 
另外,大家可能已经注意到, Kotlin 不需要写分号,不需要写分号,不需要写分号.
- 其次个人比较喜欢的一点就是, 可以在
Java7上体验到Java8的新功能, 例如lambda表达式. 例如这段代码
var numberList = 1..100
numberList
.filter { it % 2 == 0 }
.map { it * 10 }
.forEach(::println)
这段代码中,var 表示定义一个可变的属性 numberList, 如果用val来定义, 那么 numberList 就不可以再次被赋值. 接着往下看, 1..100 表示1到100的列表. 注意看, 我在定义 numberList的时候并没有写它的类型, 那是因为 Kotlin 能够根据上下文自动辨别属性的类型.
简直不能太贴心~~~
接着就是lambda表达式出场了. 这里依次用了三个操作符, 分别是
- filter 过滤器. 根据
{ }里面的表达式对numberList进行过滤 - map 转换符, 将 1里过滤好的元素在进行转换, 这里是挨个乘10
- forEach 遍历经过1,2之后的numberList, 然后按照
{}里的语句进行输出打印
看起来简单吧,仅仅三条语句就做到了将1到100的数字过滤成能被2整除然后在乘10的数字列表然后在打印出来。
接下来,我们来看一个厉害的 Higher-Order Functions Higher-Order Functions 就是Kotlin允许一个函数将另外一个函数作为参数. 例如这段代码
fun add(a: Int, b: Int): Int {
return a + b
}
fun highOrderFunctions(int1: Int, int2: Int, operater: (x: Int, y: Int) -> Int): Int {
return operater(int1, int2)
}
fun main(args: Array<String>) {
println(highOrderFunctions(1, 2, ::add))
println(highOrderFunctions(1, 2, { x, y -> x + y }))
println(highOrderFunctions(1, 2, { x, y -> x - y }))
}
运行结果如下 
神奇吧,如果你以为就这么完了那就太小看 Kotlin了,接着看, 我们可以将Higher-Order Functions 与 lambda 结合起来,
val a = highOrderFunctions(1,2) {
x, y -> x + y
}
println(a)
operater 被移到了() 外面~~~
这样的好处是什么呢, 我们在看一个例子
fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
}
finally {
lock.unlock()
}
}
fun main(args: Array<String>) {
val lock = Lock()
lock(lock) {
println("Hello")
}
}
终于可以优雅的给代码加锁了~~~
我们再来看 Kotlin 的另外一个属性
fun File.printPathAndParent() {
println(this.absoluteFile)
println(this.parent)
}
fun main(args: Array<String>) {
val path = "/Users/dongyayun/Desktop/a.txt"
println(1)
val file = File(path)
println(file.absoluteFile)
println(file.parent)
println("\r\n" + 2)
with(File(path)) {
println(absoluteFile)
println(parent)
}
println("\r\n" + 3)
with(File(path), File::printPathAndParent)
println("\r\n" + 4)
File(path).printPathAndParent()
}
运行上述代码你会发现,4段代码最终会打印出一样的结果. 其中 1 是正常的用法.
2 是使用了Higher-Order Functions.
3, 4都是使用了 Kotlin另外一个奇妙的功能, 就是 Extension Functions,在你的package里, 你可以定义某一个类的方法.
在上述例子中,
我定义了一个 File 类的printPathAndParent方法, 那么File 的实例都可以调用这个方法来进行打印自己的绝对路径和父目录

Kotlin 运用在Android上也是很巧妙的,譬如 常规我们在Activity里定义一个layout和button并加上点击事件可以这样写(使用 Kotlin)
val act = this
val layout = LinearLayout(act)
layout.orientation = LinearLayout.VERTICAL
val name = EditText(act)
val button = Button(act)
button.text = "Say Hello"
button.setOnClickListener {
Toast.makeText(act, "Hello, ${name.text}!", Toast.LENGTH_SHORT).show()
}
layout.addView(name)
layout.addView(button)
似乎和Java代码并没有太大的区别, 但是如果搭配 Intellij 出品的 anko 依赖, 我们可以这样写~
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
大大的减少了代码量呀,而且让代码通俗易读.
Kotlin暂时就说到这里, 当然 Kotlin的神奇之处远远不止我说的这些, 大家可以尝试一下,相信大家会爱上这个语言的~~~