【问题标题】:EnumSet as a parameter in generic InterfaceEnumSet 作为泛型接口中的参数
【发布时间】:2020-03-10 07:12:55
【问题描述】:

我有一个用例:

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) 具有相同的擦除,但不会覆盖它。

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

【问题讨论】:

标签: java generics inheritance enums enumset


【解决方案1】:

如果参数类型完全匹配,则方法可以覆盖另一个方法,但您的方法不匹配。尽管EnumSet&lt;FetchMode&gt;EnumSet&lt;?&gt; 的子类型,但它们并不完全相同。您没有在子类中覆盖超类方法get(EnumSet&lt;?&gt; 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) {

    }
}

【讨论】:

    【解决方案2】:

    试试这个,你必须让泛型类型扩展 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      相关资源
      最近更新 更多