【问题标题】:Generic enum iterator java通用枚举迭代器java
【发布时间】:2017-10-11 11:27:53
【问题描述】:

我的枚举

public enum ExamStausEnum {

    RESULTAWAITED("Result Awaiting"), 
    PASSED("Passed"), 
    FAILED("Failed");

    private String value;

    ExamStausEnum(String value) {
        this.value = value;
    }

    @JsonValue
    public String getValue() {
        return value;
    }
}

通用迭代器枚举

static <E extends Enum <E>> void foo(Class<E> elemType) {
    for (E e : java.util.EnumSet.allOf(elemType)) {
        System.out.println(e);
    }
}

结果:

RESULTAWAITED
PASSED
FAILED

如何打印构造函数值?

Result Awaiting
Passed
Failed

【问题讨论】:

  • 你的意思是System.out.println(e.getValue())
  • @khelwood,但这对所有枚举都是通用的,getValue 是针对这个名为 ExamStausEnum 的枚举
  • 你能在你的枚举上覆盖toString()吗?
  • 一般情况下你不能这样做。如果您有几个带有值字段的枚举,则可以使用反射获取该字段。
  • @khelwood 是的!想要同样的结果

标签: java generics enums java-8


【解决方案1】:

不可避免地要添加另一个参数来抽象getValue()调用:

static <E extends Enum <E>> void foo(Class<E> elemType, Function<? super E, ?> f) {
    for(E e : java.util.EnumSet.allOf(elemType)) {
        System.out.println(f.apply(e));
    }
}

然后,您可以为不一定具有该方法的任意 enum 类型调用它,例如

foo(Thread.State.class, Object::toString);

或者对于您的特定enum 具有该方法:

foo(ExamStausEnum.class, ExamStausEnum::getValue);

更多的用例是可能的:

foo(Thread.State.class, Enum::name);

foo(ExamStausEnum.class, Enum::ordinal);

当然,您也可以让您的ExamStausEnum 类型覆盖toString() 方法,从而无需foo 调用getValue() 方法。

【讨论】:

    【解决方案2】:

    更先进的方法是创建一个接口,声明由所有枚举实现的getValue() 方法。

    interface EnumWithValue{
       @JsonValue
       String getValue();
    }
    
    public enum ExamStausEnum implements EnumWithValue {
    
        RESULTAWAITED("Result Awaiting"), 
        PASSED("Passed"), 
        FAILED("Failed");
    
        private String value;
    
        ExamStausEnum(String value) {
            this.value = value;
        }
    
        @Override
        public String getValue() {
            return value;
        }
    }
    

    然后你可以将你的枚举投射到foo:

    static <E extends Enum <E>> void foo(Class<E> elemType) {
        for (E e : java.util.EnumSet.allOf(elemType)) {
            System.out.println(((EnumWithValue)e).getValue());
        }
    }
    

    【讨论】:

    • 我宁愿将声明更改为&lt;E extends Enum&lt;E&gt;&amp;EnumWithValue&gt; void foo(Class&lt;E&gt; elemType),而不是插入可能在运行时失败的类型转换。
    • 我认为您的建议在相同情况下也会在运行时失败...
    • 当您使用声明 &lt;E extends Enum&lt;E&gt;&amp;EnumWithValue&gt; 时,编译器将拒绝未实现 EnumWithValue 的枚举的 Class 对象。使用您的代码,您在传递错误类型时甚至不会收到警告。
    猜你喜欢
    • 2012-06-08
    • 1970-01-01
    • 2012-12-14
    • 2010-10-31
    • 1970-01-01
    • 2014-06-09
    • 2011-02-07
    • 2016-10-22
    • 1970-01-01
    相关资源
    最近更新 更多