(反射):获取一个类的父类和父类的泛型
一、解决问题
- 获取一个类的父类和父类的泛型
二、实现
- Student.java
package Test3; public class Student { private String name; private String sex; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } }
- Genericity.java
package Test3; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.HashMap; import java.util.Map; public abstract class Genericity<T> { @SuppressWarnings("rawtypes") protected Class clazz; @SuppressWarnings("unchecked") public Genericity() { // 通过反射机制获取子类传递过来的实体类的泛型类型信息 //ParameterizedType类为Type类的子类,用于获得超类的泛型参数的实际类型。具体请查看(1) //this.getClass()用于获取子类的class信息。具体查看(2) ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz = (Class<T>) type.getActualTypeArguments()[0]; } protected Map<String, Object> getMap(T cla) { Map<String, Object> map = new HashMap<String, Object>(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); //类中的成员变量为private,故必须进行此操作 try { map.put(field.getName(), field.get(cla)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return map; } }
- (1) ParameterizedType
- getClass().getGenericSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type,然后将其转换ParameterizedType。 - getActualTypeArguments()
返回表示此类型实际类型参数的 Type 对象的数组。[0]就是这个数组中第一个了。简而言之就是获得超类的泛型参数的实际类型 - Type和ParameterizedType可以理解为: 由一个类可以得到这个类的Type类型,比如一个类:Class Test extends Person<Student> Test这个类可以通过getClass().getGenericSuperclass()这个方法得到超类Person的Type,这个Type为:“Person所在的包.Person<Student所在的包.Student>” ,而ParameterizedType.getActualTypeArguments则得到Person<Student>中的泛型类型(即Student)并返回Typ[]。
- getClass().getGenericSuperclass()
- (2)在继承关系中,不管父类还是子类,这些类里面的this都代表了最终new出来的那个类的实例对象,在子类GenericityTest(继承于Genericity)中只是实例化了GenericityTest这个子类,而GenericityTest的构造方法中默认会默认调用父类Genericity的构造方法,而在父类Genericity的构造方法中存在this.getClass(),此时this.getClass()得到的Class为子类GenericityTest(因为GenericityTest有被new实例化,而父类的构造方法虽然被调用,但是调用构造方法并不是实例化对象)
- GenericityTest.java
package Test3; import java.util.Map; import javax.swing.plaf.synth.SynthSeparatorUI; /** * 测试获取一个类的父类和父类的泛型 * @author Administrator * */ public class GenericityTest extends Genericity<Student> { public static void main(String[] args) { Student stu=new Student(); stu.setName("张三"); stu.setAge("15"); stu.setSex("男"); GenericityTest test=new GenericityTest(); Map<String,Object> map=test.getMap(stu); System.out.println(map); } }
结果: