JavaBean和Map的相互轉換


JavaBean和Map的相互轉換

一、JavaBean

1.什么是JavaBean?

JavaBean其實就是一種遵循特定寫法的類,必須遵循一定的規范:

  • 類必須由public修飾,並且保證有公共的無參數的構造器
  • 包含操作屬性的的public方法,getter setter方法
  • 字段是私有的

一個JavaBean是由3部分組成,分別是屬性、方法、和事件。注意這里的屬性是property,表示的是狀態,並不是字段(Field)我們在剛開始學面向對象的時候其實有的時候也是用到了這個規范,我們寫的getter和setter方法,比如public void setName(String name){ this.name = name;}屬性其實就是name,在比如public int getAge(){return 19;},屬性其實就是age。一般的,我們寫getter個setter方法用的是IDE自己生成的,屬性和字段同名。一定要區分屬性和字段,它們並不是一個東西,也存在屬性名和字段名不同。

2.內省機制

內省機制的作用就是用來查看和操作JavaBean的屬性。

  • 獲取JavaBean的屬性名
  • 通過getter方法給屬性獲取值,通過setter給屬性設置值

常用的API

Introspector類中

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的描述器對象

 MethodDescriptor[] getMethodDescriptors() 獲得 beans MethodDescriptor。 
 PropertyDescriptor[] getPropertyDescriptors()  獲得 beans PropertyDescriptor。 

分別返回的是各自的描述器對象

 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的相互轉化

我們可以發現javabean和map之間有很多相似之處.在map中是一對鍵值對key-value,而在JavaBean中是屬性名-屬性值。現在對這兩種進行相互轉換

1.JavaBean轉化為Map

思路:把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;
}

2.把Map轉化為JavaBean

思路: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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM