java - 如何用 Gson 替换 Guava 中的 TypeToken(特别是在使用泛型类型时)
问题描述
我目前正在尝试重构一个项目以避免不得不使用番石榴作为依赖项。我主要将它用于反射相关的功能,但在大多数情况下,我可以找到一个替代方案。
但是,有一种情况我暂时无法解决:我尝试检索当前类的泛型参数的类。
它可以正常使用Guava
,因为返回的类型TokenType
可以转换为类。
番石榴:
(Class<I>) new com.google.common.reflect.TypeToken<I>(getClass()) {}.getType();
我试图用TypeToken
fromGson
代替这个调用,但显然关于 I 的信息丢失了,并且这个调用的结果是一个TypeVariable
比在执行后保留为一个类:
格森:
(Class<I>) new com.google.gson.reflect.TypeToken<I>() {}.getType();
据我所知, getClass() 参数是为什么不保留上下文的线索。当我使用Guava
相同的签名时:
(Class<I>) new com.google.gson.reflect.TypeToken<I>() {}.getType();
我收到此错误消息:
java.lang.IllegalStateException:无法为类型变量构造 TypeToken。您可能打算调用 new TypeToken(getClass()) 来为您解析类型变量。如果您确实需要创建类型变量的 TypeToken,请改用 TypeToken.of()。
我Gson
也将其视为使用Type
as 参数的(包保护的)构造函数。
有没有办法Gson
只使用获取通用参数的类?
编辑#1:
更好地理解这个问题我可以说差异似乎位于两种方法返回的底层 Type 实现中。
Guava 可以铸造,Class<I>
而 Gson 则不能。我不确定 Guava 的底层实现是什么,但 Gson 使用的是TypeVariable
.
目前我发现的解决方法是通过将 Gson TypeToken (Type) 的结果与使用当前类作为上下文的方法合并来利用 Guava 使用的两个信息 (Type + current class):
public static Type getActualType(Class context, Type parameterizedType) {
if (parameterizedType instanceof TypeVariableImpl) {
TypeVariable[] genericParameters = context.getSuperclass().getTypeParameters();
Type[] implementations = ((ParameterizedTypeImpl) context.getGenericSuperclass()).getActualTypeArguments();
for (int i = 0; i < genericParameters.length; i++) {
if (genericParameters[i].getName().equals(((TypeVariableImpl) parameterizedType).getName())) {
return implementations[i];
}
}
}
return parameterizedType;
}
(这个实现来自buremba/netty-rest 项目)
这允许我通过调用来检索预期的类:
(Class<I>) getActualType(getClass(), new com.google.gson.reflect.TypeToken<I>() {}.getType());
这似乎有点费力,我不确定这是最好的方法。
注意:这个问题也是作为Gson 项目的 Github 问题提出的
解决方案
推荐阅读
- javascript - 点击菜单按钮后 ul 消失了
- postgresql - Apache 上的 Flask 应用程序通过 Sqlalchemy 访问 Postgres
- javascript - 检查数组是否具有特定长度的元素
- numpy - AWS EMR:Zeppelin 从 python 2.7 获取 numpy 版本而不是更高版本
- node.js - 外键茉莉花测试失败
- ios - UINavigationBar.appearance().isTranslucent 不工作
- asdf-vm - scala 声称 JAVA_HOME 不正确
- android - 当屏幕强制旋转时,WindowInsets 总是返回 0
- vim - 有什么方法可以将 .vimrc 应用于特定的 tmux 会话?
- angular - nrwl nx 角度构建 API 端点