java泛型generics泛型類的用法
/**
* 測(cè)試generics泛型
* generic通用的 generics泛型
*/
public class Test1<T> {
? ?//泛型在類名后使用<>表示 泛型字符可以使用任意標(biāo)識(shí)符 公認(rèn)T(type)表示普通java類 E(element)表示容器中的元素
? ?// K(key)表示Map中的鍵key V(value)表示值 N(number)表示數(shù)值類型 ?表示不確定的JAVA類型
? ?//可以同時(shí)使用多個(gè)泛型字符 用,隔開 <x,x,x,x>
? ?private T flag;
? ?//使用T來泛指想要設(shè)定的 flag的類型 比如想用T來指代String 則類內(nèi)所有T都指代String 在外部實(shí)際調(diào)用Test1時(shí)可以通過<>改變T的指代類型 同一套Test1可以實(shí)現(xiàn)多種類型的應(yīng)用 將同一套模式泛用化
? ?public void setFlag(T flag){
? ? ? ?//將T類型的flag賦值給this.flag T的類型隨外部調(diào)用時(shí)設(shè)定而變化
? ? ? ?this.flag = flag;
? ?}
? ?public T getFlag(){
? ? ? ?//凡涉及到flag 的類型都統(tǒng)一為T 避免了類型錯(cuò)誤 省去了強(qiáng)制轉(zhuǎn)型的操作
? ? ? ?return this.flag;
? ?}
// ? ?T t = new T(); 報(bào)錯(cuò) 泛型字符不能用于創(chuàng)建對(duì)象
}
class Test2{
? ?public static void main(String[] args) {
? ? ? ?Test1<String> str = new Test1<>();
? ? ? ?//實(shí)際使用時(shí)通過設(shè)定<>內(nèi)的具體類型來使用Test1類 設(shè)定為String后 原類內(nèi)所有T都替換為String 即將flag的類型變?yōu)镾tring
? ? ? ?//格式 ?類名<想設(shè)定的類型> 引用變量名 = new 類名<>() ? ? new后的<>為空 統(tǒng)一通過等號(hào)左側(cè)來定義
? ? ? ?str.setFlag("這里的參數(shù)要求變?yōu)榱薙tring類型 將字符串傳參進(jìn)set方法中賦值給 String類型的flag");
? ? ? ?System.out.println(str.getFlag()+" 這里的get方法返回值同樣變?yōu)榱俗址?#34;);
? ? ? ?Test1<Integer> i1 = new Test1<>();
? ? ? ?//當(dāng)T設(shè)定為Integer后 Test1又變?yōu)榱耸褂肐nteger類型的類 這個(gè)Test1和上面的Test1<String>是兩個(gè)類 在編譯階段將Test1分成了兩個(gè)類 實(shí)際JVM虛擬機(jī)運(yùn)行時(shí)沒有泛型的概念
? ? ? ?i1.setFlag(100);
? ? ? ?//set方法的參數(shù)要求變?yōu)榱薎nteger類型 輸入int的100會(huì)在編譯階段轉(zhuǎn)換為 Integer.valueOf(100)
? ? ? ?System.out.println(i1.getFlag());
? ? ? ?//同樣get方法的返回值類型也變?yōu)榱薎nteger 在打印時(shí)會(huì)默認(rèn)調(diào)用Integer重寫的.toString 方法 打印Integer對(duì)象.value
? ? ? ?Test1 o1 = new Test1();
? ? ? ?//當(dāng)不寫<>時(shí) T指代Object類 new后面也不寫<>
// ? ? ? ?Test1<int> i = new Test1<>(); ?報(bào)錯(cuò) ?基本數(shù)據(jù)類型不能用于泛型 泛型只能是類/接口 基本數(shù)據(jù)類型需要用包裝類代替
? ?}
}
interface Test3<T>{
? ?//定義泛型接口
? ?T getNumber(T number);
? ?//接口的抽象方法 默認(rèn)public abstract
}
class Test3Impl implements Test3<Integer>{
? ?//實(shí)現(xiàn)泛型接口 將T設(shè)定為Integer
? ?@Override
? ?public Integer getNumber(Integer number) {
? ? ? ?//需要實(shí)現(xiàn)的方法也一并變?yōu)镮nteger類型
? ? ? ?return number;
? ?}
? ?public static void main(String[] args) {
? ? ? ?Test3Impl i3 = new Test3Impl();
? ? ? ?//正常調(diào)用類
? ? ? ?System.out.println(i3.getNumber(3));
? ? ? ?Test3 o3 = new Test3Impl();
? ? ? ?//通過接口引用變量
? ? ? ?Object o = o3.getNumber(3);
? ? ? ?System.out.println(o);
? ? ? ?//引用類型Test3沒有<>設(shè)定類型 T指代Object類 o3.getNumber()要求傳參為Object類型
? ? ? ?// o3為Test3編譯類型 運(yùn)行時(shí)類型為Test3Impl 此時(shí)如果.getNumber()內(nèi)參數(shù)不是Integer的實(shí)例會(huì)報(bào)類型轉(zhuǎn)換異常
? ? ? ?// 數(shù)字3自動(dòng)封裝為包裝類Integer傳入.getNumber()中 執(zhí)行后返回Integer對(duì)象 但由于編譯類型o3限制 返回對(duì)象自動(dòng)轉(zhuǎn)換為Object 賦值給o
? ? ? ?//打印時(shí)編譯類型o變?yōu)檫\(yùn)行時(shí)類型Integer調(diào)用重寫的.toString打印.value 結(jié)果為3
? ? ? ?Test3<Integer> i4 = new Test3Impl();
? ? ? ?//將接口設(shè)定為與實(shí)現(xiàn)類一致的類型 免去轉(zhuǎn)換
? ? ? ?System.out.println(i4.getNumber(4));
? ?}
}