获取实现接口的通用枚举的值

Get values of generic enum that implements an interface

我有以下界面:

public interface GenericMethods {
  public String getString();
}

有了这个接口,我实现了这个枚举:

public enum SpecificEnum implements GenericMethods {
  A("NOT"), B("RELATED"), C("TEXT");

  SpecificEnum(String string) {
    this.string = string;
  }

  private String string;
  
  @Override
  public String getString() {
    return this.string;
  }
}

现在,我希望能够使用参数 SpecificEnum.class 调用一个函数,并能够对该参数调用 values() 函数,以及返回数组的接口方法元素。像这样:

class Main {
  public static void main(String[] args) {
    for (GenericMethods gm : getEnums(SpecificEnum.class)) {
      System.out.printf(gm.getString());
    }
  }

  public static T[]<T extends GenericMethods> getEnums(Class<T> enum1) {
    enum1.values();
  }
}

但是,经过大量搜索,我还没有遇到使用泛型和同时实现接口的枚举的情况。我也对泛型类型进行了很多思考,但我找不到能够在泛型枚举 class 上调用 values() 的正确语法。主要的 objective 是以相同的方式管理多个相关的枚举。

我怀疑您可能正在寻找类似的东西:

public static <T extends Enum<T> & GenericMethods> T[] getEnums(Class<T> enum1) {
    return enum1.getEnumConstants();
}

public static void main(String[] args) {
    for (GenericMethods gm : getEnums(SpecificEnum.class)) {
        System.out.println(gm.getString());
    }
}

结果:
(演示:https://ideone.com/v6on2p

NOT
RELATED
TEXT

变化:

  • <T extends GenericMethods> 移到 return 类型之前,因为只有泛型方法才能声明其泛型类型。
  • 将泛型类型修改为 <T extends Enum<T> & GenericMethods> 以强制 T 除了实现 GenericMethods 之外也是某些枚举的子类型
  • 使用 getEnumConstants() 而不是 values(),因为我们使用的是 Class,而不是 enum 类型。

Class 对象上调用 getEnumConstants()。正如 javadoc 所说:

Returns the elements of this enum class or null if this Class object does not represent an enum type.

你方法的签名也不对。写法如下:

public static <T extends GenericMethods> T[] getEnums(Class<T> enumClass) {
    return enumClass.getEnumConstants();
}

当然有可能returnnull,因为不能保证Class对象是枚举class。例如。与以下 class, getEnums(Foo.class) returns null:

public class Foo implements GenericMethods {
    @Override
    public String getString() {
        return "Boo!!";
    }
}

要确保 Class 是枚举 class,请将方法更改为:

public static <T extends Enum<T> & GenericMethods> T[] getEnums(Class<T> enumClass) {
    return enumClass.getEnumConstants();
}

测试

getEnums(Foo.class); // fails to compile
SpecificEnum[] enums = getEnums(SpecificEnum.class);
System.out.println(Arrays.toString(enums));

输出

[A, B, C]