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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章