天天看點

java增強:反射機制,内省機制

  1. 反射機制概念
  2. 發射的使用場景
  3. 内省機制的使用

part1 :反射機制(  jdk提供的一套api,  用于動态建立對象 )

java增強:反射機制,内省機制

java增強:反射機制,内省機制

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 Student extends Per{
    private int score;
    public int getScore(){return score;}
    public void setScore(int score){this.score=score;}
}
           

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());
    }
           

繼續閱讀