java泛型學習,獲取泛型的實際類型,泛型知識點總結
一、什麼是泛型
1、把明確數據類型的工作推遲到創建對象或者方法調用的時候纔去確定的特殊類型。
2、格式: Page<數據類型> , 注意: 該數據類型只能是引用類型。
3、泛型的種類:
泛型類 如: public class Generic<T> {}
泛型接口 如: public interface Face<T> {}
泛型方法 如: public <T> T get(T t){ return t;}
4、泛型的通配符:
<?> : 通配任意類型 ;
< ? extends E >: 只是當前類或及其子類 。(extends:繼承,當前或子類);
< ? super E > : 只是當前類或及其父類。(super:父類,當前或父類);
Gener<E extends GenericTest & Type>: 繼承某個類,且實現某個接口。
二、 泛型類的實際參數類型
1、 通過子類繼承泛型父類獲取
a. 定義一個父類,並設置泛型爲T。
public class Parent<T> {}
b. 定義一個子類,繼承父類。 並明確泛型類型爲String。
public class Child extends Parent<String> {}
c. 測試代碼
public static void main(String[] args) {
// 獲取 Child的父類 --- Parent
Type superClass = Child.class.getGenericSuperclass();
if( superClass instanceof ParameterizedType ){
ParameterizedType p = (ParameterizedType)superClass;
Type rawType = p.getRawType(); // 父類實際類型
Type[] actualTypes = p.getActualTypeArguments(); //父類泛型實際類型
System.out.println("父類類型: "+rawType.toString() + " 父類泛型實際類型:"+Arrays.toString(actualTypes));
}
}
d. 運行結果:
父類類型: class com.haha.study.generic.Parent 父類泛型實際類型:[class java.lang.String]
2、通過子類實現泛型接口獲取
a. 定義一個接口,並設置泛型爲T。
public interface Face<T> {}
b. 定義一個類,實現接口Face。並明確泛型類型爲String。
public class Body implements Face<String> {}
c. 測試代碼
public static void main(String[] args) {
// 獲取Body類所有實現的接口,數組 --- 一個類可以實現多個接口
Type[] faces = Body.class.getGenericInterfaces();
for (Type type : faces) {
if(ParameterizedType.class.isAssignableFrom(type.getClass())){
ParameterizedType p = (ParameterizedType)type;
Type rawType = p.getRawType(); // 接口類型
Type[] actualTypes = p.getActualTypeArguments(); // 泛型實
際類型
System.out.println("接口類型 :"+rawType.toString() + " 泛型實際類型:"+Arrays.toString(actualTypes));
}
}
}
d. 運行結果:
接口類型 :interface com.haha.study.generic.Face 泛型實際類型:[class java.lang.String]
三、泛型方法的實際參數類型
1、在一個類中定義一個方法,參數和返回值均帶有泛型類型
public class GenericMethodTest {
public List<String> rawType(Map<String,Integer> map,Set<?> set){
return null;
}
}
2、獲取方法中參數泛型實際類型
public static void main(String[] args) throws Exception {
// 1、 通過反射獲取 rawType 方法對象
Method method = GenericMethodTest.class.getMethod("rawType", Map.class,Set.class);
// 2、 獲取 rawType 方法的參數泛型類型 數組 --- 一個方法有多個參數
Type[] paramTypes = method.getGenericParameterTypes();
for (Type type : paramTypes) {
if(type instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType)type;
// 2、1 實際參數類型
Type rawType = pt.getRawType();
// 2、2 泛型參數類型 數組 --一個參數可能有多個泛型
Type[] actualTypes = pt.getActualTypeArguments();
StringBuffer sb = new StringBuffer();
for (Type type2 : actualTypes) {
sb.append(type2.toString()).append(" \t");
}
System.out.println("實際參數: "+rawType.toString() + " 泛型參數:"+ sb.toString());
}
}
}
2、1: 運行結果:
實際參數: interface java.util.Map 泛型參數:class java.lang.String class java.lang.Integer
實際參數: interface java.util.Set 泛型參數:?
3、獲取方法中返回值泛型實際類型
public static void main(String[] args) throws Exception {
// 1、 通過反射獲取 rawType 方法對象
Method method = GenericMethodTest.class.getMethod("rawType", Map.class,Set.class);
// 3、獲取 rawType 方法的返回值類型
Type returnType = method.getGenericReturnType();
System.out.println("returnType :"+returnType);
if(returnType instanceof ParameterizedType){
ParameterizedType pReturnType = (ParameterizedType)returnType;
// 3、1 獲取返回值實際參數類型
Type rawType = pReturnType.getRawType();
// 3、2 獲取返回值泛型參數類型 數組 --- 如: Map<K,V>
Type[] actualTypes = pReturnType.getActualTypeArguments();
StringBuffer sb = new StringBuffer();
for (Type type : actualTypes) {
sb.append(type.toString()).append("\t");
}
System.out.println("返回值 --> "+" 實際參數類型: "+rawType.toString() + " 泛型參數類型: "+sb.toString());
}
}
3、1:運行結果:
returnType :java.util.List<java.lang.String>
返回值 --> 實際參數類型: interface java.util.List 泛型參數類型: class java.lang.String
四、泛型變量的實際參數類型
1、在一個類中,定義帶有泛型的變量
public class GenericFieldTest {
private List<String> list ;
private Map<String,Integer> map;
}
2、獲取泛型變量的實際參數類型
public static void main(String[] args) throws Exception {
// 1、 獲取 Field list
Field list = GenericFieldTest.class.getDeclaredField("list");
// 2、 獲取 list 泛型類型
Type listType = list.getGenericType();
if(listType instanceof ParameterizedType){
ParameterizedType p = (ParameterizedType)listType ;
// 2、1 實際參數類型
Type rawType = p.getRawType();
// 2、2 泛型實際參數類型
Type[] actualTypes = p.getActualTypeArguments();
System.out.println("實際參數類型: "+rawType.toString() + " 泛型參數類型:"+Arrays.toString(actualTypes));
}
Field map = GenericFieldTest.class.getDeclaredField("map");
Type mapType = map.getGenericType();
if(ParameterizedType.class.isAssignableFrom(mapType.getClass())){
ParameterizedType p = (ParameterizedType)mapType;
Type rawType = p.getRawType();
Type[] actualTypes = p.getActualTypeArguments();
System.out.println("實際參數類型: "+rawType.toString() + " 泛型參數類型:"+Arrays.toString(actualTypes));
}
}
2、1:運行結果:
實際參數類型: interface java.util.List 泛型參數類型:[class java.lang.String]
實際參數類型: interface java.util.Map 泛型參數類型:[class java.lang.String, class java.lang.Integer]