Gson与ListT对象间的相亲之旅

39次阅读

共计 4294 个字符,预计需要花费 11 分钟才能阅读完成。

随着人们的生活水平的提高,连带着人与人之间的相亲渠道也进一步改善。最近偶尔看到几档相亲的综艺节目,不管是平民还是明星。可见相亲的热潮正扑面而来。这不 Google 与 Java 两个老家伙也坐不住了,分别想着自己排行 285 的儿子 Gson 与自己排行 570 的女儿 List<T> 也该到了相亲的年龄了。于是 Google 与 Java 两个老油条会心一笑,一起策划了今天的这次相亲之旅。

地下恋情

Google 回到家就将此事告诉了 Gson,通知他明天就去 Android Studio 匆匆那年餐厅见面。Gson 欲言欲止,好像另有隐情,但在父亲高大身躯与凌厉的眼神下答应了下来,而且父亲能够在这众多的儿子中想到自己,也不忍心拒绝父亲的善意。

Gson 回到房,躺着床上,脑海回想起自己与 Java 排行 520 的女儿 Object 的地下恋情。

Gson 与 Object 的第一次见面还是被它的 Json 字符串装扮所吸引。那一天她宛如一朵含苞待放的牡丹花,美而不妖,艳而不俗,千娇百媚,无与伦比。(以上均为 Gson 视角,请勿迷恋。以下为 code 视角)

{
    "marquee": {
        "content": "翠绿烟纱散花裙",
        "status": true
    }
}

这一下就激起了 Gson 的欲望,而且 Gson 还有点小得意,对于这种女孩他已经有自己的一套完整攻略方案。既然知道了它的 Json 字符串格式,就可以迅速创建出它对应的 java 类

public class HomeMarqueeModel {
 
    private MarqueeModel marquee;
 
    public static class MarqueeModel {
        private String content;
        private boolean status;
 
        public String getContent() {return content;}
 
        public boolean isStatus() {return status;}
    }
 
    public MarqueeModel getMarquee() {return marquee;}
}

然后再根据 API 攻略法则第 3089 条,使用 fromJson 方案进行攻略,成功率高达 100%

HomeMarqueeModel model = new Gson().fromJson(jsonStr, HomeMarqueeModel.class);

就这样 Gson 完成了对 Object 的第一次攻略,获取到了 Object 的好感。但 Gson 不满足,为了完全让 Object 对自己死心塌地,必须应对 Object 的所有 Json 字符串格式。

回去之后,Gson 在 Android Studio 微信平台与 Java 中的好哥们泛型 T 打探 Object 的特性。经过交流,发现 T 它刚好是这方面的能手,T 告诉 Gson 每一个 Object 都有它独用的 Class 属性,为了代表所有的 Class 类型,刚好可以使用它的泛型 T 来表示,于是就有了 Class<T>

第二天,Gson 主动出击邀请 Object 去 Android Studio 匆匆那年餐厅吃饭。Gson 还是使用它的 fromJson 方法,只是在这方法上加入了 T 的思想。

    public <T> T getObjectGirl(String jsonStr, Class<T> tGirl) {T girl = getGson().fromJson(jsonStr, tGirl);
        return girl;
    }

就这样,Gson 完成对 Object 的所有类型的攻略,从此不再为女友而发愁。
回想结束,拉回到现实,对于明天的相亲,Gson 打算先用之前的方法试一下,毕竟 Gson 经过前面的成功实例,还是有点小膨胀,

初次见面

早上 9 点,Gson 整装待发,开着自己的兰博基尼向 Android Studio 匆匆那年餐厅进发。大约 10 点 Gson 到达餐厅,且已经选好了一处风景优雅且面朝大海的位置,静静的等候 List 的到来。半小时之后,只见一个身穿藕色纱衫的女孩,脸带微笑,身形苗条,长发披向背心,用一根银色丝带轻轻挽住,迎面而来。Gson 望着她的身影,只觉这女孩身旁似有烟霞轻笼,当真非尘世中人。(以上均为 Gson 视角,请勿迷恋。以下为 code 视角)

[
    {
        "title": "身穿藕色纱衫",
        "url": "http://127.0.0.1:8000/admin2/operation/banner-list/",
        "status": true
    },
    {
        "title": "长发披向背心",
        "url": "http://127.0.0.1:8000/admin2/operation/banner-list/",
        "status": true
    }
]

为了保守起见,Gson 决定还是按部就班来,首先创建出该 Json 字符串列表的 java 类

public class HomeBannerModel {
    private String title;
    private String url;
    private boolean status;
 
