如何从某个类中获取参数化类型

时间:2017-03-22 04:13:48

标签: java generics

我有一个通用类,如下所示

public class X<T> {
    Integer x1;
    T x2;
}

是否可以通过提供特定T的类来获得X的类型? 有点像下面的代码。

public <T> Class<?> getType(Class<T> cls) {
    return X<cls>.class;
}

===================== news =======================

谢谢大家的回答。让我解释一下我的问题的更多细节。

我只想反序列化X的对象。假设T = Integer。

如果使用Gson,代码将为:

X x = new Gson().fromJson("{x1: 1, x2: 2}", new TypeToken<X<Integer>>(){}.getType());

但我不想每次写这么久。我在想是否有办法可以简化代码如下:

X x = deserializeFunc("{x1: 1, x2: 2}", Integer.class);

3 个答案:

答案 0 :(得分:1)

泛型在运行时被“擦除”,这意味着(除其他外)对于给定的泛型类,只有一个Class对象。例如,下面打印true

final List<String> stringList = new ArrayList<String>();
final List<Integer> integerList = new ArrayList<Integer>();
System.out.println(stringList.getClass() == integerList.getClass());

所以你的问题没有意义;你的方法有return-type Class<?>,所以你显然不打算在编译时使用type参数;并且X.class只是一个单独的实例,无论类型参数如何,因此类型参数在运行时不存在。

(但我不确定这是“是”还是“不”。我想这取决于你想用这个完成的事情!)

答案 1 :(得分:0)

这类问题的一般解决方案是要求调用者将Class传递给构造函数。有很多例子(例如EnumSet),您的X类可能如下:

public class X<T> {
  private final Class<T> clazz;
  // fields

  public X(Class<T> clazz, /* arguments... */) {
    this.clazz = clazz;
    // set fields
  }

  public Class<T> getClass() {
    return clazz;
  }

  // ...
}

如果您的目标是在运行时引用泛型类型(例如X<T>,则需要使用不同的解决方法.Gson提供{{3}这样的功能},它允许您在运行时指定泛型类型。这在TypeToken中讨论,这是他们的示例:

Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

gson.fromJson(json, fooType);

答案 2 :(得分:0)

不是。 java中发生的擦除不允许发生这种情况。我不太理想的解决方案是在你的类上创建一个Class类型的字段,然后你可以看看:

public class X<T> {
    final Class<T> myType;
    Integer x1;
    T x2;
    public X(Class<T> myType) {
      this.myType = myType;
    }
}

然后你可以用x.myType来获取泛型类的类。