【问题标题】:Get "real" class of generic type获取泛型类型的“真实”类
【发布时间】:2011-04-26 01:54:21
【问题描述】:

如何获得泛型类型的“真实”类?

例如:

public class MyClass<T> {
    public void method(){
        //something

        System.out.println(T.class) //causes a compile error, I wont the class name

        //something
    }
}

如果 T = 整数

输出:

java.lang.Integer

如果 T = 字符串

输出:

java.lang.String

谢谢

【问题讨论】:

  • 你可以通过反射得到这个。但是......请记住,如果您必须根据其通用类型来区别对待您的数据,那么您做错了。你不应该这样做。如果你必须这样做,它并不像你想象的那么通用,这意味着你的班级有问题。
  • @glowcoder:我自己遇到的一个可能有效的示例是访问泛型类型的静态属性。一种解决方法是定义一个您从未真正使用过的实例,例如T obj;,因此您可以稍后说obj.static_property。另外,你可以((T)null).static_property
  • 如果您有该类型的对象,您可以在该对象上调用getClass 方法。不确定这是否有帮助。
  • @glow:请发布答案,以便我们投票!

标签: java generics


【解决方案1】:

如果您的类中有一个类型为 T 的实例变量,并且它恰好被设置,那么您可以打印该变量的类。

public class Test<T> {

    T var;

    public static void main(String[] args) {
        Test<Integer> a = new Test<Integer>();
        System.out.println(a.boo());
        a.setVar(new Integer(10));
        System.out.println(a.boo());
    }

    public String boo() {
        if (var == null) {
            return "Don't know yet";
        }
        return var.getClass().getSimpleName();
    }

    public void setVar(T var) {
        this.var = var;
    }

    public T getVar() {
        return var;
    }
}

【讨论】:

  • 考虑将 var 设置为 X 扩展 T 的类 X 的实例的情况。boo() 将打印 X 而不是 T。
【解决方案2】:

你不能。该信息在编译时从代码中剥离,这一过程称为类型擦除。更多内容请看这里:Type Erasure

编辑:对不起,运行时未加载信息。

【讨论】:

  • 好吧,不是特别正确,它在类文件中作为类或方法属性。它只是在运行时没有加载到内存中。
【解决方案3】:

正如其他人所解释的那样,您不能以这种方式做到这一点,但这是在 java 中通常实现的方式。

public class MyClass<T> {
    public void method(Class<T> clazz) {
        // something

        System.out.println(clazz.getName());

        // something
    }
}

然后你就这样使用它

new MyClass<String>().method(String.class);

【讨论】:

    【解决方案4】:

    就您的情况而言,您不能。但是,您也许可以将 Super Type Tokens 用于此类事情:http://gafter.blogspot.com/2006/12/super-type-tokens.html

    Jackson json 处理库的 TypeReference 类就是一个示例实现。

    这是高级的东西,可能比你想知道的要多;-)

    【讨论】:

      【解决方案5】:

      请注意,在接收到的泛型类型的实例上依赖“getClass()”的方法将获得该对象的实际类型,这不一定是泛型类型 - 这将是调用者知道实例的类型.

      例如,考虑调用者通过接口处理对象的情况;当传递给泛型构造时,泛型类型将是接口,而不是实例的实际类。

      考虑以下示例“Pair”类,它允许通过 POJO 返回两个对象引用:

      public class Pair<U,V>
      {
          public final U first;
          public final V second;
          public static <U,V> Pair<U,V> of (U first, V second)
          {
              return new Pair<U,V> (first, second);
          }
          protected Pair (U first, V second)
          {
              this.first  = first;
              this.second = second;
          }
      }
      

      我们正在考虑如何修改“Pair.of()”工厂函数以返回一个 Comparable Pair 派生类,如果 U 和 V 都是 Comparable 的话。然而,虽然我们可以使用 instanceof 判断 'first' 和 'second' 是否具有可比性,但我们不知道 'U' 和 'V' 本身是否具有可比性。

      为此,Pair.of() 返回的 Pair 的确切类型必须取决于泛型类型,而不是实际的参数类型。

      【讨论】:

        猜你喜欢
        • 2019-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多