JavaBean其實就是一種遵循特定寫法的類,必須遵循必定的規範:java
一個JavaBean是由3部分組成,分別是屬性、方法、和事件。注意這裏的屬性是property,表示的是狀態,並非字段(Field)咱們在剛開始學面向對象的時候其實有的時候也是用到了這個規範,咱們寫的getter和setter方法,好比public void setName(String name){ this.name = name;}屬性其實就是name,在好比public int getAge(){return 19;},屬性其實就是age。通常的,咱們寫getter個setter方法用的是IDE本身生成的,屬性和字段同名。必定要區分屬性和字段,它們並非一個東西,也存在屬性名和字段名不一樣。數組
內省機制的做用就是用來查看和操做JavaBean的屬性。ide
經常使用的API測試
Introspector類中this
static BeanInfo getBeanInfo(Class<?> beanClass) 在 Java Bean 上進行內省,瞭解其全部屬性、公開的方法和事件。 static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass) 在給定的「斷」點之下,在 Java Bean 上進行內省,瞭解其全部屬性和公開的方法。
能夠看到在Introspector類中有兩個靜態方法能夠得到獲取JavaBean的信息,通常的第一個會獲得父類Object.class中的getClass方法,第二種會屏蔽掉Object類中的方法。返回一個BeanInfo,在BeanInfo接口中有一個方法能夠得到bean的描述器對象spa
MethodDescriptor[] getMethodDescriptors() 得到 beans MethodDescriptor。 PropertyDescriptor[] getPropertyDescriptors() 得到 beans PropertyDescriptor。
分別返回的是各自的描述器對象code
Method getReadMethod() 得到應該用於讀取屬性值的方法。 就是getter方法 Method getWriteMethod() 得到應該用於寫入屬性值的方法。 就是setter方法
public class User { private String name; private int age; private boolean man; public String getName() { return name; } ...省略剩餘getter setter方法 @Override public String toString() { return "User [name=" + name + ", age=" + age + ", man=" + man + "]"; } public static void main(String[] args) throws Exception { //得到JavaBean的描述信息 BeanInfo info = Introspector.getBeanInfo(User.class,Object.class); //獲取JavaBean的屬性描述器對象,返回的是一個描述器數組 PropertyDescriptor[] pds = info.getPropertyDescriptors(); //利用反射建立這個類的對象,固然這只是測試一下 User u = User.class.newInstance(); //對描述器對象進行迭代 for (PropertyDescriptor pd : pds) { //獲取屬性名稱 和屬性的類型 System.out.println(pd.getName()+","+pd.getPropertyType()()); //獲取getset方法 Method get = pd.getReadMethod(); Method set = pd.getWriteMethod(); System.out.println("getter方法:"+get); System.out.println("setter方法:"+set); //用反射給name屬性設置值 if("name".equals(pd.getName())){ Method setter = pd.getWriteMethod(); setter.invoke(u, "xx"); Method getter = pd.getReadMethod(); Object o = getter.invoke(u);//獲取名字 System.out.println(o); } } System.out.println(u); } }
咱們能夠發現javabean和map之間有不少類似之處.在map中是一對鍵值對key-value,而在JavaBean中是屬性名-屬性值。如今對這兩種進行相互轉換對象
**思路:**把bean轉化爲map,不過就是把bean中的屬性名給map的key,把屬性值給map中的value。在程序上表達,提供一個方法,傳入的是一個JavaBean對象,返回的是一個Map。接口
上代碼:事件
//把JavaBean轉化爲map public static Map<String,Object> bean2map(Object bean) throws Exception{ Map<String,Object> map = new HashMap<>(); //獲取JavaBean的描述器 BeanInfo b = Introspector.getBeanInfo(bean.getClass(),Object.class); //獲取屬性描述器 PropertyDescriptor[] pds = b.getPropertyDescriptors(); //對屬性迭代 for (PropertyDescriptor pd : pds) { //屬性名稱 String propertyName = pd.getName(); //屬性值,用getter方法獲取 Method m = pd.getReadMethod(); Object properValue = m.invoke(bean);//用對象執行getter方法得到屬性值 //把屬性名-屬性值 存到Map中 map.put(propertyName, properValue); } return map; }
**思路:**map轉化爲javabean,不就是把map的value設置給屬性爲屬性值,也就在找到bean中和Map中key相同的屬性名,把這個key對應的value設置給這個屬性。在程序上表達就是,提供一個方法,傳入map對象和一個bean的Class類型,返回一個JavaBean對象。注意,這裏傳入的參數多了一個,由於確定得用反射建立bean對象把,若是隻傳入一個map對象,怎麼建立對象?怎麼知道吧map轉化爲何類型的JavaBean。好了,直接擼代碼:
//把Map轉化爲JavaBean public static <T> T map2bean(Map<String,Object> map,Class<T> clz) throws Exception{ //建立一個須要轉換爲的類型的對象 T obj = clz.newInstance(); //從Map中獲取和屬性名稱同樣的值,把值設置給對象(setter方法) //獲得屬性的描述器 BeanInfo b = Introspector.getBeanInfo(clz,Object.class); PropertyDescriptor[] pds = b.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { //獲得屬性的setter方法 Method setter = pd.getWriteMethod(); //獲得key名字和屬性名字相同的value設置給屬性 setter.invoke(obj, map.get(pd.getName())); } return obj; }