Android Gson的使用和源码分析总结

Gson

  • JSON(JavaScript Object Notation)
    是一种轻量级的数据交换格式
  • Gson
    Google推出的用于在Java对象和JSON数据之间进行映射的Java类库,可以将一个JSON字符串转化为Java对象(反序列化),或者将Java对象转换为JSON字符串(序列化)

Gson使用

//https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.8.5'
  • 序列化、反序列化
    // 使用new方法
    Gson gson = new Gson();

    //======================================================
    
    // toJson 将bean对象转换为json字符串
    String jsonStr = gson.toJson(user);
    
    // fromJson 将json字符串转为bean对象
    Student user= gson.fromJson(jsonStr, User.class);
    
    //======================================================
    
    // **序列化List**
    String jsonStr2 = gson.toJson(list);
    
    // **反序列化成List时需要使用到TypeToken getType()**
    List<User> retList = gson.fromJson(jsonStr2,new TypeToken<List<User>>(){}.getType());

TypeToken

  • 在反序列化列表时,用到了TypeToken
    @Test
    public void test5() {
        Gson gson = new Gson();
        User user1 = new User(10, "bob");
        User user2 = new User(12, "jack");
        ArrayList<User> users = new ArrayList<>();
        users.add(user1);
        users.add(user2);
        //序列化(Java对象转换为字节序列的过程)
        String json = gson.toJson(users);
        System.out.println(json);
        //反序列化(把字节序列恢复为Java对象的过程)
        List<User> userList = gson.fromJson(json,
                new TypeToken<List<User>>() {
                }.getType());
        System.out.println(userList);
    }
    /*
     * [{"age":10,"name":"bob"},{"age":12,"name":"jack"}]
     * [User(age=10, name=bob), User(age=12, name=jack)]
     */

  • kotlin中
        //反序列化
        val users: List<User> = Gson().fromJson(json, object : TypeToken<List<User>>() {}.type)
        //[User(name=zy, age=10), User(name=lm, age=10), User(name=zz, age=10)]
        Log.d(TAG, "test: $users")
  • Gson查看TypeToken的源码
    客户端创建一个空的匿名子类,这样做会将类型参数嵌入到匿名类的类型层次结构中,这样我们就可以在运行时重建它,而不用考虑类型擦除。

public class TypeToken<T> {
  //type对应的class类型
	final Class<? super T> rawType;
	//T对应的类型
	final Type type;
	final int hashCode;
	
	/*
	客户端创建一个空的匿名子类。
	这样做会将类型参数嵌入到匿名类的类型层次结构中,这样我们就可以在运行时重建它,而不用考虑擦除。
	*/
  protected TypeToken() {
    this.type = getSuperclassTypeParameter(getClass());
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
    this.hashCode = type.hashCode();
  }
  
  //获取泛型类型
  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]);
  }
  ...
}

使用Kotlin对Gson进行改造实现类的真泛型

  • 结合扩展函数和内联函数对Gson进行一次封装
    这样就不需要使用TypeToken的匿名类来获取T的实际类型了
  • reified只能修饰函数,不能修饰类,可以重载类的构造方法,使其具有真泛型的属性
inline fun <reified T> Gson.fromJson(json: String): T {
    return fromJson(json, T::class.java)
}

TypeAdapter核心对象

	//类型适配器,里面
	public abstract class TypeAdapter<T> {
	
		/**
		 *	该方法用于toJson时写入数据序列化
		 **/
		public abstract void write(JsonWriter out, T value) throws IOException;

		/**
		  *   该方法用于fromJson读取数据反序列化
		  **/
	 	public abstract T read(JsonReader in) throws IOException;
	}

Gson、FastJson、JSONObject三者的用法

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值