【问题标题】:Generics: creating interface for Enums泛型:为枚举创建接口
【发布时间】:2021-08-13 17:51:19
【问题描述】:

免责声明:泛型不是很强大。

假设我有这样的枚举:

public enum FirstEnum implements BaseEnum<FirstEnum> {
  
  SOMETHING_1(Month.FEBRUARY, MZ_AUGUST, MZ_NOVEMBER),
  SOMETHING_2(Month.JANUARY, MZ_APRIL, MZ_NOVEMBER);
  
  private final Month month;
  private final List<OtherEnum> otherEnumList;

  FirstEnum(final Month month, final OtherEnum... otherEnumList) {
    this.month = month;
    this.otherEnumList = Arrays.asList(otherEnumList);
  }

  public static List<OtherEnum> getByMonth(final Month month) {
    for (final FirstEnum firstEnum : FirstEnum.values()) {
      if (month.equals(firstEnum.getMonth())) {
        return firstEnum.getOtherEnumList();
      }
    }
    return Collections.emptyList();
  }
}

还有一个像这样的 SecondEnum,但现在不相关。 我的问题是如何实现 BaseEnum(我认为它是一个接口),其中 getByMonth() 方法将使用泛型实现。

我正在尝试这样的事情(但它根本不起作用):

public interface BaseEnum<T extends BaseEnum<T>> {

  static List<OtherEnum> getByMonth(final Month month) {
    for (final T firstEnum : T.values()) {
      if (month.equals(firstEnum.getMonth())) {
        return Arrays.asList(firstEnum.getOtherEnumList());
      }
    }
    return Collections.emptyList();
  }
}

感谢任何帮助!

【问题讨论】:

    标签: java generics enums


    【解决方案1】:

    这是我能得到的最接近的地方。

    public interface BaseEnum {
        public Month getMonth();
        public List<OtherEnum> getOtherEnumList();
    
        public static List<OtherEnum> getByMonth(Class<? extends BaseEnum> enumClass, final Month month) {
            for (final BaseEnum firstEnum : enumClass.getEnumConstants()) {
                if (month.equals(firstEnum.getMonth())) {
                    return firstEnum.getOtherEnumList();
                }
            }
            return Collections.emptyList();
        }
    }
    

    我们不能从枚举中取出枚举常量,除非使用枚举的具体名称,如FirstEnum.values(),或通过Class.getEnumConstants()。出于您的目的,我们希望能够像您所说的那样使用泛型并声明&lt;T extends Enum&lt;T&gt;&gt;,然后执行T.values()。由于类型擦除,这无法正常工作。

    因此调用者需要提供枚举类。好处是接口不需要是通用的。例如这样调用:

        List<OtherEnum> list = BaseEnum.getByMonth(FirstEnum.class, Month.MAY);
    

    我确信反射会是另一种选择。

    顺便说一句,如果我们愿意,我们也可以使用流操作来实现您的方法:

        public static List<OtherEnum> getByMonth(Class<? extends BaseEnum> enumClass, final Month month) {
            return Arrays.stream(enumClass.getEnumConstants())
                    .filter(e -> e.getMonth().equals(month))
                    .findAny()
                    .map(BaseEnum::getOtherEnumList)
                    .orElse(Collections.emptyList());
        }
    

    链接: Type Erasure in Java Explained | Baeldung

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多