EnumSet作为泛型接口中的参数



我有一个用例:

inteface A{
get(EnumSet<?> fetchModes);
}
class B implements A{
//Here FetchMode is an enum
get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}

但它抛出了编译时错误:

类B的方法get与类型A的get(EnumSet fetchMode(具有相同的擦除,但不会覆盖它。

我读到枚举不能是泛型的,但有什么方法可以实现这个用例吗?(基本上希望EnumSet是通用的,不同的实现可以传递不同的Enum(

如果参数类型完全匹配,则一个方法可以覆盖另一个方法,但您的方法不匹配。尽管EnumSet<FetchMode>EnumSet<?>的一个子型,但它们并不完全相同。您并没有覆盖子类中的超类方法get(EnumSet<?> fetchModes);,而是用不同的参数类型重载它。当您检查或反编译字节码get(EnumSet fetchModes)时,由于擦除,这两个都具有相同的签名,并且编译器开始抱怨。

JLS§8.4.8.1:对此进行了说明

一个类不能有两个具有相同名称和类型的成员方法擦除

解决这个问题的一个简单尝试是更改参数类型,使其与超级类的参数类型兼容,并在子类中正确地重写方法。

@Override
public void get(EnumSet<?> fetchModes) {
}

尽管这在某种程度上修复了编译器错误,但它仍然不优雅,因为它允许EnumSet存储任何对象。但理想情况下,您可能希望它只存储Enum的某个子类型。这个成语支持这一点。

您要做的是用有界类型参数声明一个泛型接口,然后通过正确重写方法来实现它,如下所示。

public interface A<E extends Enum<E>> {
void get(EnumSet<E> fetchModes);
}
public class B implements A<FetchMode> {
@Override
public void get(EnumSet<FetchMode> fetchModes) {
}
}

尝试一下,你必须使泛型类型扩展Enum:

public class B implements A<FetchMode> {
//Here FetchMode is an enum
public void get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}
}
interface A<T extends Enum<T>> {
void get(EnumSet<T> fetchModes);
}

相关内容

  • 没有找到相关文章

最新更新