java增强:反射机制,内省机制

  1. 反射机制概念
  2. 发射的使用场景
  3. 内省机制的使用

part1 :反射机制(  jdk提供的一套api,  用于动态创建对象 )


part2:  反射的使用----两个对象间属性值的复制

(浅copy:  复制一个对象,会调用构造函数)

一个存在继承关系的类:  对象的浅copy 代码实现如下

1, 定义两个javabean

public class Per {
    //属性
    private int age;
    private String name;

    //构造
    public Per(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public Per() {
        System.out.println("per 无参构造");
    }

    //get,set
    public int getAge() {       return age;  }
    public void setAge(int age) {      this.age = age;  }
    public String getName() {     return name; }
    public void setName(String name) {     this.name = name; }
}

//----------------------------------------
public class Per {
    //属性
    private int age;
    private String name;

    //构造
    public Per(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public Per() {
        System.out.println("per 无参构造");
    }

    //get,set
    public int getAge() {       return age;  }
    public void setAge(int age) {     this.age = age; }
    public String getName() {     return name; }
    public void setName(String name) {     this.name = name; }
}

2, 创建对象1, 复制为对象2-----------反射:(构造+ 字段   ),  ( 构造 + set/get  ),(构造+ get)

 //创建对象: 有属性
Student st = new Student();
@before
public void init(){     
     st.setName("yyyy");
     st.setAge(23);
     st.setScore(99)
}

 /**
     * 反射: 通过属性---copy对象
     * @throws Exception
     */
    @Test
    public void t1() throws Exception {       
        //创建对象: 带参构造
        Class<?> clazz = Class.forName("Student");
        Constructor<?> cons = clazz.getDeclaredConstructor(int.class);
        Student student = (Student) cons.newInstance(80);
        //获取: 父类属性--------------------------
        Class<?> sup = clazz.getSuperclass();
        Field age = sup.getDeclaredField("age");
        age.setAccessible(true);
        Field name = sup.getDeclaredField("name");
        name.setAccessible(true);
        //赋值
        age.set(student,st.getAge());
        name.set(student,st.getName());
        System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
    }

 /**
     * 反射: 通过方法----copy对象
     * @throws Exception
     */
    @Test
    public void t2() throws Exception {     
        //创建对象: 带参构造
        Class<?> clazz = Class.forName("Student");
        Constructor<?> cons = clazz.getDeclaredConstructor(int.class);
        Student student = (Student) cons.newInstance(89);
        //获取: 父类方法
        Method setAge = clazz.getMethod("setAge", int.class);
        Method setName = clazz.getMethod("setName", String.class);
        //赋值
        setAge.invoke(student, st.getAge());
        setName.invoke(student, st.getName());
        System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
    }

@Test
    public void t3() throws Exception {
        /**
         * get--->set方法名,  参数
         */
         //创建对象       
        Class<?> clazz = Class.forName("Student");
        Student st2 = (Student) = clazz.newInstance();
        //get方法---》set赋值
        Class clazz = st.getClass();
        Method[] ms = clazz.getMethods();

        //判断: 是否getAge()
        for (Method m : ms) {
            String get = m.getName();
            Class<?>[] paramType = m.getParameterTypes();
            Class<?> retType = m.getReturnType();

            if (get.startsWith("get") && paramType.length == 0 && retType != Class.class) {
                Object returnVal = m.invoke(st);
                String set = get.replace("get", "set");
                //set : 参数---->第二个Obj赋值
                Method setMetho = clazz.getMethod(set, retType);
                setMetho.invoke(st2, returnVal);
            }
        }
        System.out.println(st2.getName() + "," + st2.getAge() );
    }

part3:  内省机制---对象copy

 @Test
    public void t4() throws Exception {

        Student st = new Student();
        st.setAge(40);
        st.setName("aaaa");
        st.setScore(99);
        Student st2 = new Student();

        /**
         * 内省: 实现---2个对象:  属性拷贝
         */
        BeanInfo binfo = Introspector.getBeanInfo(st.getClass());
        PropertyDescriptor[] propDes = binfo.getPropertyDescriptors();

        for (PropertyDescriptor proDescriptor : propDes) {

            Method read = proDescriptor.getReadMethod();
            Method write = proDescriptor.getWriteMethod();
            String fieldName = proDescriptor.getName();

            if (read != null && write != null) {
                if (!fieldName.equals("class"))
                    write.invoke(st2, read.invoke(st));
            }
        }
        System.out.println(st2.getName() + "," + st2.getAge()+ ","+st2.getScore());
    }

part4: 对象的深度copy  

( 不会调用构造方法,  父类和子类: 都要 implements Serializable)

@Test
    public void t5() throws IOException, ClassNotFoundException {
        Student st = new Student();
        st.setAge(40);
        st.setName("aaaa");

        //把各个属性:  组合为byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream objout = new ObjectOutputStream(baos);
        objout.writeObject(st);
        baos.close();
        objout.close();

        ObjectInputStream objin = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
        Student student= (Student) objin.readObject();
        objin.close();
        System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
    }

猜你喜欢

转载自blog.csdn.net/eyeofeagle/article/details/82712597