1. 程式人生 > >為什麽你必須摒棄 Java ,全面轉向 Kotlin 語言?

為什麽你必須摒棄 Java ,全面轉向 Kotlin 語言?

就會 字符串插值 框架 substr 新的 執行 lock foo instance

是時候開始玩一門現代的編程語言了!

技術分享圖片

我想告訴你一個名為 Kotlin 的新的編程語言,以及為什麽你要開始考慮使用它來開發你的下一個項目。我以前喜歡 Java ,但是去年我發現了 Kotlin ,只要有可能我就會用 Kotlin 來寫代碼。現在我實在無法想象有什麽地方只有 Java 能做,而 Kotlin 不能的。

Kotlin 是 JetBrains 開發的,這是一家開發了一整套 IDEs 的公司,諸如 IntelliJ 和 ReSharper, 還有正在閃耀光芒的 Kotlin。這是一個務實而且簡潔的編程語言,真正讓人感覺身心愉悅的編程語言,而且效率非常高。

盡管 Kotlin 最終編譯成 JavaScript ,很快也將編譯成 機器碼,但我們仍將聚焦於其主要的環境 —— JVM。

這裏有一堆你應該完全轉向 Kotlin 語言的理由:

0# Java 互操作性

Kotlin 是 100% 與 Java 具備互操作性的。你可以使用 Kotlin 繼續你老的 Java 項目開發。所有你熟悉的 Java 框架仍然可用,任何框架,不管是 Kotlin 寫的,還是你固執 Java 小夥伴寫的都可以。

1# 熟悉的語法

Kotlin 不是誕生於學術界的怪異語言。其語法是 OOP 領域的任何開發者都熟悉的,可以或多或少的有一些了解。當然和 Java 還是有些不同的,例如重構後的構造函數以及使用 val 的變量聲明等等。下面是一個基本的 Kotlin 示例代碼:

class Foo { val b: String = "b" // val means unmodifiable

var i: Int = 0 // var means modifiable
fun hello() { val str = "Hello"
print("$str World")
} fun sum(x: Int, y: Int): Int { return x + y
} fun maxOf(a: Float, b: Float) = if (a > b) a else b
}

2# 字符串插值

這相當於是更智能,更具備可讀性的 Java 的 String.format() 方法的 Kotlin 實現:

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

3# 類型推斷

Kotlin 會自動的對變量的類型進行推斷:

val a = "abc" // type inferred to String
val b = 4 // type inferred to Int
val c: Double = 0.7 // type declared explicitly
val d: List<String> = ArrayList() // type declared explicitly


4# 智能類型轉換

Kotlin 編譯器會跟蹤你的邏輯代碼並在需要的時候進行自動的類型轉換,這意味著我們不需要在顯示轉換時做更多的 instanceof 檢查:

if (obj is String) {
print(obj.toUpperCase()) // obj is now known to be a String
}

5# 更直觀的相等性比較

你不再需要調用 equals() ,因為 == 操作符也可以用來比較結構的相等性:

val john1 = Person("John")
val john2 = Person("John")
john1 == john2 // true (structural equality)
john1 === john2 // false (referential equality)
6# 默認參數值

不需要像 Java 那樣定義很多包含不同參數的相似方法:

fun build(title: String, width: Int = 800, height: Int = 600) {
Frame(title, width, height)
}

7# 命名參數

結合默認參數值,命名參數可以消除 builders 的使用:

build("PacMan", 400, 300) // equivalent
build(title = "PacMan", width = 400, height = 300) // equivalent
build(width = 400, height = 300, title = "PacMan") // equivalent

8# When 表達式

switch 替換成 when ,代碼更具可讀性:

when (x) {
1 -> print("x is 1")
2 -> print("x is 2")
3, 4 -> print("x is 3 or 4")
in 5..10 -> print("x is 5, 6, 7, 8, 9, or 10")
else -> print("x is out of range")
}

支持表達式或者是語句,可以是有參數或者無參數:

val res: Boolean = when {
obj == null -> false
obj is String -> true
else -> throw IllegalStateException()
}

9# Properties

可以給公共字段自定義 set 和 get 行為,這意味著不再會因為那些沒用的 getters & setters 導致代碼瘋狂膨脹。

class Frame { var width: Int = 800
var height: Int = 600
val pixels: Int
get() = width * height
}

10# Data 類

這是一個 POJO 類,包含 toString(), equals(), hashCode(), 和 copy() 方法,和 Java 不同的是,它不會超過 100 行代碼:

data class Person(val name: String,
var email: String,
var age: Int)
val john = Person("John", "[email protected]", 112)

11# 操作符重載

可以重載預定義的一組操作符來提升代碼的可讀性:

data class Vec(val x: Float, val y: Float) {
operator fun plus(v: Vec) = Vec(x + v.x, y + v.y)
}
val v = Vec(2f, 3f) + Vec(4f, 1f)

