Java範型類html
public class FanXingClassTest { public static void main(String args[]){ Test<Integer> intObj = new Test<Integer>(123); Test<String> strObj = new Test<String>("一二三"); intObj.showType(); strObj.showType(); } } /** * 定義範型類 * @param <T> */ class Test<T>{ private T ob; //定義範型的成員變量 public Test(T ob){ this.ob = ob; } public void setT(T ob){ this.ob = ob; } public T getT(){ return this.ob; } public void showType(){ System.out.println("T的實際類型是:"+ob.getClass()); } }
對比一下沒有使用範型類(以下代碼),也能夠輸出同樣的結果,爲何要使用範型類?類型檢查??this
public class FanXingClassTest { public static void main(String args[]){ Test intObj = new Test(123); Test strObj = new Test("一二三"); intObj.showType(); strObj.showType(); } } /** * 定義普通類 */ class Test{ private Object ob; // 不能定義T類型的變量?? public Test(Object ob){ this.ob = ob; } public void setT(Object ob){ this.ob = ob; } public Object getT(){ return this.ob; } public void showType(){ System.out.println("T的實際類型是:"+ob.getClass()); } }
咱們作實驗以下:spa
// 兩個基本類:StringDemo和DoubleDemo public class StringDemo { private String str; public StringDemo(String str){ this.str = str; } public void setStr(String str){ this.str = str; } public String getStr(){ return this.str; } } public class DoubleDemo { private Double doubleVal; public DoubleDemo(Double doubleVal){ this.doubleVal = doubleVal; } public void setDoubleVal(Double doubleVal){ this.doubleVal = doubleVal; } public Double getDoubleVal(){ return this.doubleVal; } } // 由於上面的類中,成員和方法的邏輯都同樣,就是類型不同,所以考慮重構。Object是全部類的父類,所以能夠考慮用Object作爲成員類型,這樣就能夠實現通用了,實際上就是「Object泛型」,暫時這麼稱呼。 public class ObjectDemo { private Object obj; public ObjectDemo(Object obj){ this.obj = obj; } public void setObj(Object obj){ this.obj = obj; } public Object getObj(){ return this.obj; } } public class MyDemo { public static void main(String args[]){ ObjectDemo str = new ObjectDemo("string"); ObjectDemo dble = new ObjectDemo(123d); ObjectDemo obj = new ObjectDemo(new Object()); System.out.println(str.getObj()); System.out.println(dble.getObj()); System.out.println(obj.getObj()); } } // 在Java 5以前,爲了讓類有通用性,每每將參數類型、返回類型設置爲Object類型,當獲取這些返回類型來使用時候,必須將其「強制」轉換爲原有的類型或者接口,
// 而後才能夠調用對象上的方法。強制類型轉換很麻煩,我還要事先知道各個Object具體類型是什麼,才能作出正確轉換。不然,要是轉換的類型不對,好比將
// 「Hello Generics!」字符串強制轉換爲Double,那麼編譯的時候不會報錯,但是運行的時候就掛了。那有沒有不強制轉換的辦法----有,改用 Java5泛型來實現,
// 示例見最上面FanXingClassTest<T>範型類的定義。
範型類語法解釋3d
1. 使用<T>來聲明一個類型持有者名稱,而後就能夠把T看成一個類型表明來聲明成員、參數和返回值類型。 2. class GenericsTest<T> 聲明瞭一個泛型類,這個T沒有任何限制,實際上至關於Object類型,實際上至關於 class GenericsTest<T extends Object>。 3. 與Object泛型類相比,使用泛型所定義的類在聲明和構造實例的時候,可使用「<實際類型>」來一併指定泛型類型持有者的真實類型。類如 GenericsTest<Double> douTest=new GenericsTest<Double>(new Double("33")); 4. 實際上,當構造對象時不指定類型信息的時候,默認會使用Object類型,這也是要強制轉換的緣由.
限制範型code
// 限制範型 public class CollectionGenTest<T extends Collection> { private T x; public CollectionGenTest(T x){ this.x = x; } public T getX(){ return this.x; } public void setX(T x){ this.x = x; } } public class CollectionGenTestDemo { public static void main(String args[]){ CollectionGenTest<ArrayList> test = new CollectionGenTest<ArrayList>(new ArrayList()); System.out.println("實例化完成"); } }
// 多接口限制
<T extends SomeClass & interface1 & interface2 & interface3>
// 通配符範型
<T extends Collection> //向下限制
<?> //任意類型,至關於Object
<T super Double> // 向上限制,Double類型或者其父類
Java範型方法htm
/** * 範型方法:只需在返回值前添加<T> */ public class ExampleA { public <T> void f(T x){ System.err.println(x.getClass().getName()); } public static void main(String args[]){ ExampleA exampleA = new ExampleA(); exampleA.f(""); exampleA.f(123); exampleA.f('a'); exampleA.f(exampleA); } }
// 使用泛型方法時,沒必要指明參數類型,編譯器會本身找出具體的類型。泛型方法除了定義不一樣,調用就像普通方法同樣
// 一個static方法,沒法訪問泛型類的類型參數,因此,若要static方法須要使用泛型能力,必須使其成爲泛型方法。
方法對象
1. 定義泛型方法時,必須在返回值前邊加一個<T>,來聲明這是一個泛型方法,blog
2. Class<T>的做用就是指明泛型的具體類型,而Class<T>類型的變量c,能夠用來建立泛型類的對象。爲何要用變量c來建立對象呢?既然是泛型方法,就表明着咱們不知道具體的類型是什麼,也不知道構造方法如何,所以沒有辦法去new一個對象,但能夠利用變量c的newInstance方法去建立對象,也就是利用反射建立對象。繼承
3. http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html接口