泛型的概述
說到泛型,我們先來回顧一下之前我們了解知識的一個練習(xí)
public class GenericDemo {
public static void main(String[] args) {
// 創(chuàng)建
ArrayList array = new ArrayList();
// 添加元素
array.add("hello");
array.add("world");
array.add("java");
//添加int類型的元素
array.add(10);
// JDK5以后的自動裝箱
// 等價于: array.add(Integer.valueOf(10));
// 遍歷
Iterator it = array.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
}
}
我們先來了解一下泛型
- 泛型
- JDK1.5以后出現(xiàn)的機制
- 是一種把類型明確的工作推遲到創(chuàng)建對象或者調(diào)用方法的時候才去明確的特殊的類型。
- 好處
- 提高了程序的安全性
- 把運行時期的問題提前到了編譯期間
- 避免了強制類型轉(zhuǎn)換
泛型的使用
我們使用泛型前,先來了解它的格式。
- 格式
- <數(shù)據(jù)類型>
- 此處的數(shù)據(jù)類型只能是引用類型。
泛型在哪些地方使用呢?
看API,如果類,接口,抽象類后面跟的有< E >就說要使用泛型。一般來說就是在集合中使用。
我們用泛型修改上面例子中的錯誤
public class GenericDemo {
public static void main(String[] args) {
// 創(chuàng)建
ArrayList<String> array = new ArrayList<String>();
// 添加元素
array.add("hello");
array.add("world");
array.add("java");
//array.add(10);
// JDK5以后的自動裝箱
// 等價于:array.add(Integer.valueOf(10));
// 遍歷
Iterator<String> it = array.iterator();
while (it.hasNext()) {
// ClassCastException
// String s = (String) it.next();
String s = it.next();
System.out.println(s);
}
}
}
泛型類
- 把泛型定義在類上
- 格式:public class 類名<泛型類型1,…>
- 注意:泛型類型必須是引用類型
早期的時候,我們使用Object來代表任意的類型。
向上轉(zhuǎn)型是沒有任何問題的,但是在向下轉(zhuǎn)型的時候其實隱含了類型轉(zhuǎn)換的問題。
也就是說這樣的程序其實并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。
下面我們就來學(xué)習(xí)泛型類是怎么回事
// 泛型類:把泛型定義在類上
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
// 泛型類的測試
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectTool<String> ot = new ObjectTool<String>();
ot.setObj(new String("中國"));
String s = ot.getObj();
System.out.println("姓名是:" + s);
ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
ot2.setObj(new Integer(69));
Integer i = ot2.getObj();
System.out.println("年齡是:" + i);
}
}
輸出結(jié)果:
姓名是:中國
年齡是:69
泛型方法
- 把泛型定義在方法上
- 格式:public <泛型類型> 返回類型 方法名(泛型類型 .)
上面我們把泛型定義在了類中,現(xiàn)在我們也可以把泛型定義在方法中,來一起學(xué)習(xí)
* * 泛型方法:把泛型定義在方法上 **
public class ObjectTool {
public <T> void show(T t) {
System.out.println(t);
}
}
public class ObjectToolDemo {
public static void main(String[] args) {
// 定義泛型方法后
ObjectTool ot = new ObjectTool();
ot.show("hello");
ot.show(100);
ot.show(true);
}
}
這樣我們就可以傳遞任意類型的參數(shù)了
泛型接口
- 把泛型定義在接口上
- 格式:public interface 接口名<泛型類型1…>
/* * 泛型接口:把泛型定義在接口上 */
public interface Inter<T> {
public abstract void show(T t);
}
//實現(xiàn)類在實現(xiàn)接口的時候,我們會遇到兩種情況
//第一種情況:已經(jīng)知道是什么類型的了
public class InterImpl implements Inter<String> {
@Override
public void show(String t) {
System.out.println(t);
}
}
//第二種情況:還不知道是什么類型的
public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
public class InterDemo {
public static void main(String[] args) {
// 第一種情況的測試
Inter<String> i = new InterImpl();
i.show("hello");
// 第二種情況的測試
Inter<String> i = new InterImpl<String>();
i.show("hello");
Inter<Integer> ii = new InterImpl<Integer>();
ii.show(100);
}
}
我們來寫一個簡單的例子驗證一下上面所說的結(jié)論
public class GenericDemo {
public static void main(String[] args) {
// 泛型如果明確的寫的時候,前后必須一致 Collection<Object> c1 = new ArrayList<Object>();
// Collection<Object> c2 = new ArrayList<Animal>();//報錯
// Collection<Object> c3 = new ArrayList<Dog>();//報錯
// Collection<Object> c4 = new ArrayList<Cat>();//報錯
// ?表示任意的類型都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>();
// ? extends E:向下限定,E及其子類
// Collection<? extends Animal> c9 = new ArrayList<Object>();//報錯
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();
// ? super E:向上限定,E極其父類
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();//報錯
// Collection<? super Animal> c16 = new ArrayList<Cat>();//報錯
}
}
class Animal {}class Dog extends Animal {}class Cat extends Animal {}
仔細(xì)觀察一下上面的通配符有什么區(qū)別,你會很快的學(xué)會通配符的使用