一、什么是泛型
1、把明确数据类型的工作推迟到创建对象或者方法调用的时候才去确定的特殊类型。
2、格式: Page<数据类型> , 注意: 该数据类型只能是引用类型。
3、泛型的种类:
泛型类 如: public class Generic {}
泛型接口 如: public interface Face {}
泛型方法 如: public T get(T t){ return t;}
4、泛型的通配符:
> : 通配任意类型 ;
< ? extends E >: 只是当前类或及其子类 。(extends:继承,当前或子类);
< ? super E > : 只是当前类或及其父类。(super:父类,当前或父类);
Gener: 继承某个类,且实现某个接口。
二、 泛型类的实际参数类型
1、 通过子类继承泛型父类获取
a. 定义一个父类,并设置泛型为T。
public class Parent {}
b. 定义一个子类,继承父类。 并明确泛型类型为String。
public class Child extends Parent {}
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 {}
b. 定义一个类,实现接口Face。并明确泛型类型为String。
public class Body implements Face {}
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 rawType(Map 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
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
返回值 --> 实际参数类型: interface java.util.List 泛型参数类型: class java.lang.String
四、泛型变量的实际参数类型
1、在一个类中,定义带有泛型的变量
public class GenericFieldTest {
private List list ;
private Map 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]