美文网首页
【面向对象】泛型广泛应用封装

【面向对象】泛型广泛应用封装

作者: 嘻洋洋 | 来源:发表于2019-06-03 14:20 被阅读0次

    实际工作中,我们经常对接口调用进行封装,利用泛型返回结果值。

    1. 封装函数,统一的返回结果值

    所有的调用接口封装成一个公共函数,函数返回一个泛型类。如:

    public class ListResultDto<T> extends Dto
    {
        private static final long serialVersionUID = -7187882293150693618L;
        private static final long serialVersionUID = -557141271464869806L;
            //返回状态标识
        private int rtnCode;
            //返回话术
        private String rtnMsg = RespConstants.SUCCESS_MSG;
            //数据结果
        private List<T> result;
        
    }
    

    //提供泛型方法

    
        /**
         * 将字符串转化成bean对象
         */
        protected <T> T changeJSON2Bean(Class className, String jsonString)
        {
            if (StringUtil.isNotNullEmpty(jsonString))
            {
                return (T) JSON.parseObject(jsonString, className);
            }
            return null;
        }
    
    

    //调用封装函数赋值

        public ListResultDto<GlobalNewGoods> getGlobalNewGoodsRecommend(ModuleRequest req)
        {
            String apiUrl = RestConstants.App.Controller + RestConstants.App.GlobalNewGoodsRecommend;
                    //封装函数,返回泛型
            return requestApi(req, apiUrl, ListResultDto.class);
        }
    

    2. 容易出错的地方

    泛型取值的过程中,比较容易犯错的的地方是json字符串转换对象,一定要按类型转换。使用fastJson的时候对于泛型的反序列化很多场景下都会使用到TypeReference
    错误的做法:

        public static ResultDto<JbOrderStatus> getJbOrderStatus(GlobalOrder tbOrder)
        {
            JSONObject json = new JSONObject();
            String url = "getOrderStatus";
            ResultDto<JbOrderStatus> dto = requestThird(JSON.toJSONString(tbOrder), url, ResultDto.class);
            return dto;
        }
    

    正确的做法:

    //返回json字符串
    String result   =requestThird(jsonObject.toJSONString(), url);
    //ResultDto泛型类,指定按类型转换
    ResultDto<JbOrderStatus> dto =  JSONObject.parseObject(result, new TypeReference<ResultDto<JbOrderStatus>>(){});
    //ResultDto泛型类,指定按类型转换
    ListResultDto<TbGoodsSku> dto = JSONObject.parseObject(result, new TypeReference<ListResultDto<TbGoodsSku>>(){});
    

    类似map,List等泛型,也是如此:

    
        public static void main(String[] args) {
            Map<String, Person> map = new HashMap<>(16);
            map.put("one", new Person("zhangsan"));
            map.put("two", new Person("lisi"));
            String jsonStr = JSON.toJSONString(map);
            byte[] bytes = jsonStr.getBytes();
            String json = new String(bytes);
            Map<String, Person> res = JSON.parseObject(json, Map.class);
            System.out.println(res.get("one"));
            System.out.println(res.get("one").getName());
        }
        执行时异常:
    
    Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:67)
    Caused by: java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to subtitle.io.Person
    

    反序列化时候,虽然添加Map.class,但是没有办法指定Person类型,导致反序列化后的对象为Map<String, Map<String, String>>,而不是Map<String, Person>,所以针对泛型的反序列化,需要使用TypeReference。

    Map<String, Person> res = JSON.parseObject(json, new TypeReference<Map<String, Person>>(){});
    System.out.println(res.get("one"));
    System.out.println(res.get("one").getName());
    

    相关文章

      网友评论

          本文标题:【面向对象】泛型广泛应用封装

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