简化问题
日常使用过程中,我们经常碰到泛型的序列化Json,但是有时候我们需要把一个Json反序列化成一个泛型对象,怎么做,你可能会想到这样做,例如在Gson中
1
| Gson().fromJson<List<String>>(JsonString, List<String>::class.java)
|
但是你这样写,其实会遇到一个错误 ** Only classes are allowed on the left hand side of a class literal**
为什么会这样,因为泛型有类型擦除,泛型其实只是在编译的存在,运行的时候是不存在的,而反序列化需要再运行的时候获取到具体的类型,而类型却被擦除了,所以会报错,那么怎么办?
泛型怎么反序列化成对象?
看函数的参数类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException { T object = fromJson(json, TypeToken.get(classOfT)); return Primitives.wrap(classOfT).cast(object); }
public <T> T fromJson(String json, TypeToken<T> typeOfT) throws JsonSyntaxException { if (json == null) { return null; } StringReader reader = new StringReader(json); return fromJson(reader, typeOfT); }
|
TypeToken实际上是私有的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class TypeToken<T> { @SuppressWarnings("unchecked") protected TypeToken() { this.type = getTypeTokenTypeArgument(); this.rawType = (Class<? super T>) $Gson$Types.getRawType(type); this.hashCode = type.hashCode(); }
@SuppressWarnings("unchecked") private TypeToken(Type type) { this.type = $Gson$Types.canonicalize(Objects.requireNonNull(type)); this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type); this.hashCode = this.type.hashCode(); } }
|
我们可以通过构造Type来达到目的, 但是这个Type是接口,我们需要构造ParameterizedType
1 2 3
| public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException { return (T) fromJson(json, TypeToken.get(typeOfT)); }
|
1 2 3 4 5 6 7 8 9 10 11
| fun main(args: Array<String>) { Gson().fromJson<List<String>>("JsonString", getType(List::class.java, String::class.java)) } fun getType(raw: Class<*>, vararg args: Type) = object : ParameterizedType { override fun getRawType(): Type = raw override fun getActualTypeArguments(): Array<out Type> = args override fun getOwnerType(): Type? = null }
|
如果有多重泛型怎么写,getType可以嵌套调用的,通过Type构成Type
1 2
| getType(List::class.java, getType(List::class.java, String::class.java))
|