zoukankan      html  css  js  c++  java
  • JAVA中反射机制四

    声明:如需转载请说明地址来源:http://www.cnblogs.com/pony1223

    反射四 利用反射获取类的属性

    1.通过反射也可以获取到类中的属性,假设我们继续使用Person这个类,然后设置部分属性,公有属性,私有属性,静态属性

    package study.reflect;
    
     
    
    import java.io.InputStream;
    
    import java.util.List;
    
     
    
    public class Person
    
    {
    
        /**
    
         * 为了测试用
    
         */
    
        public String name = "test";
    
       
    
        private int age = 1;
    
       
    
        public static int password = 12345;
    
       
    
       
    
        public Person()
    
        {
    
          
    
        }
    
       
    
        public Person(String name)
    
        {
    
           System.out.println("name:"+name);
    
        }
    
       
    
        public Person(String name,int age)
    
        {
    
           System.out.println("name:"+name+",age:"+age);
    
        }
    
       
    
        private Person(List list)
    
        {
    
           System.out.println("list");
    
        }
    
       
    
        public void sayHello()
    
        {
    
           System.out.println("hello");
    
        }
    
       
    
        public void sayHello(String name)
    
        {
    
           System.out.println("hello,"+name);
    
        }
    
       
    
        public String sayHello(String name,int age)
    
        {
    
           System.out.println("hello,"+name+",age:"+age);
    
           return name;
    
        }
    
       
    
        private void sayHello(InputStream in)
    
        {
    
           System.out.println("inputStream");
    
        }
    
       
    
        public static void sayHello(Person person)
    
        {
    
           System.out.println(person);
    
        }
    
       
    
        public static void main(String[] args) {
    
           System.out.println("main");
    
        }
    
    }
    
     

    2.然后通过反射获取属性

    package study.reflect;
    
     
    
    import java.lang.reflect.Field;
    
     
    
    import org.junit.Test;
    
     
    
    public class Demo04
    
    {
    
       
    
        @Test
    
        public void test01() throws Exception
    
        {
    
           Class<?> clazz = Class.forName("study.reflect.Person");
    
           Person person = (Person) clazz.newInstance();
    
           Field field = clazz.getField("name");
    
           Object object = field.get(person);
    
           if(field.getType().equals(String.class))
    
           {
    
               System.out.println((String)object);
    
           }
    
        }
    
       
    
       
    
        @Test
    
        public void test02() throws Exception
    
        {
    
           Class<?> clazz = Class.forName("study.reflect.Person");
    
           Person person = (Person) clazz.newInstance();
    
           Field field = clazz.getDeclaredField("age");
    
           field.setAccessible(true);
    
           Object object = field.get(person);
    
           System.out.println(object);
    
        }
    
       
    
        @Test
    
        public void test03() throws Exception
    
        {
    
           Class<?> clazz = Class.forName("study.reflect.Person");
    
           //Person person = (Person) clazz.newInstance();
    
           Field field = clazz.getField("password");
    
           Object object = field.get(null);
    
           System.out.println(object);
    
        }
    
    }
    
     
    
    结果如下:
    
    test
    
    1
    
    12345

    3.前面我们学习了获取类的属性,方法,构造对象,那么我们现在模拟下java的内省操作,如下:

    思路:定义一个Model类,里面所有的属性都是private的,然后为每个属性提供getter和setter方法;

    再准备一个Map,map的key值都是类里面的属性字段的字符串表示,值任意。

    设计一个方法ObjectgetModel(Mapmap,Classcls),传入一个包含所有值的Map,然后再传入Model类的class,那么返回Model类的实例,这个实例里面已经包含好了所有相关的数据。也就是把Map中的数据通过反射,设置回到Model类实例中。

    代码:

    import java.lang.reflect.Field; 
    
    import java.lang.reflect.Method; 
    
    import java.util.Map; 
    
     
    
    public class MyBeanUtils { 
    
        public static Object populate(Class cls,Map<String, Object> map) throws ReflectiveOperationException, IllegalAccessException{ 
    
            Object obj=null; 
    
            //1 用类反射new出对象 
    
            obj=cls.newInstance(); 
    
            //2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置 
    
               //2.1遍历出所有该类声明的属性 
    
            Field flds[]=cls.getDeclaredFields(); 
    
            for(Field fld:flds){ 
    
                //获取该fld对象所代表的属性名 
    
                String fldName=fld.getName(); 
    
                 //根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值  
    
                Object value=map.get(fld.getName());//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 
    
                if(value==null){ 
    
                    System.out.println(fld.getName()+"的数据为空"); 
    
                }else{ 
    
                    //如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字 
    
                    String methodName="set"+fldName.substring(0,1).toUpperCase()+fldName.substring(1); 
    
                     //根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象 
    
                    Method method=cls.getDeclaredMethod(methodName, fld.getType()); 
    
                     //调用该method对象所代表的方法 
    
                    Object params[]=new Object[1]; 
    
                    params[0]=value; 
    
                    method.invoke(obj, params); 
    
                } 
    
            } 
    
            return obj; 
    
        } 
    
        public static<T>  T populate2(Class<T> cls,Map<String, Object> map) throws ReflectiveOperationException, IllegalAccessException{ 
    
            T obj=null; 
    
            //1 用类反射new出对象 
    
            obj=cls.newInstance(); 
    
            //2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置 
    
               //2.1遍历出所有该类声明的属性 
    
            Field flds[]=cls.getDeclaredFields(); 
    
            for(Field fld:flds){ 
    
                //获取该fld对象所代表的属性名 
    
                String fldName=fld.getName(); 
    
                 //根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值  
    
                Object value=map.get(fld.getName());//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 
    
                if(value==null){ 
    
                    System.out.println(fld.getName()+"的数据为空"); 
    
                }else{ 
    
                    //如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字 
    
                    String methodName="set"+fldName.substring(0,1).toUpperCase()+fldName.substring(1); 
    
                     //根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象 
    
                    Method method=cls.getDeclaredMethod(methodName, fld.getType()); 
    
                     //调用该method对象所代表的方法 
    
                    Object params[]=new Object[1]; 
    
                    params[0]=value; 
    
                    method.invoke(obj, params); 
    
                } 
    
            } 
    
            return obj; 
    
        } 
    
    }  
  • 相关阅读:
    input、textarea 输入框IOS键盘顶起页面不反弹,Android手机隐藏掉input/textarea
    js调微信支付、支付宝支付
    axios封装
    h5 rem js
    h5 input输入框弹 键盘弹起再关掉,页面被顶起
    webpack vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin
    将url的查询参数解析成字典对象
    设计模式之桥接模式(Bridge)
    Google OKR 目标管理体系学习
    用EF6更新数据库时出现外键错误解决方式
  • 原文地址:https://www.cnblogs.com/pony1223/p/7446185.html
Copyright © 2011-2022 走看看