更新时间:2022-12-30 15:20:28
我想我理解你的问题.您想序列化一个 Foo
,并且您在运行时拥有 T
的类对象(但它在编译时不固定).因此,Gson 中建议的创建 TypeToken
匿名子类的解决方案不起作用,因为这要求参数化类型(例如 Foo
)在以下位置进行硬编码编译时间,如果你使用类似 Foo
的东西,它就不起作用.
I think I understand your question. You want to serialize a Foo<T>
, and you have the class object of T
at runtime (but it's not fixed at compile time). Therefore, the suggested solution in Gson of creating an anonymous subclass of TypeToken
does not work because that requires that the parameterized type (e.g. Foo<String>
) be hard-coded at compile time, and it does not work if you use something like Foo<T>
.
但是,让我们看看 Gson 站点上的 TypeToken
方法实际上完成了什么.您创建 TypeToken
的匿名子类的对象,然后使用其 getType()
方法请求其类型参数.类的超类是其元数据的一部分,并包括其超类的通用参数.所以在运行时,它可以查看自己的继承层次结构,并找出你为TypeToken
使用的类型参数,然后返回一个java.lang.reflect.Type
实例对于该类型(如果它被参数化,它将是一个 ParameterizedType
实例).一旦你得到这个 Type
实例,你应该把它作为 toGson()
的第二个参数传递.
However, let's look at what the TypeToken
method on the Gson site actually accomplishes. You create an object of an anonymous subclass of TypeToken
, and then ask for its type parameter using its getType()
method. A class's superclass is part of its metadata, and includes the generic parameters of its superclass. So at runtime, it can look at its own inheritance hierarchy, and figure out what type parameter you used for TypeToken
, and then returns a java.lang.reflect.Type
instance for that type (which, if it is parameterized, will be a ParameterizedType
instance). Once you get this Type
instance, you are supposed to pass it as the second argument of the toGson()
.
我们需要做的就是找到另一种方法来创建 ParameterizedType
的这个实例.ParameterizedType
是一个接口,但遗憾的是公共Java API 没有提供任何具体的实现或任何方式来动态创建ParameterizedType
.在私有 Sun API 和您可以使用的 Gson 代码中,似乎有一个名为 ParameterizedTypeImpl
的类(例如这里).您可以简单地复制代码并将其重命名为您自己的类.然后,要在运行时创建一个表示 Foo
的 Type
对象,您可以执行类似 new ParameterizedTypeImpl(Foo.class, new Type[]{String.class}, null)
(未测试)
All we need to do is find another way to create this instance of ParameterizedType
. ParameterizedType
is an interface, but unfortunately the public Java API does not provide any concrete implementations or any way to create a ParameterizedType
dynamically. There appears to be a class called ParameterizedTypeImpl
, in the private Sun APIs and in the Gson code that you can use (e.g. here). You can simply copy the code and rename it into your own class. Then, to create a Type
object representing Foo<String>
at runtime, you can just do something like new ParameterizedTypeImpl(Foo.class, new Type[]{String.class}, null)
(untested)