Java 里的泛型简介.
我們在JDK中有時回見到1個類or接口后面跟這1個尖括號.
例如:
java.util.HashMap<K,V>我們一開始大概知道K,V 大概就是Key和Value的意思, 鍵值對嘛, 但是不知道這個特性對編程的影響.
其實這個設計Java的泛型問題. 把本文看完就明白了.
一. Java里泛型的定義
在數據結構中, 泛型(generic)這個詞代表一種編程思想.
它的意思就是:? 不論存儲結構如何差異, 都可以令其具有看起來一樣的操作方法.
例如 ArrayList 和 LinkList 這兩個容器, 它們在內存內的存儲結構是完全不同的.
但是它們的操作方法基本上是一樣的.
都具有相同的,add() 方法, remove()方法, size()方法等等.
這就是泛型的編程思想.
但是在Java里不能直接操作內存, Java里泛型是另一種定義:
java里泛型用于限制傳入容器和接口的數據類型.
二. 容器里的泛型.
我們打開Java JDK API, 查看ArrayList這個類
會見到下面的字眼
java.util
類 ArrayList<E>
ArrayList后面有個尖括號, 里面一個大寫E.
其實E代表的是Element的意思,? 它告訴我們, ArrayList可以用泛型來限制放入容器里的對象類型.
2.1 假如不使用泛型
假如我們不適用泛型
代碼是這樣寫的:
import java.util.ArrayList;class Student{int id;private String name;public Student(int id, String name){this.id = id;this.name = name;}public String toString(){return this.id + ": " + this.name;} }public class ArrayList1{public static void main(String args[]){ArrayList arr = new ArrayList();arr.add(new Student(1,"Jack"));arr.add(new Student(2,"Bill"));arr.add(1);arr.add("Jack");Student st = arr.get(1);System.out.println(st);}}上面的代碼中, arr這個容器添加了兩個Student對象, 1個integer對象(自動裝箱),1個String對象.
但是編譯失敗
原因在于這行代碼:
Student st = arr.get(1);在JDK API中, get()方法是這樣定義的:
get
public E get(int?index)其實上面的定義告訴我們, 可以使用泛型來決定get()方法的返回值類型, 但是如果不使用泛型, 返回的類型是object.
上面用1個Student的引用st 來接收1個Object類型對象, 所以會編譯失敗.
所以我們需要強制轉換, 將出錯的代碼改為:
Student st = (Student)arr.get(1);這樣就編譯通過了.
但是編譯信息有兩句warning:
Note: ArrayList1.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.它告訴我們這樣是不安全的, 因為沒有使用泛型, arr容器內還可能有其它的類型的對象.
一旦我把上面的get方法里的參數從1改成2, 則會發生轉會失敗, 拋出異常..
2.2 使用泛型:
我們可以在定義1個容器時使用泛型, 方法很簡單, 就是在容器類名后面加上尖括號,后面寫上你要放入的對象類名.
例如:
Arraylist<Student> arr = new ArrayList<Student>();修改后的代碼如下: import java.util.ArrayList;class Student{int id;private String name;public Student(int id, String name){this.id = id;this.name = name;}public String toString(){return this.id + ": " + this.name;} }public class ArrayList2{public static void main(String args[]){ArrayList<Student> arr = new ArrayList<Student>();arr.add(new Student(1,"Jack"));arr.add(new Student(2,"Bill"));//arr.add(1);//arr.add("Jack");Student st = arr.get(1);//Student st = (Student)arr.get(1);System.out.println(st);}}
上面的 get()方法已經不需要強制轉換了.
值得注意的是, 當使用了泛型以后, 上面的arr容器就不能再放入除Student對象之外的其他類型元素. 否則會報錯!
三. 接口里的泛型.
我地再一次打開JDKAPI,? 看看Comparable接口的定義:
ava.lang?
接口 Comparable<T>
類型參數:
然后再看看Comparable里面最重要的方法:
| int | compareTo(T?o)? ??????????比較此對象與指定對象的順序。 |
里面都有1個T, 意思也是可以利用泛型來指定傳入Comparable接口里方法的參數類型:
3.1 假如不使用泛型:
如果不使用泛型, 那么使用實現了Comparable接口的對象里的comparaTo方法里就能接受各種類型的對象, 必須使用強制轉會:例子:
例如上面的例子
類Student 實現了Comparable接口,? 重寫comparaTo時的參數必須是對象Object
內容里還必須強制轉會:
Student st = (Student)o;這樣寫雖然看起來ok, 但是實際上也不安全
因為這樣寫, Student對象調用compareTo方法時就能放入各種類型的參數.
編譯時是無錯的,但是執行時就有可能轉換失敗了.
3.2 假如使用泛型.
接口使用泛型的方法也很簡單:
只需要在接口名后面加上<參數類名>就ok
上面修改后, 重寫的compareTo方法參數就應該指定為Student類.
而且不能將其他類型對象作為參數調用, 否則編譯出錯.
四. 使用泛型的意義
通過上面的例子, 我們可以得出使用java泛型 有如下好處:
1.避免強制轉換的代碼
2.限制傳入容器的對象類型 和 接口方法參數的類型
3.避免了編譯通過, 但是因為強制轉換失敗而執行出錯的情況. 令java程序更加安全健壯.
總結
以上是生活随笔為你收集整理的Java 里的泛型简介.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 里的HashMap(HashT
- 下一篇: Java里的数组介绍