是否有一种方法可以避免类型擦除并访问类型参数?
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,并用它来做一些事情。这是可能的吗?如果是这样的话,在不传入构造函数中的类或参数之外的任何地方,如何才能做到呢?
编辑:这个问题的主要目的是找出关于类型擦除是否有任何实用的方法。
发布于 2011-12-10 20:12:07
AFACT,没有实用的方法可以绕过类型擦除,因为您不能要求运行时无法访问的东西。当然,假设您同意为实现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> {
}发布于 2011-12-09 23:24:55
如果您愿意/能够将类令牌传递给构造函数:
public Foo(Class<T> clazz) {
baz(clazz);
}
private void baz(Class<T> qux) {
// ...
}这样,您可以使用Class.newInstance()生成T类型的对象,尝试使用Class.cast()将任意对象转换为T,等等。
你打算用baz()做什么?
发布于 2011-12-10 19:30:12
正如pholser在他的回答中所指出的,实现这一目标的唯一方法是传递表示T类型的T对象。正是因为有了类型擦除,像T.class这样的东西才不可能实现,因为T在运行时之前被删除了。
您似乎不愿传入Class对象,但这是使用getEnumConstants()方法的唯一方法。下面是一个完整的示例:
public class Foo<T extends Enum<?> & Bar> {
final Class<T> clazz;
public Foo(Class<T> clazz) {
this.clazz = clazz;
}
public void baz() {
T[] constants = clazz.getEnumConstants();
System.out.println(Arrays.toString(constants));
}
public static void main(String[] args) {
new Foo<MyEnum>(MyEnum.class).baz(); //prints "[A, B, C, D]"
}
}
public interface Bar { }
public enum MyEnum implements Bar { A, B, C, D; }https://stackoverflow.com/questions/8452893
复制相似问题