【问题标题】:Get values of generic enum that implements an interface获取实现接口的通用枚举的值
【发布时间】:2020-10-29 16:52:20
【问题描述】:

我有如下界面:

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();
  }
}

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

【问题讨论】:

    标签: java generics enums interface


    【解决方案1】:

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

    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
    

    变化:

    • &lt;T extends GenericMethods&gt; 移到返回类型之前,因为只有泛型方法才能声明其泛型类型。
    • 将泛型类型修改为&lt;T extends Enum&lt;T&gt; &amp; GenericMethods&gt;,以强制 T 成为除实现 GenericMethods 之外的某些 Enum 的子类型
    • 使用getEnumConstants() 而不是values(),因为我们使用的是Class,而不是enum 类型。

    【讨论】:

    • 谢谢,按预期工作。作为一个后续问题,由于泛型类型声明的限制,没有任何方法可以将泛型类存储在不相关的枚举属性中,对吗?
    • @Phaellow 抱歉,但我不确定您所说的“存储通用类”是什么意思。现在我怀疑你可能正在寻找一种方法来创建Class,它代表例如List&lt;Integer&gt;(因为我们不能通过像List&lt;Integer&gt;.class 这样的代码来创建它,因为它不会编译)。如果是这种情况,那么您可能会对此感兴趣:Google Gson - deserialize list<class> object? (generic type) - 特别是Type listType = new TypeToken&lt;ArrayList&lt;YourClass&gt;&gt;(){}.getType();
    • 对不起,如果我不清楚,我的意思是有一个特定的枚举,里面有一个类型为Class&lt;T&gt; 的字段,比如private Class&lt;T&gt; clazz;,其中 T 是我们一直在谈论的泛型。我很确定枚举不允许类型参数定义,但可能有一种我不知道的解决方法。
    • @Phaellow 然后不,对不起,但我也不知道任何解决方法。但仅仅因为我不知道解决方案并不意味着没有解决方案,所以也许可以考虑提出单独的问题(只需在其中解释您需要该机制以避免XY problem的目的)。
    【解决方案2】:

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

    如果此 Class 对象不表示枚举类型,则返回此枚举类的元素或 null

    您的方法的签名也是错误的。写法如下:

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

    当然,它可能返回null,因为不能保证Class 对象是一个枚举类。例如。对于以下类,getEnums(Foo.class) 返回null

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

    要确保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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多