内省及反射属性复制案例

1、内省

JavaBean


pojo:   plain old java object.
标准javabean.
class Person{

    private String name ;

    public Person(){
    }

    //getter
    public String getName(){
        return name ;
    }

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

广义上的javabean


Property
---------------
    属性                  //通过标准javabean的get/set方法得到的属性


Field
----------------
    字段。
    成员变量。

Introspector:

内省.
Introspector.getBeanInfo(Class clazz);          //得到类的Bean信息
BeanInfo                                        //类的Bean信息。
BeanInfo.getPropertyDescriptor()                //属性描述符
BeanInfo.getMethodDescriptor()                  //方法描述符。
PropertyDescritor.getReadMethod()               //获得getXxx方法()
PropertyDescritor.getWriteMethod()              //获得setXxx方法()
 1 /**
 2  * 测试内省(可以得到从父类继承的get、set方法)
 3  * 
 4  * @author feigu
 5  *
 6  */
 7 public class TestIntrospector {
 8     public static void main(String[] args) {
 9         try {
10             BeanInfo info = Introspector.getBeanInfo(Person.class);
11             // 得到属性描述符
12             PropertyDescriptor[] pds = info.getPropertyDescriptors();
13             for (PropertyDescriptor pd : pds) {
14                 System.out.println(pd.getName());
15                 System.out.println("-------------");
16                 // 得到get方法
17                 System.out.println(pd.getReadMethod());
18                 System.out.println("_______________");
19                 // 得到set方法
20                 System.out.println(pd.getWriteMethod());
21             }
22         } catch (IntrospectionException e) {
23             // TODO Auto-generated catch block
24             e.printStackTrace();
25         }
26     }
27 }

属性的复制

 1 public class IntrospectorDemo {
 2 
 3     public static void main(String[] args) {
 4         Student s1=new Student("小明", 23, "No111");
 5         Student s2=new Student();
 6         Class calzz=Student.class;
 7         Field[] fields = calzz.getDeclaredFields();
 8         //通过class得到对应beaninfo对象
 9         try {
10             BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
11             PropertyDescriptor[] ppds = beanInfo.getPropertyDescriptors();
12             for (PropertyDescriptor ppd : ppds) {
13                 System.out.println(ppd.getReadMethod());
14                 Object object = ppd.getReadMethod().invoke(s1);
15                 System.out.println(object);
16                 //去除setClass方法的影响
17                 if(ppd.getWriteMethod()==null){
18                     continue;
19                 }
20                 ppd.getWriteMethod().invoke(s2, object);
21             }
22             System.out.println(s2.getStuNo()+ ":"+s2.getName()+":"+s2.getAge());
23         } catch (Exception e) {
24             e.printStackTrace();
25         }
26     }
27 }

 

2、反射案例(通过反射实现对象属性的复制)

反射

动态访问对象或类的属性和方法。 

Class

类描述符.
Class clazz = Person.class ;
clazz = Class.forName("x.x.x.x.xxx");
//new Person();
clazz.newInstance();

Method

方法描述符。
//定义方法
clazz.getDeclaredMethod(String , Class...);
//可见方法。
clazz.getMethod(String name,Class...);
Method.setAccessible(true);         //内存中

Field

字段描述符
Class.getDeclaredField(String name) ;
Field.setAccessible(true);
int mod = Field.getModifier();
Modifier.isStatic(mod) ;

Constructor

构造器描述符。
Class.getDeclaredConstructor(Class...)
Constructor.newInstance(...);

a instanceof Person

模糊判断。

Person.class == a.getClass()

精确判断。
/**
 * 通过反射实现对象属性的复制
 * @author feigu
 *
 */
public class PersonDemo {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Person p1 = new Person("xiaoming", 12);
        //Person p2 = new Person();
        Dog dog = new Dog();
        // propCopy(p1, p2);
        //promCopy(p1, p2);
        promCopy(p1, dog);
        System.out.println(dog);

    }

    // 通过字段进行属性复制
    public static void propCopy(Person a, Person b) throws Exception {
        Field[] clazz = a.getClass().getDeclaredFields();
        for (Field f : clazz) {
            // String f=field.getName();
            f.setAccessible(true);
            Object ob = f.get(a);
            f.set(b, ob);
            // System.out.println(f);

        }
    }

    // 通过方法进行属性复制
    public static void promCopy(Person a, Dog b) throws Exception {
        Method[] methods_a = a.getClass().getDeclaredMethods();
        Class clazz= b.getClass();
        for (Method mm_a : methods_a) {
            // 方法名
            String m_a = mm_a.getName();
            // c参数类型
            Class[] parameterTypes = mm_a.getParameterTypes();
            // 返回值类型
            Class returnType = mm_a.getReturnType();
            if (m_a.startsWith("get") && (parameterTypes == null || parameterTypes.length == 0)
                    && returnType != void.class) {
                //得到对应参数类型和返回值的b对象方法
                String m_b= m_a.replace("get", "set");
                try {
                    mm_a.setAccessible(true);
                    Method mm_b = clazz.getDeclaredMethod(m_b, returnType);
                    Object obj = mm_a.invoke(a);
                    mm_b.setAccessible(true);
                    mm_b.invoke(b, obj);
                } catch (Exception e) {
                    continue;
                }
                
                }
            }
        }
    }

 3、属性测试

 1 public class TestReflectApp {
 2 
 3     public static void main(String[] args) throws Exception {
 4         //
 5         InputStream is = new FileInputStream("D:\\eclipse-workspace-bigdata4\\Java25\\src\\objects.properties");
 6 //        byte[] bytes = new byte[is.available()];
 7 //        is.read(bytes);
 8 //        //is.close();
 9         //System.out.println(new String(bytes));
10         Properties prop = new Properties();
11         prop.load(is);
12         
13         //
14         String objClass = prop.getProperty("object.class");
15         Class clazz = Class.forName(objClass);
16         Object obj = clazz.newInstance();
17         
18         //name
19         String propName = prop.getProperty("object.prop1.name");
20         String propValue = prop.getProperty("object.prop1.value");
21         Field f = clazz.getDeclaredField(propName);
22         if(f.getType() == String.class){
23             f.setAccessible(true);
24             f.set(obj, propValue);
25         }
26         
27         
28         //name
29         propName = prop.getProperty("object.prop2.name");
30         propValue = prop.getProperty("object.prop2.value");
31         f = clazz.getDeclaredField(propName);
32         if(f.getType() == int.class){
33             f.setAccessible(true);
34             Integer i = Integer.parseInt(propValue) ;
35             f.set(obj, i);
36         }
37         
38     }

 

posted on 2017-04-29 10:21  艺海浮台  阅读(191)  评论(0编辑  收藏  举报