1、内省
JavaBean
pojo: plain old java object.
标准javabean.
class Person{
private String name ;
public Person(){
}
//getter
public String getName(){
return name ;
}
//setter
public void setName(String name){
this.name = name ;
}
}
广义上的javabean
Property
---------------
属性 //通过标准javabean的get/set方法得到的属性
Field
----------------
字段。
成员变量。
Introspector:
内省.
Introspector.getBeanInfo(Class clazz); //得到类的Bean信息
BeanInfo //类的Bean信息。
BeanInfo.getPropertyDescriptor() //属性描述符
BeanInfo.getMethodDescriptor() //方法描述符。
PropertyDescritor.getReadMethod() //获得getXxx方法()
PropertyDescritor.getWriteMethod() //获得setXxx方法()
1 /** 2 * 测试内省(可以得到从父类继承的get、set方法) 3 * 4 * @author feigu 5 * 6 */ 7 public class TestIntrospector { 8 public static void main(String[] args) { 9 try { 10 BeanInfo info = Introspector.getBeanInfo(Person.class); 11 // 得到属性描述符 12 PropertyDescriptor[] pds = info.getPropertyDescriptors(); 13 for (PropertyDescriptor pd : pds) { 14 System.out.println(pd.getName()); 15 System.out.println("-------------"); 16 // 得到get方法 17 System.out.println(pd.getReadMethod()); 18 System.out.println("_______________"); 19 // 得到set方法 20 System.out.println(pd.getWriteMethod()); 21 } 22 } catch (IntrospectionException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 } 27 }
属性的复制
1 public class IntrospectorDemo { 2 3 public static void main(String[] args) { 4 Student s1=new Student("小明", 23, "No111"); 5 Student s2=new Student(); 6 Class calzz=Student.class; 7 Field[] fields = calzz.getDeclaredFields(); 8 //通过class得到对应beaninfo对象 9 try { 10 BeanInfo beanInfo = Introspector.getBeanInfo(Student.class); 11 PropertyDescriptor[] ppds = beanInfo.getPropertyDescriptors(); 12 for (PropertyDescriptor ppd : ppds) { 13 System.out.println(ppd.getReadMethod()); 14 Object object = ppd.getReadMethod().invoke(s1); 15 System.out.println(object); 16 //去除setClass方法的影响 17 if(ppd.getWriteMethod()==null){ 18 continue; 19 } 20 ppd.getWriteMethod().invoke(s2, object); 21 } 22 System.out.println(s2.getStuNo()+ ":"+s2.getName()+":"+s2.getAge()); 23 } catch (Exception e) { 24 e.printStackTrace(); 25 } 26 } 27 }
2、反射案例(通过反射实现对象属性的复制)
反射
动态访问对象或类的属性和方法。
Class
类描述符.
Class clazz = Person.class ;
clazz = Class.forName("x.x.x.x.xxx");
//new Person();
clazz.newInstance();
Method
方法描述符。
//定义方法
clazz.getDeclaredMethod(String , Class...);
//可见方法。
clazz.getMethod(String name,Class...);
Method.setAccessible(true); //内存中
Field
字段描述符
Class.getDeclaredField(String name) ;
Field.setAccessible(true);
int mod = Field.getModifier();
Modifier.isStatic(mod) ;
Constructor
构造器描述符。
Class.getDeclaredConstructor(Class...)
Constructor.newInstance(...);
a instanceof Person
模糊判断。
Person.class == a.getClass()
精确判断。
/** * 通过反射实现对象属性的复制 * @author feigu * */ public class PersonDemo { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Person p1 = new Person("xiaoming", 12); //Person p2 = new Person(); Dog dog = new Dog(); // propCopy(p1, p2); //promCopy(p1, p2); promCopy(p1, dog); System.out.println(dog); } // 通过字段进行属性复制 public static void propCopy(Person a, Person b) throws Exception { Field[] clazz = a.getClass().getDeclaredFields(); for (Field f : clazz) { // String f=field.getName(); f.setAccessible(true); Object ob = f.get(a); f.set(b, ob); // System.out.println(f); } } // 通过方法进行属性复制 public static void promCopy(Person a, Dog b) throws Exception { Method[] methods_a = a.getClass().getDeclaredMethods(); Class clazz= b.getClass(); for (Method mm_a : methods_a) { // 方法名 String m_a = mm_a.getName(); // c参数类型 Class[] parameterTypes = mm_a.getParameterTypes(); // 返回值类型 Class returnType = mm_a.getReturnType(); if (m_a.startsWith("get") && (parameterTypes == null || parameterTypes.length == 0) && returnType != void.class) { //得到对应参数类型和返回值的b对象方法 String m_b= m_a.replace("get", "set"); try { mm_a.setAccessible(true); Method mm_b = clazz.getDeclaredMethod(m_b, returnType); Object obj = mm_a.invoke(a); mm_b.setAccessible(true); mm_b.invoke(b, obj); } catch (Exception e) { continue; } } } } }
3、属性测试
1 public class TestReflectApp { 2 3 public static void main(String[] args) throws Exception { 4 // 5 InputStream is = new FileInputStream("D:\eclipse-workspace-bigdata4\Java25\src\objects.properties"); 6 // byte[] bytes = new byte[is.available()]; 7 // is.read(bytes); 8 // //is.close(); 9 //System.out.println(new String(bytes)); 10 Properties prop = new Properties(); 11 prop.load(is); 12 13 // 14 String objClass = prop.getProperty("object.class"); 15 Class clazz = Class.forName(objClass); 16 Object obj = clazz.newInstance(); 17 18 //name 19 String propName = prop.getProperty("object.prop1.name"); 20 String propValue = prop.getProperty("object.prop1.value"); 21 Field f = clazz.getDeclaredField(propName); 22 if(f.getType() == String.class){ 23 f.setAccessible(true); 24 f.set(obj, propValue); 25 } 26 27 28 //name 29 propName = prop.getProperty("object.prop2.name"); 30 propValue = prop.getProperty("object.prop2.value"); 31 f = clazz.getDeclaredField(propName); 32 if(f.getType() == int.class){ 33 f.setAccessible(true); 34 Integer i = Integer.parseInt(propValue) ; 35 f.set(obj, i); 36 } 37 38 }