---
# System prepended metadata

title: Kotlin 介紹 - 與 Java 基礎差異
tags: [Kotlin]

---

---
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 語言

        兩者來說翻譯型語言的共通性較強，但相對的它的效率較低，它的特點剛好與編譯型語言相反
    :::

    編譯概念圖如下
    > ![](https://i.imgur.com/YqWImiz.png)

## 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 |
    :::



    **--實作結果--**
    > ![](https://i.imgur.com/g0b39EU.png)

    :::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 是可以有返回值

        > ![](https://i.imgur.com/m4JvKZc.png)

        ```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}")
            }
            ```
            > ![](https://i.imgur.com/GTSfwao.png)

        :::


    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)

        }
        ```

        > ![](https://i.imgur.com/5GI9Dag.png)

### 循環 & 區間 - 語法糖

* 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")
        }
    }
    ```
    > ![](https://i.imgur.com/s2IV3Db.png)

    :::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
        }
    }
    ```
    **--實作結果--**
    > ![](https://i.imgur.com/ZvKAjEy.png)

    :::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`
