避免Java类型擦除


问题内容

有没有一种方法可以避免类型擦除并获得对类型参数的访问?

public class Foo<T extends Enum<?> & Bar> {
    public Foo() {
        // access the template class here?
        // i.e. :
        baz(T.class); // obviously doesn't work
    }

    private void baz(Class<T> qux) { 
        // do stuff like
        T[] constants = qux.getEnumConstants();
        ...
    } 
}

我需要了解T并使用它来做事。是否可以,如果可以,如何在 将类传入构造函数或参数之外的任何地方的 情况下 完成操作?

编辑: 这个问题的主要目的是找出是否有 任何实用的方法 来消除类型擦除。


问题答案:

实际上, 没有 类型擦除的实用方法,因为您不能要求运行时无法访问的内容。当然,假设您同意为实现Bar接口的每个枚举子类化通用类是一个实际的解决方法。

enum Test implements Bar {
    ONE, TWO
}

class Foo<T> extends FooAbstract<Test> {
    public Foo() {
        ParameterizedType genericSuperclass =
                (ParameterizedType) getClass().getGenericSuperclass();
        baz((Class<T>) genericSuperclass.getActualTypeArguments()[0]);
    }

    private void baz(Class<T> qux) {
        T[] constants = qux.getEnumConstants();
        System.out.println(Arrays.toString(constants)); // print [ONE, TWO]
    }
}

interface Bar {
}

class FooAbstract<T extends Enum<?> & Bar> {
}