如何在运行时从通用类型定义和运行时类型参数构建Java类型对象? [英] How do I build a Java type object at runtime from a generic type definition and runtime type parameters?

查看:147
本文介绍了如何在运行时从通用类型定义和运行时类型参数构建Java类型对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设泛型类型声明(Java)

  class Foo< T> {
public T bar;




$ p
$ b

我如何在运行时实例化一个表示Foo参数化的Type对象一个特定的类型T(也只在运行时才知道)?

解决方案

我想我明白你的问题。你想序列化一个 Foo< T> ,并且在运行时你有类对象 T 在编译时固定)。因此,Gson建议创建 TypeToken 的匿名子类的解决方案不起作用,因为这需要参数化类型(例如 Foo < / code>)在编译时被硬编码,如果使用类似于 Foo< T> 的元素,则它不起作用。



然而,让我们看看Gson站点上的 TypeToken 方法实际完成了什么。您创建一个匿名的 TypeToken 子类的对象,然后使用它的 getType()方法询问它的类型参数。一个类的超类是它的元数据的一部分,并且包括它的超类的通用参数。因此,在运行时,它可以查看自己的继承层次结构,并找出用于 TypeToken 的类型参数,然后返回 java.lang .reflect.Type 这个类型的实例(如果它是参数化的,它将是一个 ParameterizedType 实例)。一旦获得 Type 实例,就应该将它作为的第二个参数传递给toGson()



我们需要做的是找到另一种方法来创建这个 ParameterizedType 的实例。 ParameterizedType 是一个接口,但不幸的是,公共Java API没有提供任何具体的实现,也没有提供任何方法来创建 ParameterizedType 动态。似乎有一个名为 ParameterizedTypeImpl 的类,可以在私有Sun API和Gson代码中使用( eg here )。您可以简单地复制代码并将其重命名为您自己的类。然后,在运行时创建类型代表 Foo< String> >的对象,您可以像 new ParameterizedTypeImpl(Foo.class,new Type [] {String.class},null)(未测试)

Assuming a generic type declaration (Java)

class Foo<T> {
    public T bar;
}

how can I, at runtime, instantiate a Type object that represents Foo parameterized over a specific type T (also known only at runtime)?

解决方案

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>.

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().

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)

这篇关于如何在运行时从通用类型定义和运行时类型参数构建Java类型对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