1. 首先个人认为最重要的一点是能够和 Java 100%的兼容.

例如下面有一段 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())
}

输出如下结果 1

接下来, 我们用Kotlin写一段同样功能的Customer类, 看看只需要多少行代码.

data class CustomerKotlin(val id: Int, var name: String)  

是的, 只需要这一行就可以达到和Java五十多行一样的效果.

运行结果如下 2

另外,大家可能已经注意到, Kotlin 不需要写分号,不需要写分号,不需要写分号.

  1. 其次个人比较喜欢的一点就是, 可以在 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表达式出场了. 这里依次用了三个操作符, 分别是

  1. filter 过滤器. 根据 { } 里面的表达式对numberList进行过滤
  2. map 转换符, 将 1里过滤好的元素在进行转换, 这里是挨个乘10
  3. 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 }))

}

运行结果如下 3

神奇吧,如果你以为就这么完了那就太小看 Kotlin了,接着看, 我们可以将Higher-Order Functionslambda 结合起来,

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 的实例都可以调用这个方法来进行打印自己的绝对路径和父目录
4

Kotlin 运用在Android上也是很巧妙的,譬如 常规我们在Activity里定义一个layoutbutton并加上点击事件可以这样写(使用 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的神奇之处远远不止我说的这些, 大家可以尝试一下,相信大家会爱上这个语言的~~~