您需要使用带有未经检查的强制转换的通用辅助方法:
private static <T extends Enum<T> & Marshallable> void fooHelper(Class<? extends Marshallable> type) {
if (type.isEnum()) {
//This is safe because of the isEnum check, and we don't return any
//type with T (important because the caller can specify what T is).
@SuppressWarnings("unchecked")
final Class<T> enumType = (Class<T>)type;
final List<T> enumConstants = Arrays.asList(enumType.getEnumConstants());
foo(enumConstants);
}
}
您的版本不起作用的原因是因为 with T extends Enum<T> & Marshallable
,T
是递归绑定的 - 只能用类型参数表示的东西。通配符类型参数? extends Enum<? extends Marshallable>
不再指定该关系。
警告:必须fooHelper
不返回包含的类型,T
因为这可能会导致堆污染。例如:
private static <T extends Enum<T> & Marshallable> List<T> unsafeFooHelper(Class<? extends Marshallable> type) {
if (type.isEnum()) {
//no longer safe!
@SuppressWarnings("unchecked")
final Class<T> enumType = (Class<T>)type;
return Arrays.asList(enumType.getEnumConstants());
}
return Collections.emptyList();
}
enum Enum1 implements Marshallable { ONE, TWO }
enum Enum2 implements Marshallable { A, B }
...
//caller lies about what T is:
List<Enum2> enumConstants = Main.<Enum2>unsafeFooHelper(Enum1.class);
//sometime later...
Enum2 enumConstant = enumConstants.get(0); //ClassCastException