12# 解構聲明

一些對象是可以解構的,一個很有用的例子就是對 Map 進行叠代:

for ((key, value) in map) {
print("Key: $key")
print("Value: $value")
}

13# Ranges

完全為了可讀性:

for (i in 1..100) { ... }
for (i in 0 until 100) { ... }for (i in 2..10 step 2) { ... }
for (i in 10 downTo 1) { ... }
if (x in 1..10) { ... }

14# 擴展函數

還記得你第一次用 Java 實現一個 List 的排序嗎?你找不到一個 sort() 函數,然後你就四處求助,最終找到了 Collections.sort()。後來你需要將一個字符串的首字符變成大寫,最終你還是自己寫了一個方法來實現,因為你當時還不知道有這麽個東西 StringUtils.capitalize().

如果只有一種方法可以向已有的類添加新的函數,這樣 IDE 就可以幫助你在代碼完成時找到正確的函數。在 Kotlin 裏你可以這麽做:

fun String.replaceSpaces(): String {
return this.replace(‘ ‘, ‘_‘)
}
val formatted = str.replaceSpaces()

標準庫擴展了 Java 原來類型的功能,這是字符串對象所需要的:

str.removeSuffix(".txt")
str.capitalize()
str.substringAfterLast("/")
str.replaceAfter(":", "classified")

15# Null 安全

Java 是我們應該稱之為是一個幾乎靜態類型的編程語言。Java 的 String 變量類型無法保證它不會等於 null。盡管我們已經習慣了這樣的情況,但它否定了靜態類型檢查的安全性,導致 Java 程序員總是活在各種空指針異常的恐懼中。

var a: String = "abc"
a = null // 編譯錯誤
var b: String? = "xyz"
b = null // 正確

Kotlin 強制你必須在訪問一個可為空的類型變量時候必須確保不會發生空指針:

val x = b.length // 編譯錯誤: b 允許為空

雖然看起來有點麻煩,但這的確是 Kotlin 一個微小卻又非常重要的特性。我們仍可以使用智能的轉換,可以在需要的時候將允許為空的類型轉成不允許為空:

if (b == null) return
val x = b.length // 正確

我們也可以使用安全調用方法 ?. 該表達式在 b 為空時返回 null,而不是拋出空指針異常:

val x = b?.length // type of x is nullable Int

安全調用可以鏈接在一起,以避免像其他語言一樣存在大量嵌套的 if-not-null 檢查,如果我們想要一個默認值而不是 null 時,可以用 ?: 操作符:

val name = ship?.captain?.name ?: "unknown"

如果沒有適合你的,那麽你應該是需要一個空指針了,你將不得不顯式的進行處理:

val x = b?.length ?: throw NullPointerException() // same as below
val x = b!!.length // same as above

16# 更好的 Lambdas

嘿,帥哥,這是一個很好的 Lambda 系統 —— 在完美的可讀性和簡潔之間取得非常好的平衡,這得益於非常聰明的設計選擇。其語法簡單直接:

val sum = { x: Int, y: Int -> x + y } // type: (Int, Int) -> Int
val res = sum(4,7) // res == 11

優點體現在:

如果 lambda 是方法的最後一個參數或者是唯一參數的話,那麽方法的括號可以移動或者省略.
如果我們選擇不去聲明單參數的 lambda 表達式的參數,那麽 Kotlin 會隱式的將之命名為 it.
結合上述優點,下面的三個不同的語句效果一樣:

numbers.filter({ x -> x.isPrime() })
numbers.filter { x -> x.isPrime() }
numbers.filter { it.isPrime() }

這個可以讓你編寫更加簡潔的函數式代碼,就像下面這樣優雅:

persons
.filter { it.age >= 18 }
.sortedBy { it.name }
.map { it.email }
.forEach { print(it) }

Kotlin 的 lambda 系統和擴展函數結合,可以非常棒的用來開發各種 DSL。例如 Anko 這個 DSL 的例子可以增強 Android 的開發:

verticalLayout { padding = dip(30)
editText { hint = “Name”
textSize = 24f
}
editText { hint = “Password”
textSize = 24f
}
button(“Login”) { textSize = 26f
}
}

17# IDE 支持

如果你打算開始使用 Kotlin 開發項目,在工具上你會有很多的選擇。但我強烈推薦使用 IntelliJ ,因為它自帶 Kotlin 的支持 — 它的特點展示了同一組人設計的開發工具和語言時的優勢。

只是給你一個很小但有非常聰明的例子,當我從 Stackoverflow 粘貼Java 代碼執行後,會彈出窗口提醒你粘貼了 Java 的代碼到 Kotlin 文件裏。

喜歡小編輕輕點個關註吧!

為什麽你必須摒棄 Java ,全面轉向 Kotlin 語言?