?# 第四章第三節--1泛型
標簽(空格分隔): 廖雪峰
---
## 為什么要使用泛型
例子:JDK提供的`ArrayList`,可以看做是一個可變的數組,其特點為比數組操作起來更方便.

在`ArrayList`的內容是使用一個`Object[]`數組來存放所有的數據,當不實用使用泛型直接來存儲`String`類型的時候,在代碼中需要進行強制轉型,如下圖所示,這樣寫代碼的時候就很不方便,容易出現錯誤,在打印的時候也無法統一執行.

若為每種`Object`都單獨的編寫一個`ArrayList`,這樣便不用強制轉型.可是這樣一來就需要對于每種不同的類型都重新構建一個`Arraylist`,JDK中原本的數據類型就有上千種,所以這種方法也是不可行的.

最好的思路便是重用一套代碼,把數據類型作為參數的形式傳遞進去.這邊是泛型的雛形了.
這樣就可以實現編寫一次代碼,實現各種類型的`ArrayList`.

## 什么是泛型
泛型就是一種模版,例如`ArrayList<T>`
- 在代碼中為用到的類創建對應的`ArrayList<類型>`代碼表示為`ArrayList<String> list = new ArrayList<String>()`;
- 編譯器將對這種類型做檢測,`list.add("hello");list.add(123);//complie error.`
## 泛型的繼承關系
`ArrayList<T>`實現的是`List<T>`接口,我們可以向上轉型.

注意:`ArrayList`可以向上轉型為`List`,不過`ArrayList<Integer>`不能向上轉型為`ArrayList<Number>`/`List<Number>`

如果把`ArrayList<Integer>`向上轉型為`ArrayList<Number>`,那么就可以添加`float`類型,如果添加`float`類型之后,打印的時候便又出現類型不能確定的問題,導致出錯.
## 小節小結
- 泛型就是編寫模版代碼來適應任意類型.(把類型按照參數的形式傳出去)
- 不必對類型進行強制轉換.
- 編譯器在添加的時候便對元素進行檢查.
- 注意泛型的繼承關系.可以把`ArrayList<T>`向上轉型為`List<T>`,不能把`ArrayList<T>`向上轉為`ArrayList<T的父類>`或者`List<T的父類>`
- 前言
- 一:Java快速入門
- 二:Java面向對象編程
- 三:Java異常處理
- 錯誤處理
- Java的異常
- 捕獲異常
- 拋出異常
- 自定義異常
- 斷言和日志
- 使用斷言
- 使用JDK Logging
- 使用Commons Logging
- 使用Log4j
- 四:Java反射與泛型
- 反射
- Class類
- 訪問字段
- 調用方法
- 調用構造方法
- 獲取繼承關系
- 注解
- 使用注解
- 定義注解
- 處理注解
- 泛型
- 什么是泛型
- 使用泛型
- 編寫泛型
- 擦拭法
- extends通配符
- super通配符
- 泛型和反射
- 五:Java集合
- Java集合簡介
- Java集合簡介
- List
- 使用List
- 編寫equals方法
- Map
- Set
- Queue
- Stack
- 最佳實踐
- 六:Java IO編程
- 七:Java處理日期和時間
- 八:JUnit單元測試
- 九:Java正則表達式
- 十:Java加密與安全
- 十一:Java多線程編程
- 十二:Maven基礎
- 十三:Java網絡編程
- 十四:Java操作XML和JSON
- 十五:Java JDBC編程
- 十六:Java函數式編程