掃盲:Kotlin 的泛型
阿新 • • 發佈:2020-12-29
# 引子
相信總是有很多同學,總是在抱怨泛型無論怎麼學習,都只是停留在一個簡單使用的水平,所以一直為此而備受苦惱。
Kotlin 作為一門能和 Java 相互呼叫的語言,自然也支援泛型,不過 Kotlin 的新關鍵字 `in` 和 `out` 卻總能繞暈一部分人,歸根結底,還是因為 Java 的泛型基本功沒有足夠紮實。
很多同學總是會產生這些疑問:
- Kotlin 泛型和 Java 泛型到底有何區別?
- Java 泛型存在的意義到底是什麼?
- Java 的型別擦除到底是指什麼?
- Java 泛型的上界、下界、萬用字元到底有何區別?它們可以實現多重限制麼?
- Java 的 ` extends T>`、` super T>`、`>` 到底對應了什麼?有哪些使用場景?
- Kotlin 的 `in`、`out`、`*`、`where` 到底有何魔力?
- 泛型方法又是什麼?
今天,就用一篇文章為大家解除上述疑惑。
# 泛型:型別安全的利刃
總所周知,Java 在 1.5 之前,是沒有泛型這個概念的。那時候的 `List` 還只是一個可以裝下一切的集合。所以我們難免會寫上這樣的程式碼:
```java
List list = new ArrayList();
list.add(1);
list.add("nanchen2251");
String str = (String) list.get(0);
```
上面的程式碼編譯並沒有任何問題,但執行的時候一定會出現常見的 `ClassCastException` 異常:
```
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
```
**這個體驗非常糟糕,我們真正需要的是在程式碼編譯的時候就能發現錯誤,而不是讓錯誤的程式碼釋出到生產環境中。**
而如果上述程式碼我們增加上泛型,就會在編譯期就能看到明顯的錯誤啦。
```java
List list = new ArrayList<>();
list.add(1);
//