反射:(運用於框架)數組
獲取字節碼文件的三種方法:
//獲取字節碼文件的三種方法
//方法一
//Class clazz=Class.forName("text.reflect.Person");
//方法二
//Class clazz=Person.class;
//方法三
Person p=new Person();
Class clazz=p.getClass();框架
//得到構造函數,調用構造函數
Constructor cs=clazz.getConstructor(null);
cs.newInstance(null);函數
//暴力訪問
Constructor cs=clazz.getDeclaredConstructor(String.class,int.class);
cs.setAccessible(true);
cs.newInstance("周貝特",20);對象
Constructor cs=clazz.getDeclaredConstructor(null);
//獲取類的對象
Person p=(Person)cs.newInstance(null);
//用對象訪問屬性和方法
System.out.println(p.name);ip
//獲取全部的構造函數
Class clazz=Class.forName("text.reflect.Person");
Constructor []ct=clazz.getDeclaredConstructors();
System.out.println(ct.length);字符串
//用反射獲取方法
//獲取字節碼文件
Class clazz=類名.class;
//獲取方法對象,靜態方法,對象爲null
Method m=clazz.getMethod(對象,參數類型.class)
//暴力訪問同構造函數的暴力訪問。get
例外:
Method m=clazz.getMethod(null,String[].class);
m.invoke(null,new String[] {"a","b"});//jdk1.5會將整個數組看成一個參數,而jdk1.4會將數組的每一個元素看成一個參數,jdk5兼容
1.4,因此這裏會報錯,
解決方法:
類中的main方法須要的是一個參數,而按照jdk1.4的原則,上面invoke傳入的是兩個參數:
m.invoke(null,new Object(){new String []{"a","b"}});
m.invoke(null,(Object)new String []{"a","b"});it
獲取字段:class
Class clazz=Class.forName("text.reflect.Person");
Person p=(Person)clazz.newInstance();
//獲取字段對象
Field f=clazz.getField("name");
String str=(String)f.get(p);
System.out.println(str);容器
設置字段
f.set(p,18 );
System.out.println(p.age);
暴力訪問和訪問方法和構造方法相同
關於反射和內省:
內省:操做屬性:set和get方法
獲取類中屬性方法一(先將類中的屬性封裝到beaninfo容器中,再用PropertyDescriptor獲取屬性描述器):
BeanInfo bi=Introspector.getBeanInfo(Student.class);
//獲取類中的全部屬性表述器
PropertyDescriptor []pds=bi.getPropertyDescriptors();
System.out.println(pds.length);
for (PropertyDescriptor pro : pds) {
System.out.println(pro.getName());
}
方法二:
建立PropertyDescriptor的對象。
Student s=new Student();
//建立PropertyDescriptor,獲取student中的name對象。
PropertyDescriptor pd=new PropertyDescriptor("name", Student.class);
//獲取Read對象,至關於獲取name的get方法
Method md=pd.getReadMethod();
//至關於調用name的get方法
String str=(String)md.invoke(s, null);
System.out.println(str);
//至關於name的set方法
Method md2=pd.getWriteMethod();
//調用set方法
md2.invoke(s, "周貝特");
System.out.println(s.getName());
用beanutils框架操做類屬性:
獲取屬性,至關於get方法
Student s=new Student();
String str=BeanUtils.getProperty(s, "name");
System.out.println(str);
設置屬性:至關於set方法:
Student s=new Student();
BeanUtils.setProperty(s, "name", "周貝特");
System.out.println(s.getName());
beanutils可自動進行類型的轉換,但僅限於基本
類型。
經過BeanUtils.getProperty(s, "name");返回的是字符串,就是自動轉型的體現
當須要操做非基本類型的屬性時,可以使用藉口轉換器的類來實現:
Student s=new Student();
//加入轉換器
ConvertUtils.register(new DateLocaleConverter(),Date.class);
BeanUtils.setProperty(s, "birthday", "1991-06-11");
System.out.println(s.getBirthday());
用beanutils封裝map集合到類中:
Map map=new HashMap();map.put("name", "戴佳偉");map.put("age", 18);map.put("birthday", "1991-06-11");Person p=new Person();System.out.println("封裝前的數據"+p);//加入轉換器ConvertUtils.register(new DateLocaleConverter(), Date.class);//封裝map集合中的數據到Person對象中BeanUtils.populate(p, map);System.out.println("封裝後的數據"+p);