Type下面又有四個子接口類ParameterizedType、TypeVariable、GenericArrayType、WildcardTypejava
List<? extends Data>
,而裏面的 ? 稱爲通配符類型WildcardType
@AnTest("list")List<String>list
泛型: 把類型明確的工做推遲到建立對象或調用方法的時候纔去明確的特殊的類型
public class MainTest<T> { private T param; } public static void main(String[] args){ MainTest<String> data = new MainTest<String>(){}; ParameterizedType genType1 = (ParameterizedType)data.getClass().getGenericSuperclass(); }
public class MainTest{ public static void main(String[] args){ printData("siting"); } static <T> T printData(T t){ System.out.println(t); return t; } }
public class MainTest { public static void main(String[] args){ List<String> strArr = new ArrayList<>(); List<Integer> intArr = new ArrayList<>(); Type strClazz = strArr.getClass(); Type intClazz = intArr.getClass(); } }
public class MainTest<T> { T param; public static void main(String[] args){ MainTest<String> test = new MainTest<>(); test.setParam("siting"); } public T getParam() { return param; } public void setParam(T param) { this.param = param; } }
public class com/MainTest { ...省略 public static main([Ljava/lang/String;)V L0 LINENUMBER 7 L0 NEW com/MainTest DUP INVOKESPECIAL com/MainTest.<init> ()V ASTORE 1 L1 LINENUMBER 8 L1 ALOAD 1 LDC "siting" // 調用類型擦除後的setParam(Object) INVOKEVIRTUAL com/MainTest.setParam (Ljava/lang/Object;)V L2 ...省略//getParam 的返回值是Object public getParam()Ljava/lang/Object; L0 LINENUMBER 10 L0 ALOAD 0 GETFIELD com/MainTest.param : Ljava/lang/Object; ARETURN ...省略//setParam 的入參是Object public setParam(Ljava/lang/Object;)V L0 LINENUMBER 11 L0 ALOAD 0 ALOAD 1 PUTFIELD com/MainTest.param : Ljava/lang/Object; RETURN ... }
public class MainTest<T> { T param; static public class SubTest1 extends MainTest<String>{} static public class SubTest2<R> extends MainTest<R>{} //SubTest3繼承的時原生類型 static public class SubTest3 extends MainTest{} }
public class MainTest<T> { List<T> param; public static void main(String[] args) throws Exception{ Class clazz = MainTest.class; TypeVariable[] typeVariable = clazz.getTypeParameters(); // 1 Field field = clazz.getDeclaredField("param"); ParameterizedType arrayType = (ParameterizedType)field.getGenericType(); // interface List<E> 的泛型類型E被T,具體化,所以其被識別爲 TypeVariable TypeVariable variable1 = (TypeVariable)arrayType.getActualTypeArguments()[0]; // 2 ParameterizedType type = (ParameterizedType)SubTest.class.getGenericSuperclass(); TypeVariable variable2 = (TypeVariable)type.getActualTypeArguments()[0]; } static class SubTest<R> extends MainTest<R>{} }
public interface ParameterizedType extends Type { //獲取實際參數,List<String>裏的String; 若是是List<T>則是TypeVariable類型 Type[] getActualTypeArguments(); // 獲取原始類型List<String> -> List<E> Type getRawType(); Type getOwnerType(); }
Class clazz = List<String>.class
編譯時不經過的;還有就是直接經過泛型類new建立的對象,其Class並不是ParameterizedType類型,而是泛型自己的class,示例以下public class MainTest<T> { public static void main(String[] args){ MainTest<String> str = new MainTest<String>(); Class variable = str.getClass(); Type genType1 = variable.getGenericSuperclass(); } }
// 1 子類繼承泛型時,指定具體參數(能夠是String等已知類型,也能夠是子類的泛型參數) // 2 獲取在類內部定義的泛型屬性,需指定具體泛型參數 // 3 局部代碼,能夠經過泛型的匿名內部子類(需指定具體泛型參數)獲取ParameterizedType類型 public class MainTest<T> { List<T> list; public static void main(String[] args) throws NoSuchFieldException { SubTest<String> str = new SubTest<>(); // 方式一 Class variable = str.getClass(); // 父類是(521)ParameterizedType類型 ParameterizedType genType = (ParameterizedType)variable.getGenericSuperclass(); // (521)ParameterizedType類型的原生類型是(479)class com.MainTest Type clazz = genType.getRawType(); //MainTest.class 的原生類型是 (479)class com.MainTest Class rawClazz = MainTest.class; //方式二,泛型屬性 Field field = rawClazz.getDeclaredField("list"); //屬性list 類型是(546)ParameterizedType類型List<T> ParameterizedType fieldType = (ParameterizedType)field.getGenericType(); // 方式三 MainTest<String> sub3 = new MainTest<String>(){}; // clazz3是匿名子類 Class clazz3 = sub3.getClass(); //父類是(555)ParameterizedType類型 ParameterizedType genType3 = (ParameterizedType) clazz3.getGenericSuperclass(); // (555)ParameterizedType類型的原生類型是(479)class com.MainTest Type type3 = genType3.getRawType(); } public static class SubTest<R> extends MainTest<R>{ } }
public static void print(List list){} ----->>> public static void print(List<?> list){}
List<? extends Number的子類>
,代表List裏的元素都是Number的子類public static void print(List<? extends Number> list) { Number n = new Double("1.0"); list.add(n); Number tmp = list.get(0); }
class Parent{ } class Child extends Parent{ } public class MainTest<T> { T param; public static void main(String[] args){ MainTest<? super Child> parent_m = new MainTest<>(); parent_m.setParam(new Child()); Object parent = parent_m.getParam(); } public T getParam() { return param; } public void setParam(T param) { this.param = param; } }
public interface GenericArrayType extends Type { //得到這個數組元素類型,即得到:A<T>(A<T>[])或 T(T[]) Type getGenericComponentType(); }
public class MainTest<T> { T[] param; public static void main(String[] args) throws Exception{ Class clazz = MainTest.class; Field field = clazz.getDeclaredField("param"); GenericArrayType arrayType = (GenericArrayType)field.getGenericType(); TypeVariable variable = (TypeVariable) arrayType.getGenericComponentType(); } }