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; 

    } 

}  

 

posted on 2017-08-28 22:53  pony1223  阅读(678)  评论(0编辑  收藏  举报

导航