获取泛型类型的“真实”类

14

我该如何获取泛型类型的“真实”类?

例如:

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

谢谢


2
你可以通过反射来获取这个。但是...请记住,如果您必须根据其泛型类型以不同方式处理数据,则做法是错误的。您不应该这样做。如果您确实需要这样做,那么它并不像您认为的那样通用,这意味着您的类存在问题。 - corsiKa
1
@glowcoder:一个可能有效的例子,我自己也遇到过,就是访问泛型类型的静态属性。一种解决方法是定义一个你从未真正使用过的实例,比如 T obj;,这样你就可以在以后说 obj.static_property。此外,你还可以做 ((T)null).static_property - mellamokb
如果您有该类型的对象,您可以在该对象上调用getClass方法。不确定这是否有帮助。 - Cristian Sanchez
1
@glow:请发布一个答案,这样我们就可以点赞了! - Hovercraft Full Of Eels
5个回答

22
如果你的类中有一个类型为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 的一个实例,其中 X 扩展了 T。boo() 将打印 X 而不是 T。 - jackrabbit

11

你不能从运行时获取这些信息。 在编译时,代码中的信息会被去除,这个过程称为类型擦除。 了解更多信息,请参见:类型擦除

编辑:对不起,我的错误,信息不是在运行时加载的。


1
好的,不是特别准确,它作为类或方法属性存储在类文件中。只是在运行时没有加载到内存中。 - MeBigFatGuy

4

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

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

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

        // something
    }
}

你可以像这样使用它

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

3
在您的情况下,您无法这样做。但是,您可能可以使用超级类型标记来处理此类事情:http://gafter.blogspot.com/2006/12/super-type-tokens.html。这些的一个示例实现是Jackson json处理库的TypeReference类。
这是高级内容,可能比您想知道的还要多;-)

0
请注意,依赖于对使用泛型类型接收的实例调用'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()' 工厂函数,以便在 U 和 V 都是可比较的情况下返回一个可比较的 Pair 派生类。然而,虽然我们可以使用 instanceof 确定 'first' 和 'second' 是否可比较,但我们不知道 'U' 和 'V' 自身是否可比较。
为使此方法奏效,由 Pair.of() 返回的 Pair 的确切类型必须取决于泛型类型,而不是实际参数类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接