zoukankan      html  css  js  c++  java
  • java为什么使用TypeReference

    用途

    在使用fastJson时,对于泛型的反序列化很多场景下都会使用到TypeReference,例如:

    void testTypeReference() {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(9);
            list.add(4);
            list.add(8);
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("a", list);
            System.out.println(jsonObj);
    
            List<String> list2 = jsonObj.getObject("a", new TypeReference<List<Integer>>(){});
    
            System.out.println(list2);
        }

    输出

    {"a":[1,9,4,8]}
    [1, 9, 4, 8]
    

    使用TypeReference可以明确的指定反序列化的类型,具体实现逻辑参考TypeReference的构造函数 

      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.type = cachedType;
        }

    解说

    其中核心的方法是:getActualTypeArguments,它可以得到父类的反省类型

    ParameterizedType是一个记录类型泛型的接口, 继承自Type,一共三方法:

    • Type[] getActualTypeArguments(); //返回泛型类型数组
    • Type getRawType(); //返回原始类型Type
    • Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。

    例如 Map<String,String> 对应的ParameterizedType三个方法分别取值如下:

    • [class java.lang.String, class java.lang.String]
    • interface java.util.Map
    • null

    例证

    package JsonLearn;
    
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.HashMap;
    import java.util.Map;
    
    public class TypeReferencBaseLearn {
        public static class IntMap extends HashMap<String, Integer> {}
    
        void test1() {
            IntMap intMap = new IntMap();
            System.out.println("getSuperclass:" + intMap.getClass().getSuperclass());
            System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
            Type type = intMap.getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                ParameterizedType p = (ParameterizedType)type;
                for (Type t : p.getActualTypeArguments()) {
                    System.out.println(t);
                }
            }
        }
    
        void test2() {
            Map<String, Integer> intMap = new HashMap<>();
            System.out.println("
    getSuperclass:" + intMap.getClass().getSuperclass());
            System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
            Type type = intMap.getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                ParameterizedType p = (ParameterizedType)type;
                for (Type t : p.getActualTypeArguments()) {
                    System.out.println(t);
                }
            }
        }
    
        void test3() {
            Map<String, Integer> intMap = new HashMap<String, Integer>(){};
            System.out.println("
    getSuperclass:" + intMap.getClass().getSuperclass());
            System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass());
            Type type = intMap.getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                ParameterizedType p = (ParameterizedType)type;
                for (Type t : p.getActualTypeArguments()) {
                    System.out.println(t);
                }
            }
        }
    
        public static void main(String[] args) {
            TypeReferencBaseLearn obj = new TypeReferencBaseLearn();
            obj.test1();
            obj.test2();
            obj.test3();
        }
    }

    输出

    getSuperclass:class java.util.HashMap
    getGenericSuperclass:java.util.HashMap<java.lang.String, java.lang.Integer>
    class java.lang.String
    class java.lang.Integer
    
    getSuperclass:class java.util.AbstractMap
    getGenericSuperclass:java.util.AbstractMap<K, V>
    K
    V
    
    getSuperclass:class java.util.HashMap
    getGenericSuperclass:java.util.HashMap<java.lang.String, java.lang.Integer>
    class java.lang.String
    class java.lang.Integer 

    注意区分test3()中的:

    Map<String, Integer> intMap = new HashMap<String, Integer>(){};

    而不是

    Map<String, Integer> intMap = new HashMap<String, Integer>;

    后者是test2()

  • 相关阅读:
    奇怪的肚疼
    惊喜:vs2005 和 msdn 中文版 已经提供Subscriber 下载,MSDN全球订户可以下中文版爽了
    英语构语法(前、后缀部分)
    TSQL中的递归 作者:Alexander Kozak
    筹划向 Visual Studio 2005 导航控件的迁移 作者:Dave Donaldson Steven DeWalt
    Atlas客服端文件介绍
    Chinese lunar calendar for www.live.com
    帮助解决网页和JS文件中的中文编码问题的小工具
    ADO.NET 2.0 功能一览 作者:Bob Beauchemin
    Prototype.js 1.4中文使用手册PDF版下载
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/9804097.html
Copyright © 2011-2022 走看看