[TOC]html
泛型,也就是將類型參數化,而後在使用類或者方法的時候能夠傳入類型,在不須要建立新類型實現的前提下能夠經過泛型控制形參的類型。泛型能夠用在類,方法和接口中。java
在使用泛型的代碼中常常能夠看到一些泛型相關的符號,它們的做用以下表所示:post
類型 | 功能 |
---|---|
T,E,K,V | 泛型標識,能夠寫人任意標識,不一樣字母更可能是一種約定,等同於< T extends Object> |
? | 無限制通配符,表示不肯定類型,等同於< ? extends Object> |
extend | 上界通配符 |
super | 下界通配符 |
& | 附加約束(AdditionalBound, tjls8-4.4) |
public class GenericDemo<C> { //泛型類 public static void main(String[] args) { //泛型類用Integer初始化,因此C相關的方法屬性必須是Integer GenericDemo<Integer> gd = new GenericDemo<Integer>(); gd.classPrint(1); gd.setX(2); //---------------------- //泛型方法,與調用的類型保持一致,參數類型得爲String GenericDemo.<String>methodPrint("abc"); //--------------------- //泛型接口,與初始化時候傳入的類型保持一致,參數類型得是Double IFC<Double> ifc = new IFC<Double>() {}; ifc.interfacePrint(2.9); } private C c; public void setX(C c) { this.c = c; } public void classPrint(C c) { System.out.println(c.getClass()); } //泛型方法,前面的<T>是爲了標識這是一個泛型方法 public static <T> void methodPrint(T t) { System.out.println(t.getClass()); } interface IFC<I> { //泛型接口 default void interfacePrint(I i) { System.out.println(i.getClass());} } }
基本泛型T是用於定義,將數據類型參數化,不能用於實例化。而 ? 則是在實例化對象時不肯定泛型具體參數類型的時候泛指Object的全部子類型。this
類型 | 特色 |
---|---|
T | < T extends Object>,用於定義 |
? | < ? extends Object>,用於實例化 |
?不能和Object等效,<u>?是類型實參而不是類型形參,它用於泛指各類類型實參</u>,當具體類型不肯定的時候就可使用?,示例以下:spa
public class test6 { public static void main(String[] args) { List<String> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); test(list1); test(list2); } public static void test(List<?> list) { System.out.println(list); } }
上下界通配符其實涉及到java 的多態屬性,上下轉型的可行性,<u>子類實例能夠轉換成父類實例,可是父類實例卻不必定能轉換成子類實例,只有自己就是該子類實例向上轉型的父類實例才能夠向下轉型爲子類實例。</u>.net
<? extends T> 表示類型範圍爲T以及其子類,<? super T>表示類型範圍爲T及其父類。 界限通配符在應用於集合的時候會影響集合的讀寫行爲: 上界<? extends T> 限制了類型上限,只能向上轉型,能夠讀,可是無法寫,由於子類型不肯定,無法向下轉型; 下界<? super T>限制類型的下限,只能向下轉型,能夠寫,可是無法讀,由於父類型不肯定,無法向上轉型。 示例: ```java public class test { public static void main(String[] args) { //<? extends B> 範圍: A類或者A的子類 //因爲下限不肯定,因此沒法向下轉型至具體類型 List<? extends B> list1 = new ArrayList<B>(){{add(new B());}}; // list1.add(new B()); //沒法添加該類型, 向下轉型沒法肯定目標類型 // list1.add(new C()); A a = list1.get(0); //正常向上轉型 //<? super B> 範圍: B類或者B的父類 //因爲上限不肯定,因此B類和B類的子類都可以加入,可是B類的父類不行 List<? super B> list2 = new ArrayList<>(); // list2.add(new A()); //沒法向下轉型 list2.add(new B()); //正常向上轉型 list2.add(new C()); // C c = list2.get(0);//沒法向下轉型,不增強制轉換會報錯 C c = (C)list2.get(0); } // A -> B -> C static class A {}; static class B extends A {}; static class C extends B {}; } ``` ## 4, 附加約束(&) AdditionalBound 的語法以下: ``` TypeBound: extends ClassOrInterfaceType {AdditionalBound} AdditionalBound: & InterfaceType ``` 也就是說extends後面能夠在加個額外約束,具體爲接口類型,能夠I1 & I2 & I3這樣連排,注意必須是接口類型,不能是class或者類型變量,這裏額外約束的做用是限制類型必須實現相關的接口,示例以下: ```java public class test { public static void main(String[] args) { test1(1); test1("1"); test2(2); test2("2"); // test3(3); //test3方法String類型才知足額外約束 test3("3"); } public static <T extends Object> void test1(T t) { System.out.println(t.getClass()); } //得同時實現Serializable和Comparable接口 public static <T extends Object & Serializable & Comparable> void test2(T t) { System.out.println(t.getClass()); } //得同時實現Serializable,CharSequence和Comparable接口 public static <T extends Object & Serializable & CharSequence & Comparable> void test3(T t) { System.out.println(t.getClass()); } } ``` 此外,附加約束還可用於類型強制轉換: ```java public class test12 { public static void main(String[] args) { System.out.println(test()); } public static Object test() { // return (Object & Number)"abced"; //編譯不經過 // return (Object)"abced"; //編譯經過 return (Object & CharSequence & Comparable)"abcde"; //編譯經過 } } ``` 在一些類型轉換的場景能夠經過附加約束控制類型轉換的範圍。 參考連接: [https://codeday.me/bug/20190313/767875.html](https://codeday.me/bug/20190313/767875.html) [https://juejin.im/post/5b614848e51d45355d51f792](https://juejin.im/post/5b614848e51d45355d51f792) [https://www.cnblogs.com/whatlonelytear/p/11055126.html](https://www.cnblogs.com/whatlonelytear/p/11055126.html) [https://blog.csdn.net/s10461/article/details/53941091](https://blog.csdn.net/s10461/article/details/53941091) [https://blog.csdn.net/claram/article/details/51943742](https://blog.csdn.net/claram/article/details/51943742)code
原文出處:https://www.cnblogs.com/cord/p/11616353.htmlhtm