先定义一个学生类:
类中具备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; }