zoukankan      html  css  js  c++  java
  • 内省及反射属性复制案例

    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     }
  • 相关阅读:
    Q739.每日温度
    面试题46. 把数字成字符串
    [990. 等式方程的可满足性]--并查集
    [128. 最长连续序列]
    javaweb实现简单登陆功能
    7.12_python_lx_practise
    7.12_python_lx_day6
    7.12_python_lx_day5
    7.2_python_lx_day4
    7.2_python_lx_day3
  • 原文地址:https://www.cnblogs.com/yihaifutai/p/6784612.html
Copyright © 2011-2022 走看看