Java-類轉換工具類

1.這是一個類直接轉換的工具類,可適用於

  • 對象轉換
  • 對象列表轉換
  • 屬性拷貝, 當且僅當兩個對象的非靜態屬性名稱相同且對應的屬性類型也相同時才進行屬性值拷貝
  • 將對象轉換爲散列表Object---Map
  • 將list<object>轉換爲 List<Map<String, Object>>
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

/**
 * @Auther: cjw
 * @Date: 2016/7/18 17:22
 * @Description: bean 工具類
 */
public class BeanUtil {
	
	private static WriteLock lock = new ReentrantReadWriteLock().writeLock();
	
	private static final Map<Class<?>, Map<String, Field>> METADATA = new HashMap<>();
	
	/**
	 * 對象轉換
	 * 
	 * @param source
	 *            源對象
	 * @param targetClass
	 *            目標類
	 * @return 返回一個新的目標類對象, 該目標類對象的屬性值從源對象中拷貝而來
	 */
	public static <T> T convert(Object source, Class<T> targetClass) {
		T target = newInstance(targetClass);
		copyProperties(source, target);
		return target;
	}
	
	/**
	 * 對象列表轉換
	 * 
	 * @param sources
	 *            源對象列表
	 * @param targetClass
	 *            目標類
	 * @return 返回一個新的目標對象列表, 每個目標類對象的屬性值從源對象中拷貝而來
	 */
	public static <T> List<T> convert(Collection<?> sources, Class<T> targetClass) {
		List<T> targets = new ArrayList<T>();
		if (sources != null && sources.size() > 0) {
			for (Object source : sources) {
				targets.add(convert(source, targetClass));
			}
		}
		return targets;
	}
	
	/**
	 * 屬性拷貝, 當且僅當兩個對象的非靜態屬性名稱相同且對應的屬性類型也相同時才進行屬性值拷貝
	 * 
	 * @param source
	 *            源對象
	 * @param target
	 *            目標對象
	 */
	public static void copyProperties(Object source, Object target) {
		copyProperties(source, target, true);
	}
	
	/**
	 * 屬性拷貝, 當且僅當兩個對象的非靜態屬性名稱相同且對應的屬性類型也相同時才進行屬性值拷貝
	 * 
	 * @param source
	 *            源對象
	 * @param target
	 *            目標對象
	 * @param copyNullProperty
	 *            是否拷貝null屬性值
	 */
	public static void copyProperties(Object source, Object target, boolean copyNullProperty) {
		if (source == null) {
			return ;
		}
		Class<?> sourceClass = source.getClass();
		Class<?> targetClass = target.getClass();
		Map<String, Field> targetFields = getFieldsMap(targetClass, FieldType.NOT_STATIC);
		Map<String, Field> sourceFields = getFieldsMap(sourceClass, FieldType.NOT_STATIC);
		for (String name : targetFields.keySet()) {
			if (sourceFields.containsKey(name)) {
				Field sourceField = sourceFields.get(name);
				Field targetField = targetFields.get(name);
				if (targetField.getType() == sourceField.getType()) {
					Object value = getPropertyValue(source, sourceField);
					if (value == null && !copyNullProperty) {
						continue ;
					}
					setPropertyValue(target, targetField, value);
				}
			}
		}
	}

