对象转map,map转对象,map转泛型对象 工具类 借用阿里TypeReference 泛型传递

这篇博客介绍了如何使用Java工具类实现对象到Map、Map到对象以及Map到泛型对象的转换,重点是利用阿里巴巴的TypeReference解决泛型类型传递的问题。

工具类代码:


package vip.rory.dht.common.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhanghangtian
 */
public class BeanUtil {

    @SuppressWarnings("unchecked")
    public static <T, K, V> T mapToBean(Map<K, V> map, TypeReference<T> typeReference)
            throws IllegalArgumentException, InvocationTargetException, ClassNotFoundException, Exception {
        Type type = typeReference.getRawType();
        return (T) mapToBean(map, Class.forName(type.getTypeName()));
    }

    public static <T, K, V> T mapToBean(Map<K, V> map, Class<T> clazz)
            throws Exception, IllegalArgumentException, InvocationTargetException {
        T t = null;
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            t = clazz.newInstance();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (map.containsKey(key)) {
                    Object value = map.get(key);
                    Method setter = property.getWriteMethod();// Java中提供了用来访问某个属性的getter/setter方法
                    setter.invoke(t, value);
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        return t;
    }

    public static Map<String, Object> beanToMap(Object bean) throws Exception, IllegalAccessException {
        if (bean == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (!key.equals("class")) {
                    Method getter = property.getReadMethod();// Java中提供了用来访问某个属性的 getter/setter方法
                    Object value;
                    value = getter.invoke(bean);
                    map.put(key, value);
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();

        }
        return map;
    }

}

 

 

TypeReference代码:


package vip.rory.dht.common.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Represents a generic type {@code T}. Java doesn't yet provide a way to
 * represent generic types, so this class does. Forces clients to create a
 * subclass of this class which enables retrieval the type information even at
 * runtime.
 * <p>
 * For example, to create a type literal for {@code List<String>}, you can
 * create an empty anonymous inner class:
 *
 * <pre>
 * TypeReference&lt;List&lt;String&gt;&gt; list = new TypeReference&lt;List&lt;String&gt;&gt;() {
 * };
 * </pre>
 * 
 * This syntax cannot be used to create type literals that have wildcard
 * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
 */
public class TypeReference<T> {
    static ConcurrentMap<Type, Type> classTypeCache = new ConcurrentHashMap<Type, Type>(16, 0.75f, 1);

    protected final Type             type;

    protected final Type             rawType;

    /**
     * Constructs a new type literal. Derives represented class from type
     * parameter.
     * <p>
     * Clients create an empty anonymous subclass. Doing so embeds the type
     * parameter in the anonymous class's type hierarchy so we can reconstitute
     * it at runtime despite erasure.
     */
    protected TypeReference() {
        Type superClass = getClass().getGenericSuperclass();

        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];

        Type cachedType = classTypeCache.get(type);
        if (cachedType == null) {
            classTypeCache.putIfAbsent(type, type);
            cachedType = classTypeCache.get(type);
        }
        this.rawType = ((ParameterizedType) type).getRawType();
        this.type = cachedType;
    }

    /**
     * Gets underlying {@code Type} instance.
     */
    public Type getType() {
        return type;
    }

    public Type getRawType() {
        return rawType;
    }

    public final static Type LIST_STRING = new TypeReference<List<String>>() {
    }.getType();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值