java获取泛型的实际类型

这是一个困扰了我好久的问题,在我写的android请求框架总结(二)中写到过利用框架自动解析json数据,代码如下

Object o;
if (result.charAt(0) == '{') {
//解析对象
     o = new Gson().fromJson(result, clazz);
} else {
      //这个方法是在stackoverflow中找到的可将json转换为list,普通的通过type去解析是不行的
      o = new Gson().fromJson(result, com.google.gson.internal.$Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, clazz));
}
listener.success(o);

返回的对象也只能是Object类型,具体用的时候还需要做一下强转

HttpClient.postRequest(this, "http://www.baidu.com", TestBean.class, map, new OnResponseListener() {
            @Override
            public void success(Object result) {
                //如果result为对象
                TestBean testBean = ((TestBean) result);
                //如果result为list
                List<TestBean> testBeans = (ArrayList<TestBean>) result;
            }

            @Override
            public void failure(String errorMessage) {
                System.out.println("errorMessage = " + errorMessage);
            }
        });

其实当时有想过用泛型来做,但就是不知如何获取泛型的实际类型,虽然已经比较简洁了,但是感觉还不太彻底,如果直接能得到对象就更好了,终于,皇天不负有心人,有大神解决了这个问题,前两天比较火的hongyang大神的OkHttpUtils的一篇文章关于json自动解析的这一块对我的帮助比较大,当然,我也顺便吐槽下,OkHttpUtils的封装并不能帮助大家更好的理解OkHttp,OkHttp的设计非常优秀,但是经过这么一封装,又和之前看到的快速开发框架无异,希望看的人也能多思考,可以借鉴其中优秀的地方,同时也要能看到不足的一面,不要盲目跟风。

看代码:

 public static abstract class ResultCallback<T>
    {
        Type mType;

        public ResultCallback()
        {
            mType = getSuperclassTypeParameter(getClass());
        }

        /** * 得到泛型T的实际Type */
        static Type getSuperclassTypeParameter(Class<?> subclass)
        {
            Type superclass = subclass.getGenericSuperclass();
            if (superclass instanceof Class)
            {
                throw new RuntimeException("Missing type parameter.");
            }
            ParameterizedType parameterized = (ParameterizedType) superclass;
            return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
        }

    }

使用

callBack.onSuccess(new Gson().fromJson(result, callBack.type));

这样就可以直接返回结果,如下:

//也支持List<Person>直接返回
 HttpClient.post(response, new ResultCallBack<TestBean>() {
            @Override public void onSuccess(TestBean result) {
            }
        });

这种方式可以简化不少的代码,但是Android Studio不是很给力,通常提示是这样的

java获取泛型的实际类型_第1张图片

完了还要移动鼠标手动去修改代码,比原来做一下强转也没有方便多少,但还是有办法的,还记得android Studio提供的活动模板(live template)的功能吗?Android Studio 使用技巧(三),这里来体验下它的强大之处,效果演示:

java获取泛型的实际类型_第2张图片

还有一点不明我测试了下

Gson Types.canonicalize(parameterized.getActualTypeArguments()[0]); 和
parameterized.getActualTypeArguments()[0]
打印的结果是一样的,去掉外面的一层包裹也能正常运行

你可能感兴趣的:(java,android,框架,泛型,模板引擎)