如何在运行时从泛型类型定义和运行时类型参数构建Java类型对象?

Sof*_*mes 10 java generics reflection

假设泛型类型声明(Java)

class Foo<T> {
    public T bar;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在运行时实例化一个Type对象,该对象表示在特定类型T上参数化的Foo(也仅在运行时才知道)?

new*_*cct 13

我想我理解你的问题.你想序列化一个Foo<T>,并且你有T运行时的类对象(但它在编译时没有修复).因此,Gson中建议的创建匿名子类的解决方案TypeToken不起作用,因为它要求参数化类型(例如Foo<String>)在编译时进行硬编码,如果使用类似的东西则不起作用Foo<T>.

但是,让我们来看看TypeTokenGson网站上的方法实际上是什么.您创建一个匿名子类的对象TypeToken,然后使用其getType()方法请求其类型参数.类的超类是其元数据的一部分,包括其超类的泛型参数.因此,在运行时,它可以看看自己的继承层次结构,并找出你使用什么类型的参数TypeToken,然后返回一个java.lang.reflect.Type实例该类型(其中,如果是参数化,将是一个ParameterizedType实例).一旦你得到这个Type实例,你应该把它作为第二个参数传递给你toGson().

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


Ale*_*exV 5

假设我们正在谈论List<String>例如。
您可以构造如下:

    Type type = new ParameterizedType() {
            public Type getRawType() {
                return List.class;
            }

            public Type getOwnerType() {
                return null;
            }

            public Type[] getActualTypeArguments() {
                return new Type[] { String.class};
            }
        };
Run Code Online (Sandbox Code Playgroud)

如果您需要此功能以从JSON反序列化,则可以Type通过调用使用此功能gson.fromJson