反射及利用反射复制对象的demo

反射是java编程的灵魂,在用反射之前有几个类需要了解:Class,Method,Feild,Constructor,在demo中演示这些类中比较常用的方法,然后用反射实现copy对象的封装类来说明反射的微妙。

1、常用方法:

public class ReflectDemo {

    /** Class */
    @Test
    public void testClass() throws Exception{
        Class<?> claz = People.class;
        // 1、getMethods(), 获取所有方法,包括notify等从Object继承的方法
        Method[] methods = claz.getMethods();
        Arrays.asList(methods).forEach(method -> System.out.println(method.getName()));

        // 2、getMethod(String name, Class<?>... parameterTypes), 方法名及参数列表
        Method method = claz.getMethod("setName", String.class);
        System.out.println(method.getName());

        // 3、getClassLoader(), 加载器
        System.out.println(claz.getClassLoader());

        // 4、newInstance(), 获取实例
        Object instance = claz.newInstance();
        if (instance instanceof People) {
            People people = (People) instance;
            people.setAddress("广东深圳");
            System.out.println(people);
        }

        System.out.println("------------Field-------------");
        // 5、getFields(), 获取共有属性字段
        Field[] fields = claz.getFields();
        Arrays.asList(fields).stream().forEach(field -> System.out.println(field.getName()));

        // 6、getDeclaredFields(), 获取所有字段,包括私有
        Field[] declaredFields = claz.getDeclaredFields();
        Arrays.asList(declaredFields).stream().forEach(field -> System.out.println(field.getName()));

        System.out.println("------------Constructor-------------");
        // 7、getConstructors(), 获取构造方法
        Constructor<?>[] constructors = claz.getConstructors();
        Arrays.asList(constructors).stream().forEach(constructor -> System.out.println(constructor.getParameterCount()));
    }

    /** Method */
    @Test
    public void testMethod() throws Exception{
        People people = new People("11001", "张三", "广东深圳", "程序员");
        Class<?> clazz = people.getClass();
        Constructor<?> constructor = clazz.getConstructor(String.class, String.class, String.class, String.class);
        System.out.println(constructor.getName());

        Method action = clazz.getMethod("action", String.class, String.class, String.class);

        // 1、getName(), 方法名称
        String name = action.getName();
        System.out.println(name);

        // 2、getParameterCount(), 参数数量
        int parameterCount = action.getParameterCount();
        System.out.println(parameterCount);

        // 3、getParameterTypes(), 参数类型
        Class<?>[] parameterTypes = action.getParameterTypes();
        Arrays.asList(parameterTypes).stream().forEach(para -> System.out.println(para.getName()));

        // 4、getReturnType(), 获取返回类型
        Class<?> returnType = action.getReturnType();
        System.out.println(returnType.getName());

        // 5、getDeclaredAnnotations(), 获取使用的注解
        Annotation[] declaredAnnotations = action.getDeclaredAnnotations();
        System.out.println(declaredAnnotations.length);

        // 6、改变对象的值
        Method setAddress = clazz.getMethod("setAddress", String.class);
        setAddress.invoke(people, "北京市海淀区");
        System.out.println(people);

        System.out.println("***** and so on *****");
    }

    /** Field */
    @Test
    public void testField() throws Exception{
        People people = new People("11001", "张三", "广东深圳", "程序员");
        Class<?> clazz = people.getClass();

        // 1、getField(), 只能获取共有字段
        Field field = clazz.getField("work");
        Object work = field.get(people);
        System.out.println(work);

        // 2、getDeclaredField(), 可以获取包括私有字段
        Field address = clazz.getDeclaredField("address");
        // 设置访问权限
        address.setAccessible(true);
        Object o = address.get(people);
        System.out.println(o);  // out -> 广东深圳
    }
}

2、很多情况下,在java编程中可能会遇到VO,DO对象相互转换的情况,同时两个实体类的字段比较相似,当然可以通过写setter方法来手动设置(试想有几十个字段的时候呢),这里通过反射实现一个封装,简化冗余的set赋值:
 

public class CopyDemo {

    @Test
    public void testCopy() throws Exception{
        StudentDO studentDO = new StudentDO(1101, "张三", "2015018", 98.5, "man", "football", 25);
        StudentVO studentVO = new StudentVO();

        // studentDO -> studentVO
        copyUtils(studentDO, studentVO);

        System.out.println(studentVO);
    }

    private void copyUtils( StudentDO studentDO, StudentVO studentVO) throws Exception{
        Class<?> clazzVO = studentVO.getClass();
        Class<?> clazzDO = studentDO.getClass();

        Method[] methodsVO = clazzVO.getMethods();
        for (Method methodVO : methodsVO) {
            // VO的set方法
            String nameVO = methodVO.getName();
            if (!nameVO.startsWith("set")) {
                continue;
            }
            // 获取VO参数类型
            Class<?>[] parameterTypes = methodVO.getParameterTypes();
            if (parameterTypes.length < 1) {
                continue;
            }
            Class<?> paraType = parameterTypes[0];

            // DO的get方法
            String nameDO = "get" + StringUtils.toUpperCase(nameVO.charAt(3) + "") + nameVO.substring(4);
            Method methodDO = clazzDO.getMethod(nameDO);
            // 获取DO返回类型
            Class<?> returnType = methodDO.getReturnType();
            // 通过get获取值
            Object invokeValue = methodDO.invoke(studentDO);

            // 按理说returnType和paraType类型一致, 如果不一致判断后转换即可
            if (returnType.getName().equals(paraType.getName())) {
                methodVO.invoke(studentVO, invokeValue);
            }
        }
    }
}

两个实体类(除了雷名不同,其他先设定为相同)

StudentVO.java:

public class StudentVO {
    private Integer id;
    private String name;
    private String sno;
    private Double score;
    private String sex;
    private String hobby;
    private Integer age;

    public StudentVO() {

    }
    public StudentVO(Integer id, String name, String sno, Double score, String sex, String hobby, Integer age) {
        this.id = id;
        this.name = name;
        this.sno = sno;
        this.score = score;
        this.sex = sex;
        this.hobby = hobby;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSno() {
        return sno;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "StudentVO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sno='" + sno + '\'' +
                ", score=" + score +
                ", sex='" + sex + '\'' +
                ", hobby='" + hobby + '\'' +
                ", age=" + age +
                '}';
    }
}

StudentDO.java

public class StudentDO {
    private Integer id;
    private String name;
    private String sno;
    private Double score;
    private String sex;
    private String hobby;
    private Integer age;

    public StudentDO() {

    }
    public StudentDO(Integer id, String name, String sno, Double score, String sex, String hobby, Integer age) {
        this.id = id;
        this.name = name;
        this.sno = sno;
        this.score = score;
        this.sex = sex;
        this.hobby = hobby;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSno() {
        return sno;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "StudentDO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sno='" + sno + '\'' +
                ", score=" + score +
                ", sex='" + sex + '\'' +
                ", hobby='" + hobby + '\'' +
                ", age=" + age +
                '}';
    }
}

猜你喜欢

转载自blog.csdn.net/ldw201510803006/article/details/83048854