好吧,首先,你需要了解为什么你所做的可能不是你认为的所做的。让我们来看一个简单的例子。
interface Face { <T> List<T> get();}你所拥有的是通用方法
get。泛型方法的类型参数取决于调用站点提供的内容。因此,例如:
Face f = ...;// this call site dictates T to be NumberList<Number> l = f.<Number>get();
当你覆盖它像
class Impl implements Face { @Override public List<String> get() { return ...; }}你可以执行此操作(仅由于擦除操作),但你可能不应该这样做。仅允许向后兼容非通用代码。你应该听警告并且不要这样做。这样做意味着例如,我仍然可以指示它返回其他内容:
Face f = new Impl();// now I've caused heap pollution because you// actually returned to me a List<String>List<Number> l = f.<Number>get();
这就是为什么存在未经检查的转换的原因。
你可能要使用的是通用接口声明:
interface Face<T> { List<T> get();}现在,参数
to
T取决于对象引用的类型。
Face<Number> f = ...;// get must return List<Number>List<Number> l = f.get();
我们可以像
class Impl implements Face<String> { @Override public List<String> get() { return ...; }}此外,你无法访问枚举上的协变返回类型。当你覆盖枚举常量上的方法时,其类为匿名。匿名类没有名称,因此无法引用。因此,程序员无法知道其协变返回类型来使用它。此外,枚举不能声明泛型类型参数。因此,使用枚举根本无法实现你想做的事情。
你可以使用带有public static final实例的类来模拟通用枚举:
public abstract class SimEnum<T> implements Face<T> { public static final SimEnum<Number> A = new SimEnum<Number>() { @Override public List<Number> get() { return ...; } }; public static final SimEnum<String> B = new SimEnum<String>() { @Override public List<String> get() { return ...; } }; private SimEnum() {} public static SumEnum<?>[] values() { return new SimEnum<?>[] { A, B }; }}否则,你需要彻底改变你的想法。