    public String getTitle() {return title;}
 
    public String getUrl() {return url;}
 
    public boolean isStatus() {return status;}
}

然后再使用 fromJson 方案进行攻略,稍微不同的是这里它是一个数组

HomeBannerModel[] array = new Gson().fromJson(jsonStr, HomeBannerModel[].class);
List<HomeBannerModel> list = Arrays.asList(array);

嗯,看样子效果不错,有进一步发展的机会。于是 Gson 又展示它的另一个攻略

Type type = new TypeToken<List<HomeBannerModel>>(){}.getType();
List<HomeBannerModel> list = new Gson().fromJson(jsonStr, type);

果然,Gson 再一次成功逗笑了 List。Gson 的膨胀心再一次暴涨。Gson 于是大胆起来,套用之前泛型 T 的思想。于是有了下面的第一次 T 尝试

发现不行,不支持这种泛型 T 解析。既然这种不行,还就换另一种, 于是就有了第二次 T 的尝试

public <T> List<T> getListGirl(String jsonStr) {Type type = new TypeToken<List<T>>(){}.getType();
      List<T> listGirl = new Gson().fromJson(jsonStr, type);
      return listGirl;
}

发现没问题,那么再来实践运行一下。发现会报如下异常,导致小姐姐不开心。

java.lang.AssertionError: illegal type variable reference

说明 Gson 解析不支持该泛型 T 书写,导致 Type 解析出错,Gson 一下懵了,那该咋整呢?虽然前面的攻略有效果,但最后的尝试没有成功。但天色以晚,今天的相亲也只能就此打住,有待进一步商榷。

请教

回到家 Gson 一直挂念着这件事,一筹莫展。Google 看到自己儿子愁眉苦展的样子,不经询问今天的进展。了解情况后,Google 给 Gson 的建议是,可以去请教下 ParameterizedType。于是 Gson 迫不及待的去找 ParameterizedType 学习人生真谛。

经过请教,发现 ParameterizedType 是继承于 Type,自己另外提供了三个抽象方法,分别为

  1. Type[] getActualTypeArguments() 返回真正所需的 Type 类型数组
  2. Type getRawType() 返回原始的 Type 类型
  3. Type getOwnerType() 返回此类的成员类型,例如:O<T>.I<S>。如果为顶层类型,则返回 null。

所以为了解决之前的问题,Gson 打算先自定义一个 GirlParameterizedType 类,让它实现 ParameterizedType 接口。code 如下:

    private static class GirlParameterizedType implements ParameterizedType {
 
        private Class aClass;
 
        GirlParameterizedType(Class aClass) {this.aClass = aClass;}
 
        @NonNull
        @Override
        public Type[] getActualTypeArguments() {return new Type[]{aClass};
        }
 
        @NonNull
        @Override
        public Type getRawType() {return List.class;}
 
        @Override
        public Type getOwnerType() {return null;}
    }

既然找到问题所在,Gson 迫不及待的邀请 List 去逛 Android Studio 商城,希望明天能够顺利拿下 List 女神。

再次相见

在 Android Studio 商城,Gson 再一次看到了 List,只不过她今天已经换了一身装扮。只见她身穿粉红玫瑰香紧身袍袍袖上衣,下罩翠绿烟纱散花裙,腰间用金丝软烟罗系成一个大大的蝴蝶结,鬓发低垂斜插碧玉瓒凤钗,显的体态修长妖妖艳艳勾人魂魄。不过 Gson 已早有准备,直接步入主题,拿出昨天准备好的 GirlParameterizedType。

public <T> List<T> getListGirl(String jsonStr, Class<T> tClass) {Type type =  getGson().fromJson(response, new HttpClientParameterizedType(tClass));
      List<T> listGirl = new Gson().fromJson(jsonStr, type);
      return listGirl;
}

发现是如此的简单,一击必中,直击 List 芳心。于是一小时之后,Gson 双手已经挂满了商品,额头也满头大汗,但 List 还有意未尽的样子,Gson 万万没想到最后居然败在购物上,果然带女孩来商城就是个错误的选择 …

这次的相亲也算完美结束,只不过 Gson 心中又有了心的疑虑,对于 Object 与 List 都是百年难遇的女孩,该如何抉择呢?要不各位看官这个抉择就交给你们,相信你们会做出正确的抉择的,毕竟大家都不想在 code 的人生中留下一丝 bug 的身影。

最后,不知大家看的感受如何,有什么感受也可以反馈给我。如果喜欢这种方式,可以关注我的公众号:Android 补给站,以便及时推送最新文章给你哟~

正文完
 0