接口設計時爲了避免序列化的麻煩,將接口定義爲參數爲map<String,String>類型的接口,但是現在調用時需要轉換當前的實體Bean爲Map,接口接收方再把Map轉換爲另一個Bean實體。過程中的需要對類型判斷轉換。
先貼出兩段方法:
// Bean --> Map 1: 利用Introspector和PropertyDescriptor 將Bean --> Map
public static Map<String, String> transBean2Map(Object obj) {
if(obj == null){
return null;
}
Map<String, String> map = new HashMap();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// 過濾class屬性
if (!key.equals("class")) {
// 得到property對應的getter方法
Method getter = property.getReadMethod();
Object value = getter.invoke(obj);
if ((value instanceof String)||(value instanceof Integer)||(value instanceof Long)
||(value instanceof Short)||(value instanceof Double)||(value instanceof Float)
||(value instanceof Character)||(value instanceof Byte)||(value instanceof Boolean)){
// value = sdf.format(value);
map.put(key, value.toString());
}else if (value instanceof Date){
map.put(key, sdf.format(value));
}
// map.put(key, value.toString());
}
}
} catch (Exception e) {
System.out.println("transBean2Map Error " + e);
}
return map;
}
// Map --> Bean 1: 利用Introspector,PropertyDescriptor實現 Map --> Bean
public static void transMap2Bean(Map<String, String> map, Object obj) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (map.containsKey(key)) {
Object value = map.get(key);
// 得到property對應的setter方法
Method setter = property.getWriteMethod();
if (Date.class.equals(property.getPropertyType())){
setter.invoke(obj, sdf.parse(value.toString()));
}else if (Integer.class.equals(property.getPropertyType())||
Integer.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Integer.parseInt(value.toString()));
}else if (Long.class.equals(property.getPropertyType())||
Long.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Long.parseLong(value.toString()));
}else if (Byte.class.equals(property.getPropertyType())||
Byte.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Byte.valueOf(value.toString()));
}else if (Character.class.equals(property.getPropertyType())||
Character.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, value.toString().charAt(0));
}else if (Short.class.equals(property.getPropertyType())||
Short.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Short.parseShort(value.toString()));
}else if (Boolean.class.equals(property.getPropertyType())||
Boolean.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Boolean.parseBoolean(value.toString()));
}else if (Float.class.equals(property.getPropertyType())||
Float.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Float.parseFloat(value.toString()));
}else if (Double.class.equals(property.getPropertyType())||
Double.TYPE.equals(property.getPropertyType())){
setter.invoke(obj, Double.parseDouble(value.toString()));
}else if (String.class.equals(property.getPropertyType())){
setter.invoke(obj, value);
}
}
}
} catch (Exception e) {
System.out.println("transMap2Bean Error " + e);
}
return;
}
這裏使用了Introspector和PropertyDescriptor的類獲取Bean的get和set方法,再通過get和set方法實現對bean的賦值。但是有一個問題就是因爲Map中的類型都是String類型,在對Bean取值和賦值時必須要進行類型的轉換,否則就會報錯。
在類型判斷時用到了兩種方法,instanceof和equals,下面詳細記錄一下這種方法的使用:
java 中的instanceof 運算符是用來在運行時指出對象是否是特定類的一個實例。instanceof通過返回一個布爾值來指出,這個對象是否是這個特定類或者是它的子類的一個實例。但是有一個問題是,一個實例instanceof任何他的父類都可以返回true,我們在transBean2Map裏,因爲是從Bean中取到的值都是向上轉爲Object類型了,所以只是instanceof最終的子類就可以。
在transMap2Bean方法中,因爲是把Map中的值放到Bean中,要判斷Bean中的屬性的類型,並沒有實例,只能使用類的equals方法,判斷類型是否相同。我使用了Date.class.equals(property.getPropertyType())這種方式。但是還是要注意的地方是,基本數據類型和基本數據類型的對象類型是需要分別判斷的。例如:屬性爲int的property和屬性爲Integer的property的property.getPropertyType()值是不同的。
總結比較:
instanceof是判斷實例是否是指定類的子類或相同類的實例,必須是一個類的實例,Class或者基本數據類型都是不行的。
使用equals時,是判斷類是否是相同的,不關乎具體實例。而且基本數據類型和他們的對象類型也是嚴格區分的。Integer.class.equals(property.getPropertyType())和Integer.TYPE.equals(property.getPropertyType())