	/**
	 * 創建類的一個實例
	 * 
	 * @param beanClass
	 *            類
	 */
	public static <T> T newInstance(Class<T> beanClass) {
		try {
			return beanClass.newInstance();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 設置對象屬性的值
	 * 
	 * @param bean
	 *            目標對象
	 * @param field
	 *            屬性名稱
	 * @param propertyValue
	 *            屬性的值
	 */
	public static void setPropertyValue(Object bean, Field field, Object propertyValue) {
		try {
			field.set(bean, propertyValue);
		} catch (Throwable e) {
			throw new RuntimeException(bean.getClass().getName() + " " + field.getName() + " " + propertyValue, e);
		}
	}

	/**
	 * 獲取目標屬性的值
	 * 
	 * @param bean
	 *            目標對象
	 * @param field
	 *            屬性名稱
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getPropertyValue(Object bean, Field field) {
		try {
			return (T) field.get(bean);
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 設置屬性的值
	 * 
	 * @param bean
	 *            對象或類
	 * @param property
	 *            類屬性或對象屬性名稱
	 * @param propertyValue
	 *            屬性的值
	 */
	public static void setPropertyValue(Object bean, String property, Object propertyValue) {
		if (bean != null) {
			Class<?> beanClass = null;
			if (bean instanceof Class) {
				beanClass = (Class<?>) bean;
			} else {
				beanClass = bean.getClass();
			}
			Field field = getFieldsMap(beanClass, FieldType.ALL).get(property);
			if (field != null) {
				setPropertyValue(bean, field, propertyValue);
			}
		}
	}
	
	/**
	 * 獲取屬性的值
	 * 
	 * @param bean
	 *            對象或類
	 * @param property
	 *            類屬性名稱或對象屬性名稱
	 * @return
	 */
	public static <T> T getPropertyValue(Object bean, String property) {
		if (bean != null) {
			Class<?> beanClass = null;
			if (bean instanceof Class) {
				beanClass = (Class<?>) bean;
			} else {
				beanClass = bean.getClass();
			}
			Field field = getFieldsMap(beanClass, FieldType.ALL).get(property);
			if (field != null) {
				return getPropertyValue(bean, field);
			}
		}
		return null;
	}
	
	/**
	 * 獲取屬性的類型
	 * 
	 * @param bean
	 *            對象或類
	 * @param property
	 *            類屬性名稱或對象屬性名稱
	 * @return
	 */
	public static Class<?> getPropertyType(Object bean, String property) {
		if (bean != null) {
			Class<?> beanClass = null;
			if (bean instanceof Class) {
				beanClass = (Class<?>) bean;
			} else {
				beanClass = bean.getClass();
			}
			Field field = getFieldsMap(beanClass, FieldType.ALL).get(property);
			if (field != null) {
				return field.getType();
			}
		}
		return null;
	}
	
	/**
	 * 將對象轉換爲散列表
	 * 
	 * @param source
	 *            源對象
	 * @return
	 */
	public static Map<String, Object> convertMap(Object source) {
		return convertMap(source, true);
	}
	
	/**
	 * 將對象轉換爲散列表
	 * 
	 * @param source
	 *            源對象
	 * @param convertNullProperty
	 *            空屬性是否轉換
	 * @return
	 */
	public static Map<String, Object> convertMap(Object source, boolean convertNullProperty) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (source != null) {
			Map<String, Field> sourceFields = getFieldsMap(source.getClass(), FieldType.NOT_STATIC);
			for (String name : sourceFields.keySet()) {
				Object value = getPropertyValue(source, sourceFields.get(name));
				if (value == null && !convertNullProperty) {
					continue ;
				} else {
					map.put(name, value);
				}
			}
		}
		return map;
	}

	/**
	 *  將list<object>轉換爲 List<Map<String, Object>>
	 * @param sources
	 * @param convertNullProperty
	 * @return
	 */
	public static List<Map<String, Object>> convertListMap(List<?> sources, boolean convertNullProperty) {
		List<Map<String, Object>> maps = new ArrayList<>();
		for (Object object : sources){
			maps.add(convertMap(object,convertNullProperty));
		}
		return maps;
	}


	/**
	 * 獲取聲明的屬性表
	 * 
	 * @param beanClass
	 *            目標類
	 * @param fieldType
	 *            屬性類型
	 * @return
	 */
	private static Map<String, Field> getFieldsMap(Class<?> beanClass, FieldType fieldType) {
		Map<String, Field> map = getReferableFieldsMap(beanClass);
		Map<String, Field> target = new HashMap<>();
		if (map != null && !map.isEmpty()) {
			for (String name : map.keySet()) {
				Field field = map.get(name);
				switch (fieldType) {
				case ALL:
					target.put(name, field);
					break;
				case STATIC:
					if ((field.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
						target.put(name, field);
					}
					break;
				case NOT_STATIC:
					if ((field.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
						target.put(name, field);
					}
					break;
				}
			}
		}
		return target;
	}
	
	/**
	 * 獲取當前類聲明的屬性表
	 * 
	 * @param beanClass
	 *            目標類
	 * @return
	 */
	private static Map<String, Field> getDeclaredFieldsMap(Class<?> beanClass) {
		Field[] fields = beanClass.getDeclaredFields();
		Map<String, Field> map = new HashMap<String, Field>();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				field.setAccessible(true);
				map.put(field.getName(), field);
			}
		}
		return map;
	}
	
	/**
	 * 獲取聲明的所有屬性表
	 * 
	 * @param beanClass
	 *            目標類
	 * @return
	 */
	private static Map<String, Field> getReferableFieldsMap(Class<?> beanClass) {
		if (!METADATA.containsKey(beanClass)) {
			try {
				lock.lock();
				if (!METADATA.containsKey(beanClass)) {
					Map<String, Field> map = new HashMap<>();
					while (beanClass != null) {
						map.putAll(getDeclaredFieldsMap(beanClass));
						beanClass = beanClass.getSuperclass();
					}
					METADATA.put(beanClass, map);
				}
			} finally {
				lock.unlock();
			}
		}
		return METADATA.get(beanClass);
	}
	
	enum FieldType { STATIC, NOT_STATIC, ALL }
	
	/**
	 * 調用成員方法(或類方法), 該方法要求被調方法參數必須不能有基本數據類型
	 * 
	 * @param object
	 *            具體的對象(或類)
	 * @param methodName
	 *            對象的成員方法名稱(或類的類方法名稱)
	 * @param argValues
	 *            方法的參數值列表
	 * @return
	 */
	public static <E> E invokeMethod(Object object, String methodName, Object... argValues) {
		Class<?>[] classes = null;
		if (argValues != null && argValues.length > 0) {
			int length = argValues.length;
			classes = new Class<?>[length];
			for (int i = 0; i < length; i++) {
				classes[i] = argValues[i].getClass();
			}
		}
		return invokeMethod(object, methodName, argValues, classes);
	}
	
	/**
	 * 調用對象的成員方法(或類的類方法)
	 * 
	 * @param object
	 *            具體的對象(或類)
	 * @param methodName
	 *            對象的成員方法名稱(或類的類方法名稱)
	 * @param argValues
	 *            方法的參數值列表
	 * @param argTypes
	 *            方法的參數類型列表
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <E> E invokeMethod(Object object, String methodName, Object[] argValues, Class<?>[] argTypes) {
		try {
			return (E) getAccessibleMethod(object, methodName, argTypes).invoke(object, argValues);
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 獲取可訪問的方法對象
	 * 
	 * @param object
	 *            具體的對象(或類)
	 * @param methodName
	 *            對象的成員方法名稱(或類的類方法名稱)
	 * @param types
	 *            方法的參數類型列表
	 * @return
	 */
	private static Method getAccessibleMethod(Object object, String methodName, Class<?>... types) {
		Class<?> entityClass = object instanceof Class ? (Class<?>) object : object.getClass();
		while (entityClass != null) {
			try {
				Method target = entityClass.getDeclaredMethod(methodName, types);
				target.setAccessible(true);
				return target;
			} catch (Throwable e) {}
			entityClass = entityClass.getSuperclass();
		}
		return null;
	}
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章