欢迎来访...
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用反射和内省对对象的操作

Posted on 2014-03-20 13:43  天赐绝尘  阅读(144)  评论(0编辑  收藏  举报


先定义一个学生类:

类中具备getter、setter

class Student {
	private String name;
	private int age;
	public Student(String s, int a){
		this.name = s;
		this.age = a;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

分别使用反射和内省对对象的操作:

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class IntroSpectorTest {

	public static void main(String[] args) throws Exception {
	
		Student s = new Student("zhangsan", 20);
		Student s1 = new Student("lisi", 20);
		//通过反射获得s的各项值
		Method methodGetName = s.getClass().getMethod("getName");
		String name = (String) methodGetName.invoke(s);
		System.out.println(name);
		//通过内省获得...
		PropertyDescriptor pd = new PropertyDescriptor("name", s.getClass());
		Method methodGetName1 = pd.getReadMethod();
		String name1 = (String) methodGetName1.invoke(s);
		System.out.println(name1);
		
		System.out.println("-----------");
		//继续使用反射对s对象赋值
		Method methodSetNmae = s.getClass().getMethod("setName", String.class);
		methodSetNmae.invoke(s, "lisi");
		System.out.println(s.getName());
		
		//继续使用内省对s对象赋值
		Method methodSetName1 = pd.getWriteMethod();
		methodSetName1.invoke(s1, "zhangsan");
		System.out.println(s1.getName());
		
		System.out.println("-------------");
		//对其他属性操作
		PropertyDescriptor pd1 = new PropertyDescriptor("age", s.getClass());
		Method methodGetAge = pd1.getReadMethod();
		System.out.println(methodGetAge.invoke(s1));
		Method methodSetAge = pd1.getWriteMethod();
		methodSetAge.invoke(s1, 23);
		System.out.println(s1.getAge());
	}
}

两者分别是怎样实现对元素的操作的呢?

反射:

1、获得某类的某个具体操作方法 (通过类.class文件调用方法,并传入方法名和参数获得)

2、使用获得的方法操作属性 (调用得到的方法传入对象以及需要的参数操作属性)

内省:

1、获得某对象的某一属性 (通过传入属性名称,类.class获得相应的属性对象)

2、获得某类的某个具体操作方法 (通过属性对象获得get/set方法)

3、使用获得的方法操作属性 (同反射)


提取方法---优化后的内省操作对象属性代码:

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IntroSpectorTest {

	public static void main(String[] args) throws Exception {
	
		Student s = new Student("zhangsan", 20);

		//通过内省获得属性值
		String propertyName = "name";
		Object retVal = getProperty(s, propertyName);
		System.out.println("s对象的名字"+retVal);
			
		//使用内省对属性赋值
		setProperty(s, propertyName);
		System.out.println("设置后的名字:"+s.getName());	

	}
	
	//内省中提取出来的设置属性的方法
	private static void setProperty(Student s, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, s.getClass());
		Method methodSetName = pd.getWriteMethod();
		methodSetName.invoke(s, "lisi");
	}
	
	//内省中提取出来的获取属性的方法
	private static Object getProperty(Student s, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, s.getClass());
		Method methodGetName1 = pd.getReadMethod();
		Object retVal = methodGetName1.invoke(s);
		return retVal;
	}
}

通过遍历某一.class获得属性:

//内省中通过遍历某一.class获得属性
	private static Object getProperty(Student s, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
		Object retVal = null;
		BeanInfo beanInfo = Introspector.getBeanInfo(s.getClass());
		PropertyDescriptor[] prop = beanInfo.getPropertyDescriptors();
		for(PropertyDescriptor p : prop){
			if(p.getName().equals(propertyName)){
				Method methodGetName = p.getReadMethod();
				retVal = methodGetName.invoke(s);
				break;
			}
		}
		return retVal;
	}