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