我正在为两个依赖的泛型模型实现Gson TypeAdapter
。
interface ModelA<T> {}
interface ModelB<T> extends ModelA<List<T>> {}
为此,我需要获得TypeToken
和TypeAdapter
。通过做
Type type = ((ParameterizedType) type).getActualTypeArguments()[0];
TypeToken<?> token = TypeToken.get(type);
TypeAdapter<?> adapter = gson.getAdapter(token);
我为任何给定类型AnyType
的模型和相关适配器获取了一个类型标记。这是我ModelA
所需要的,但对于ModelB
,我需要List<AnyType>
的适配器,这是直接使用ModelA<List<AnyType>>
的结果。
使用传递原始类型标记的原始类型的接口
token.getRawType().getGenericInterfaces()[0]
我似乎只获得了List
类型的删除类型。
如何组合这两个信息以获取通用List<AnyType>
类型或直接创建?作为输入,它只有ModelB<AnyType>
的类型标记。
对于给定的行为,我实施了一个显示差异的简单测试。我使用Gson内部非API类expected
从 hahn 的答案中取了$Gson$Types
部分。
public class TypeTokenValidate {
public interface ModelA<T> {}
public interface ModelB<T> extends ModelA<List<T>> {}
@Test
public void genericToken() throws Exception {
TypeToken<ModelB<String>> token = new TypeToken<ModelB<String>>() {};
ModelB<String> m = new ModelB<String>() {};
Type expected = $Gson$Types.resolve(ModelB.class, m.getClass(),
ModelA.class.getTypeParameters()[0]);
assertEquals(expected, getActual(token));
}
private static Type getActual(TypeToken<?> token) {
Type type = token.getType();
//type = token.getRawType().getGenericInterfaces()[0];
type = ((ParameterizedType) type).getActualTypeArguments()[0];
return TypeToken.get(type).getType();
}
}
答案 0 :(得分:3)
您可以使用$Gson$Types
来检索已键入Type
的{{1}}。例如:
List
会返回ModelB<String> m = new ModelB<String>() {};
Type resolve = $Gson$Types.resolve(m.getClass(), m.getClass(), ModelA.class.getTypeParameters()[0]);
,Type
设置为rawType
,List
设置为typeArguments
。因此,您可以根据需要保留类型。
然后执行此块
[String]
会导致TypeToken<?> token = TypeToken.get(resolve);
TypeAdapter<?> adapter = gson.getAdapter(token);
的适配器设置为CollectionTypeAdaptorFactory
elementTypeAdapter.type
。
答案 1 :(得分:1)
如果您使用.getType()
而不是.getRawType()
,那么您要查找的信息似乎会被保留:
import java.util.List;
import java.lang.reflect.ParameterizedType;
import com.google.gson.reflect.TypeToken;
public class Test {
public interface ModelA<T> {};
public interface ModelB<T> extends ModelA<List<T>> {}
public static void main(String[] args) {
// Using java.lang.reflect.*:
System.out.println(ModelB.class.getGenericInterfaces()[0]);
// out: Test.Test$ModelA<java.util.List<T>>
System.out.println(((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0]);
// out: java.util.List<T>
System.out.println(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0]).getActualTypeArguments()[0]);
// out: T
// Recovery from a TokenType instance...
// ... using .getRawType()
System.out.println(TypeToken.get(ModelB.class.getGenericInterfaces()[0]).getRawType());
// out: interface Test$ModelA
System.out.println(TypeToken.get(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0])).getRawType());
// out: interface java.util.List
// ... using .getType()
System.out.println(TypeToken.get(ModelB.class.getGenericInterfaces()[0]).getType());
// out: Test$ModelA<java.util.List<T>>
System.out.println(TypeToken.get(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0])).getType());
// out: java.util.List<T>
}
}
希望您能从中找出如何创建TokenAdaptors
。