接受任何枚举并返回所有属性的方法

时间:2017-08-15 16:56:36

标签: java enums

我有以下枚举,我想创建一个接受Enum对象的方法,并返回该枚举属性的逗号分隔列表。因此,对于以下枚举,我的方法将接受它作为参数,返回字符串“1,2”

 public class typeEnum {
      public enum validTypes{
           TYPE1("1"),
           TYPE2("2");

      private String value;

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

    public String getValue() {
        return value;
    }

    public static boolean contains(String type) {
        for (validTypes msgType : validTypes.values()) {
            if (msgType.value.equals(type)) {
                return true;
            }
        }
        return false;
    }
  }
 }

我的预期方法如下:

 public static <E extends Enum<E>, S extends String> String enumPropsToString(E enumClazz, S value) {
 return ....
}

2 个答案:

答案 0 :(得分:2)

枚举可以实现接口:

public interface ValuedEnum {
  public String getValue();
}

public class SomeEnum implements ValuedEnum {
  //your body from above
}

然后,您可以使用&#34;交叉类型&#34;在您的方法签名中:

public <T extends Enum<T> & ValuedEnum> String propsToString (Class<T> enumClass) {
    Arrays.stream(enumClass.getEnumConstants()).map(e -> e.getValue()).collect(Collectors.joining(", "));
}

您也可以通过反思执行此操作 - 检查任意枚举的enumClass参数,找到您需要Method签名的getValue,然后反思性地调用它;但这种方式是类型安全的,而且非常简单,我强烈建议这样做。

阅读您的评论,如果您想允许任意属性,那么我建议您只使用Stream API:

public static <T> String propsToString (T[] values, Function<T, String> extractor) {
    return Arrays.stream(values).map(extractor).collect(Collectors.joining(", "));
}

可以像这样调用:

propsToString(MyEnum.values(), MyEnum::name);

答案 1 :(得分:1)

以下是您需要的方法:

private static <E extends Enum<E>> String enumValues(Class<E> clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    Method m = clazz.getMethod("values");
    Object[] values = (Object[])m.invoke(null);
    Method f = clazz.getMethod("getValue");
    StringBuilder sb = new StringBuilder(f.invoke(values[0]).toString());
    for (int i = 1 ; i < values.length ; i++) {
        sb.append(", ");
        sb.append(f.invoke(values[i]).toString());
    }
    return sb.toString();
}

用法:

enum MyEnum {
    X("A"), Y("B");

    public String value;

    MyEnum(String value) {
        this.value = value;
    }
}
// ...
System.out.println(enumValues(MyEnum.class));
// prints "A, B"

解释这是如何工作的:

您应该传递Class<E>,而不是将枚举实例传递给方法。这样可以更容易地反映其中的内容。它还使得调用方法变得更容易,因为您不需要创建新的枚举实例。

首先,我们需要获取传入的枚举类的所有值。为此,我们从枚举类中获取方法values并调用它。在这里,我将所有值存储在名为values的变量中。

然后我从枚举类中获得了方法getValue。在评论中,您说当枚举没有value字段时,不应将其传递给此方法。我假设你的意思是你不关心不存在的value字段而你信任调用者。这就是为什么我这里没有做任何检查。

之后我使用字符串构建器和for循环来连接每个枚举值的value值。

很久很久!

请注意,此方法极不安全。您可能应该使用其他答案所说的接口。但是,嘿,这很有趣,你似乎有信心你不会在那里传递任何无效的东西。 :)