美文网首页
java泛型类型擦除,json转对象的问题

java泛型类型擦除,json转对象的问题

作者: zhengaoly | 来源:发表于2022-05-22 14:51 被阅读0次

    TypeReference

    字面意思是指Type的Reference,也就是某类型的一个指向或者引用,主要解决泛型中,泛型参数被擦出的问题。通过TypeReference可以获取到泛型参数的类型。

    protected TypeReference() {
            // 获取当前class的父类的Type
            Type superClass = this.getClass().getGenericSuperclass();
            // 父类class的泛型类型数组,表示的是该类型的实际类型参数
            Type type = ((ParameterizedType)superClass).getActualTypeArguments()[0];
            Type cachedType = (Type)classTypeCache.get(type);
            if (cachedType == null) {
                classTypeCache.putIfAbsent(type, type);
                cachedType = (Type)classTypeCache.get(type);
            }
     
            this.type = cachedType;
        }
    

    相关方法

        Type[] getActualTypeArguments
        核心接口,返回泛型类型数组, 该接口可获取父类实际泛型类型,返回的Type数组对象表示该类型的实际类型参数。 
    
        Type getRawType()
        返回原始类型Type
    
        Type getOwnerType()
        返回 Type 对象,表示此类型是其成员之一的类型。
    

    代码示例

    package com.baomidou.mybatisplus.samples.typehandler;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.Getter;
    import lombok.Setter;
    
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    @Getter
    @Setter
    class UserBase {
    
        private String userName;
        private int age;
        private long addTime;
    }
    public class test2222 {
    
        private static final String TRUE = "true";
     
        public static void main(String[] args) throws JsonProcessingException {
            String json1 = "{\"userName\":\"小李飞刀\",\"age\":18,\"addTime\":1591851786568}";
            /**
             * 1、将jsonString转为map的四种方式
             *     Map.class
             *     实体类.class
             *     new TypeReference<实体类>(){}
             *     new TypeReference<Map<String,Object>>(){}
             **/
            //不建议这种方式,没有明确知名Map具体类型。maven package打包时会有警告。
            //Map.class没有彻底清楚说明类型,默认成Map<Object, Object>
            ObjectMapper objectMapper=new ObjectMapper();
            Map map = objectMapper.readValue(json1, Map.class);
            System.out.println(map.get("userName"));
            UserBase userBase = objectMapper.readValue(json1, UserBase.class);
            System.out.println(userBase.getAddTime());
            UserBase userBase1 = objectMapper.readValue(json1, new TypeReference<UserBase>(){});
            System.out.println(userBase1.getAge());
            Map userBaseMap = objectMapper.readValue(json1, new TypeReference<Map<String,Object>>(){});
            System.out.println(userBaseMap.get("userName"));
            /**
             * 2、将jsonString转为List<Map>的四种方式
             *     new TypeReference<List<Map<String, Object>>>(){}
             *     new TypeReference<List<实体类>(){}
             *     new TypeReference<实体类[]>(){}
             *     List.class
             **/
            String json2 = "[{\"userName\":\"小李飞刀\",\"age\":18,\"addTime\":123}, {\"userName\":\"小李飞刀2\",\"age\":182,\"addTime\":1234}]";
            List listMap = objectMapper.readValue(json2, new TypeReference<List<Map<String, Object>>>(){});
            for(Object map1 : listMap){
                Map map2 = (Map)map1;
                System.out.println(map2.get("userName"));
            }
            List listBean = objectMapper.readValue(json2, new TypeReference<List<UserBase>>(){});
            for(Object userBase2 : listBean){
                UserBase userBase3 = (UserBase)userBase2;
                System.out.println(userBase3.getAge());
            }
            UserBase[] userBaseAry = objectMapper.readValue(json2, new TypeReference<UserBase[]>(){});
            System.out.println("ary: " + userBaseAry[0].getUserName());
     
            List list2 = objectMapper.readValue(json2, List.class);
            System.out.println(list2.get(0));
    
            class IntMap extends HashMap<String,Integer> {
    
            }
            IntMap intMap = new IntMap();
            System.out.println("superClass:"+intMap.getClass().getSuperclass());
    
            Type type = intMap.getClass().getGenericSuperclass();
            if(type instanceof ParameterizedType){
                ParameterizedType p = (ParameterizedType) type;
                for (Type t : p.getActualTypeArguments()){
                    System.out.println(t);
                }
            }
    
            System.out.println("=====newclass=====");
            Map<String,Integer> newIntMap = new HashMap<>();
            System.out.println(newIntMap.getClass().getSuperclass());
    
            Type newClassType = newIntMap.getClass().getGenericSuperclass();
            if(newClassType instanceof ParameterizedType){
                ParameterizedType p = (ParameterizedType) newClassType;
                for (Type t : p.getActualTypeArguments()){
                    System.out.println(t);
                }
            }
    
            System.out.println("=====subclass=====");
            HashMap<String,Integer> subIntMap = new HashMap<String,Integer>(){};
            System.out.println(subIntMap.getClass().getSuperclass());
    
            Type subClassType = subIntMap.getClass().getGenericSuperclass();
            if(subClassType instanceof ParameterizedType){
                ParameterizedType p = (ParameterizedType) subClassType;
                for (Type t : p.getActualTypeArguments()){
                    System.out.println(t);
                }
            }
            System.out.println("me-----------");
    
            Map<String,Integer> me = new HashMap<>();
            System.out.println(me.getClass());
            Type meClassType = me.getClass().getGenericSuperclass();
            if (meClassType instanceof ParameterizedType) {
                ParameterizedType classType = (ParameterizedType) meClassType;
                for (Type actualTypeArgument : classType.getActualTypeArguments()) {
                    System.out.println(actualTypeArgument);
                }
            }
    
        }
    }
    

    对应输出

    小李飞刀
    1591851786568
    18
    小李飞刀
    小李飞刀
    小李飞刀2
    18
    182
    ary: 小李飞刀
    {userName=小李飞刀, age=18, addTime=123}
    superClass:class java.util.HashMap
    class java.lang.String
    class java.lang.Integer
    =====newclass=====
    class java.util.AbstractMap
    K
    V
    =====subclass=====
    class java.util.HashMap
    class java.lang.String
    class java.lang.Integer
    me-----------
    class java.util.HashMap
    K
    V
    

    MybatisPlus 自定义 TypeHandler 映射JSON类型为List
    https://blog.csdn.net/li18215100977/article/details/121267367

    相关文章

      网友评论

          本文标题:java泛型类型擦除,json转对象的问题

          本文链接:https://www.haomeiwen.com/subject/rapkprtx.html