---
title: 'Kotlin 介紹 - 與 Java 基礎差異'
disqus: kyleAlien
---
Kotlin 介紹 - 與 Java 基礎差異
===
## Overview of Content
以下參考,第一行代碼 (第三版), Kotlin 進階實戰
如有引用參考本文章請詳註出處,感謝 :smile:
:::success
* 如果喜歡讀更好看一點的網頁版本,可以到我新做的網站 [**DevTech Ascendancy Hub**](https://devtechascendancy.com/)
本篇文章對應的是 [**Kotlin 與 Java 比較 | Kotlin 生態、入門 | Kotlin 特點、基礎**](https://devtechascendancy.com/kotlin-vs-java-ecosystem-intro-features-basics/)
:::
[TOC]
## Kotlin 簡介
Kotlin 是由 [**JetBrains 公司**](https://www.jetbrains.com/zh-cn/company/) 開發與設計,2011 就已釋出第一個版本,並在 2012 年將其開源,2016 年 Kotlin 發布了正式 1.0 版,並在自家的 IDE 開發工具 `IntelliJIDEA` 加入該語言
**Kotlin 是基於 JVM 的語言**,所以它可以很好的跟 Java 相容,並且它不只可以開發 Android App 甚至可以開發後端服務、編譯成 JavaScript 程式
:::info
* Kotlin 是 JetBrains 團隊開發出來的程式語言,其取名也源自於 **聖彼得堡附近的 [柯特林島](https://zh.m.wikipedia.org/zh-tw/%E7%A7%91%E7%89%B9%E6%9E%97%E5%B3%B6)** (俄羅斯附近)
:::
### Kotlin 特性
* Kotlin 語言有以下幾個高級語言特性 (收集了各個語言的專長 (`Python`, `Java`, `C#`, `JavaScript`, `Scala`, `Groovy`... 等等)
1. **函數(方法)**:高階函數 & Lambda 表達式
2. **防止 `NPE`**:空類型,`Elvis` 表達式,Scope Function
3. **Lazy loading**:懶加載,在需要時才創建資源,並且 Lazy loading **默認執行序(線程)安全**
4. **DSL 編程**:如同 Groovy 一樣的 DSL 編程
5. **Thread 管理**:以往在 Java Multi Thread 中我們常常會耗費 CPU 時間來做上下文切換,而 **在 Kotlin 中,有開發 `Coroutine` library 幫助我們做快速的上下文切換**
:::success
* 關於 Kotlin 更多 Coroutine 的使用請看 [**Coroutine - 協程**](https://hackmd.io/ggeGXU86T1uzhN8rVD8MHQ)
:::
### Kotlin & JVM 虛擬機
* 在 Android Java 有使用版權問題([**甲骨文、Google十年恩怨落幕!90億美元Java案大翻盤**](https://www.bnext.com.tw/article/62139/google-v-oracle-supreme-court-declares-fair?)),而 JVM 並沒有版權問題,這也就是為何 Kotlin 可以編譯出 Android 能夠接受的語言,其原因主要是因為 **JVM 透過翻譯字節碼(`Byte code`)來運行程式**,**而 Java、Kotlin 都是翻譯型語言,透過 JVM 翻譯過後都是相同的**
> 這是基於平台開發語言抽象化的優點,讓語言本身面向的是 JVM 虛擬機,只要編譯出 JVM 可識別的 `Byte code` 就可以在不同平台上運行
:::info
* **翻譯型 & 編譯型 ?**
> **`編譯型`**:典型的編譯型語言像是 C、C++ 都屬於編譯型語言,**它會針對當前的 CPU 編譯成對應的二進制文件**
> **`翻譯型`**:需要翻譯成第三方能夠看得懂的語言,再由第三方翻譯成二進制碼給 CPU 做程式運行,就像是 Java、Python 語言
兩者來說翻譯型語言的共通性較強,但相對的它的效率較低,它的特點剛好與編譯型語言相反
:::
編譯概念圖如下
> 
## Kotlin 發展
Kotlin 的發展以目前來看,是作為 **Java 的輔助、加強**(可從上面的輔助看出),不會完全的取代 Java
### Kotlin 生態圈
* Kotlin 目前已經是 Android App 開發的主流語言(官方推薦, [**Kotlin and Android**](https://developer.android.com/kotlin?hl=zh-tw)),除了一動端之外後端也可以很好的使用 Kotlin(後端開發常使用的 Spring 也推薦 Kotlin)
* Kotlin 不只可以編譯成 Java 語言,也可以直接編譯成 `Binary code` & `Js code`,對於跨平台編譯也佔據一席之地([**kotlin multiplatform**](https://kotlinlang.org/docs/multiplatform.html))
* Kotlin 支援多平台 & 語言,其中包括 `JVM`, `Android`, `iOS`, `JavaScript`, `Linux`, `Windows`, `Mac` 甚至嵌入式 `STM32`
:::success
* JetBrains 提供多平台開發 `Kotlin Multiplatform Mobile` (KMM)
:::
## 與 Java 基礎差異
* 程式執行主要分為三種方式執行(以程式結構化的概念去思考,分為三點去討論!)
1. **順序語句** : 如同 Java 是由上往下單句執行
2. **條件語句** : 條件判斷 `if/else`,**Kotlin 沒有 `switch` 關鍵字,並使用了 `when` 取代**
3. **循環語句** : `for/while` 條件循環
### Kotlin 變量宣告
* Java 中要定義一個遍量必須聲明變量的型態 (int a = 20),Kotlin 宣告時只允許在變量前聲明 **var**、**val** 兩個關鍵字,並且有自動推倒的特性
| kotlin 變量關鍵字 | 與 Java 比對 | 舉例 |
| -------- | -------- | -------- |
| var | 該變量可改變 | var A |
| val | 如同**在變量前使用 final 描述**,說明該變量是不可改變的 | val B |
* 先說明幾個特性 ^1.^ **Kotlin 結語不需使用 `;` 分號**、^2.^ Kotlni 類型可以**自動推倒** (也可以自行設定)
```kotlin=
// 包名不建議大寫開頭
package class_1
/**
* 變數 & 型態
* 變數皆使用 var、val 定義
* var : 可變參數
* val : 不可變參數,其功能是為了解決 Java 中 final 不常被使用的問題
*/
fun main() {
println("Hello Kotlin!") // 結束不須分號
var a = 10
a = 15
// a = "Boy"; Err: var 推導後類型不可變
println("a = $a");
val b = 20
// b = 25 Err: val 描述後不可再賦值, Val cannot be reassigned
println("b = $b");
var c : Int = 30 // ':' 類型指定
c = 33
println("c = $c");
var d : Short = 1 // Kotlin 完全秉棄了 Java 的基礎類型,"全部皆為對象",基礎數據類型全部大寫
d = 11
println("d = $d");
}
```
:::warning
* 關鍵字、自動推倒,要注意幾點:
1. **`var` 類型推導完成後,不可再賦予其他類型**
2. `val` 必須賦予值,並且不能再對其變量進行更改,否則編譯器會提是 `Val cannot be reassigned` 錯誤
3. 自動推導並非每次都有用,若是我們對一個變量延遲賦值,Kotlin 就無法自動推倒其類型,這時可以使用 `:` 指定
```kotlin=
// lateinit 延遲初始化,就必須指定參數類型
lateinit var name: String
```
4. **Kotlin 內所的事物皆為對象**,也就是 **沒有基礎數據類型** (其實也就是將 Java 每一個數據類型開頭改為大寫)
| Java 基礎數據類型 | Kotlin 對象數據類型 |
| -------- | -------- |
| boolean | Boolean |
| char | Char |
| byte | Boolean |
| short | Short |
| int | Int |
| long | Long |
| float | Float |
| double | Double |
:::
**--實作結果--**
> 
:::success
* **為何設計 `val` 關鍵字**
**`val` 的設計是為了解決 ++Java 中 final 描述詞沒有被正當使用的情況++**;一般來說 **類、變量若是沒有被使用應該都宣告為 final,以免被誤用**,這是一個好習慣
:::
### if / else & when 判斷
* 以下會先說 if 與 Java 不同的使用地方,其最大的不同在於 **Kotlin 的 if 可以直接返回數值,並且不需要 return 關鍵字**
* **when 作為取代 switch 的關鍵字**,並且 Kotlin 對其功能進行了拓展,可以搭配 `is` 使用在類的判斷相當於 java instanceof (取代 case,並 **省略了 break 關鍵字**),並且最後使用 else (取代 default)
1. **`if/else` 判斷**
```kotlin=
// Kotlin's if 可使用如同 Java's if
fun useIf(n1: Int, n2: Int) : String {
var result = ""
if (n1 > n2) {
result = "$n1 is Bigger"
} else {
result = "$n2 is Bigger"
}
return result
}
// Kotlin's if 可以有返回值!!
// 該返回值在代碼中的最後一行 (不須 return
fun useIfDiff(n1: Int, n2: Int) : String {
return if (n1 > n2) {
"$n1 is Bigger"
} else {
return "$n2 is Bigger" // return 可有可無
}
}
fun useIfSimple(n1: Int, n2: Int) = if (n1 > n2) {
"$n1 is Bigger"
} else {
"$n2 is Bigger" // return 不可以用在 = 符號
}
```
2. **`when` 代替 `switch`**
when 語句如同 if 是可以有返回值
> 
```kotlin=
fun useWhenSimple(id: Int) = when(id) {
1 -> "A"
2 -> { // 超過一行時使用大括號
"B"
}
3 -> "C"
else -> "Non" // like default
}
// when 可以配合 is 一起使用,相當於 Java 的 instanceof
fun useIs(id: Number) : Unit = when(id) {
is Int -> println("Params is Int")
is Double -> println("Params is Double")
is Float -> println("Params is Float")
else -> println("Cannot decide Type")
}
// 若要直接使用參數判斷,when 就不需要括弧,並且可以 對關鍵字進行操作
fun useWhenWithParams(id: Number) = when {
id is Byte -> println("Params is Int")
id == 11 -> println("Params is 11")
id == 11.1 -> println("Params is 11.1")
id.toFloat() == 1.0f -> {
println("Params is 1.0f")
}
else -> println("Cannot decide Type")
}
```
:::warning
* `==` 符號在 Java 中是用來判斷兩個內存地址是否相同,而 Kotlin `==` 符號則是判斷對象、字串是否相同,相當於 equals 的方法
| 功能 | Java 關鍵字 | Kotlin 關鍵字 |
| -------- | -------- | -------- |
| 對象是否相等 (內容) | `equals` | `==` |
| 內存(記憶體)地址是否相等 | `==` | `===` |
```kotlin=
package class_1
fun main() {
val a : String = "Hello"
val b : String = String(StringBuffer("Hello"))
println("a.equals(b): ${a.equals(b)}")
println("a == b: ${a == b}")
println("a === b: ${a === b}")
}
```
> 
:::
3. 測試順序語句、條件語句、循環語句
```kotlin=
package class_1
/**
* 程式的運營主要有三種型語句
* 1. 順序語句 (執行程式的順序
* 2. 條件語句 (if/else、when
* 3. 循環語句 (for、while
*/
fun main() {
var r = useIf(11, 2)
println("Answer: $r")
r = useIfDiff(11, 22)
println("Answer: $r")
r = useIfSimple(33, 22)
println("Answer: $r")
// --------------------------------------------
r = useWhenSimple(3)
println("When(id): $r")
useIs(12.3f)
useWhenWithParams(11)
useWhenWithParams(1.0)
}
```
> 
### 循環 & 區間 - 語法糖
* Kotlin 語言的特色之一,就是它有提供一系列優秀的「語法糖」,可以 **有利於開發速度、可讀性**!以下是 Kotlin 常用的 循環 & 區間 的關鍵字
| 關鍵字(符號) | 功能 |
| -------- | -------- |
| until | 同樣是個區間,但是不包含最後一個元素 (左閉右開) |
| in | 判斷是否符合在區間內,會配合著 `..` 一起使用 (類似 Python) |
| `..` | 區間,**包含最後一個數字** (`until` 則不包含) |
| step | 前進的數量 |
| downTo | 前面都是升序,`downTo` 則是降序讀取 |
```kotlin=
/**
* 循環: Kotlin 也提供 for & while
* while 與 Java、C、C++ 相同
* for-i 轉為 foreach,並大幅增強改變為 for-in
*
* 區間: 使用關鍵字 `..` 可以表示數值的區間 (小到大)
* 用數學的表達方式就是 [0, 10]
*/
fun main() {
println("3 in 0..10: ${3 in 0..10}")
// 以下如同 [0, 2, 4, 6, 8. 10]
println("3 in 0..10 step 2: ${3 in 0..10 step 2}") // false
// 以下如同 [0, 3, 6, 9]
println("3 in 0..10 step 3: ${3 in 0..10 step 3}") // true
// 以下如同 [10, 7, 4, 1]
println("4 in 10 downTo 0 step 3: ${4 in 10 downTo 0 step 3}") // true
useForIn()
useForInStep()
useForInUntil()
useForInDownTo()
}
fun useForIn() {
for (i in 0 .. 5) {
println("$i")
}
}
fun useForInStep() {
for (i in 0 .. 5 step 2) { // 一次前進 2
println("Step: $i")
}
}
// 達成左閉右開
fun useForInUntil() {
for (i in 0 until 5) { // 當然可以與 step 結合 (0 ~ 4)
println("until: $i")
}
}
// 區間 `..` & Until 都是 "升序",downTo 則是降序
fun useForInDownTo() {
for (i in 5 downTo 0 step 2) { // 區間 [10,0],並配合 step 使用
println("downTo: $i")
}
}
```
> 
:::info
* 指定次數的 For 迴圈會使用 `in` + `until`
```kotlin=
fun forControl(times : Int = 10) {
for (i in 0 until times) {
// TODO:
}
}
```
:::
### tag 標籤 - @
* 上面的循環語句可以配合標籤一起使用;一般來說跳出迴圈必須使用 `break`,在 Kotlin 中也可以使用「**標籤**」來代替;**標籤的功能就像是 C/C++ 的 `goto` 一般**,可以直接轉會到那一行
> 標籤格式: `<標籤名稱>@`
```java=
package class_1
fun main() {
customFor()
println()
kotlinTag()
}
// 傳統 for 用法
fun customFor() {
for(i in 0..5) {
println("customFor i: $i")
for (j in 0..5) {
if (i == 2) {
println("Till 2 use break")
break
}
}
if(i == 4) break
}
}
/**
* 使用標籤達到相同的效果
*/
fun kotlinTag() {
// 標籤
Hi@ for(i in 0..5) {
println("kotlinTag i: $i")
Tag@for (j in 0..5) {
if (i == 2) {
println("Till 2 use Break & Tag")
break@Tag // 跳出 tag 標籤
}
}
if(i == 4) break@Hi
}
}
```
**--實作結果--**
> 
:::info
* **Class 類就自帶標籤,++標籤與類同名++**,範例如下
```java=
class PC {
var CPU = "Intel-core-i5";
var ram = 16;
fun info2() {
// 返回 this@PC,也就是 PC 類
println("Cpu: ${this@PC.CPU}, ram: ${this@PC.CPU}")
}
}
```
:::
## 更多的 Kotlin 語言相關文章
在這裡,我們提供了一系列豐富且深入的 Kotlin 語言相關文章,涵蓋了從基礎到進階的各個方面。讓我們一起來探索這些精彩內容!
### Kotlin 語言基礎
* **Kotlin 語言基礎**:想要建立堅實的 Kotlin 基礎?以下這些文章將帶你深入探索 Kotlin 的關鍵基礎和概念,幫你打造更堅固的 Kotlin 語言基礎
:::info
* [**Kotlin 函數、類、屬性 | DataClass、Sealed、Object 關鍵字 | Enum、Companion、NPE**](https://devtechascendancy.com/kotlin-functions_oop_dataclass_sealed_object/)
* [**深入探究 Kotlin 與 Java 泛型:擦除、取得泛型類型、型變、投影 | 協變、逆變**](https://devtechascendancy.com/explore-kotlin-java-generics_type_erasure/)
* [**深入 Kotlin 函數特性:Inline、擴展、標準函數全解析 | 提升程式碼效能與可讀性**](https://devtechascendancy.com/kotlin_inline_extensions_standards-func/)
* [**Kotlin DSL、操作符、中綴表達式 Infix | DSL 詳解 | DSL 設計與應用**](https://devtechascendancy.com/kotlin-dsl-operators-infix-explained/)
:::
### Kotlin 特性、特點
* **Kotlin 特性、特點**:探索 Kotlin 的獨特特性和功能,加深對 Kotlin 語言的理解,並增強對於語言特性的應用
:::warning
* [**Kotlin 代理與懶加載機制:使用、lazy 深度解析**](https://devtechascendancy.com/kotlin-delegate_java-proxy_lateinit_lazy/)
* [**Kotlin Lambda 編程 & Bytecode | Array & Collections 集合 | 集合函數式 API**](https://devtechascendancy.com/kotlin-lambda-bytecode-array-collections-functional/)
* [**深入理解 Kotlin:智能推斷與 Contact 規則**](https://devtechascendancy.com/kotlin-smart-inference-contract-rules-guide/)
:::
### Kotlin 進階:協程、響應式、異步
* **Kotlin 進階:協程、響應式、異步**:若想深入學習 Kotlin 的進階主題,包括協程應用、Channel 使用、以及 Flow 的探索,請查看以下文章
:::danger
* [**應用 Kotlin 協程:對比 Thread、創建協程、任務掛起 | Dispatcher、CoroutineContext、CoroutineScope**](https://devtechascendancy.com/applied-kotlin-coroutines-in-depth-guide/)
* [**Kotlin Channel 使用介紹 | Select、Actor | 生產者消費者**](https://devtechascendancy.com/kotlin-channel_select_actor_cs/)
* [**探索 Kotlin Flow:基本使用、RxJava 對比、背壓機制 | Flow 細節**](https://devtechascendancy.com/kotlin-flow-usage_compare-rx_backpressure/)
:::
## Appendix & FAQ
:::info
:::
###### tags: `Kotlin`