Android中GSON序列化List<String>及TypeToken访问权限问题咨询
问题解答:GSON解析与TypeToken访问错误处理
一、GSON存储字符串带"values"是否正常?
这肯定是不正常的,说明你在序列化URL列表的时候,没处理好JSON结构。正常情况下,如果原始数据是纯URL数组(比如["https://xxx.com", "https://yyy.com"]),用GSON直接序列化List<String>的话,得到的应该就是纯数组字符串,不会多出外层的{"values": [...]}结构。
出现这个问题的常见原因有两个:
- 你可能定义了一个带
values字段的包装类(比如UrlWrapper),然后把这个包装类对象序列化后存入了数据库,而不是直接序列化URL列表本身。举个例子:
// 错误示范:用包装类导致外层多了values键 public class UrlWrapper { private List<String> values; // getter/setter } // 然后序列化的是wrapper对象,不是list String json = new Gson().toJson(new UrlWrapper(urlList));
- 或者你在解析后端返回的JSON时,错误地用对象类型去接收纯数组,导致GSON自动给你包装了一层
values结构。
解决办法也很明确:
- 如果后端返回的就是纯URL数组,直接序列化
List<String>即可:String json = new Gson().toJson(urlList);,这样存入数据库的就是干净的数组字符串。 - 如果后端返回的确实是
{"values": [...]}的结构,那你得用对应的包装类去解析,存储时可以选择存整个包装类的JSON,或者提前把values列表提取出来单独存储。
二、TypeToken has protected access错误含义与解决
这个错误的意思很直白:TypeToken的构造方法是protected权限的,你不能直接通过new TypeToken<List<String>>()来创建实例——这是GSON的刻意设计,因为TypeToken需要借助Java的匿名内部类机制来保留泛型的类型信息(毕竟Java运行时会擦除泛型)。
你的代码大概率犯了这个错误:
// 错误写法!直接实例化TypeToken会触发权限错误 TypeToken<List<String>> token = new TypeToken<List<String>>();
正确的做法是通过匿名内部类来创建TypeToken,这样Java会保留泛型参数的信息,GSON才能正确解析泛型集合:
// 正确写法:用匿名内部类获取Type Type urlListType = new TypeToken<List<String>>() {}.getType(); List<String> urlList = new Gson().fromJson(dbStoredString, urlListType);
要是你用的是GSON 2.10及以上版本,还可以用更简洁的参数化类型生成方式:
Type urlListType = TypeToken.getParameterized(List.class, String.class).getType();
这样也能避免匿名内部类的写法,效果是一样的。
总结你的代码问题
综合来看,你的代码可能存在两个问题:
- 序列化URL列表时错误使用了包装类,导致存储的JSON带
values外层; - 反序列化时没有用正确的方式创建
TypeToken,触发了权限访问错误。
内容的提问来源于stack exchange,提问作者ibai.kar
相关产品推荐
相关产品推荐

