首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >以多态方式将Java枚举值转换为字符串列表

以多态方式将Java枚举值转换为字符串列表
EN

Stack Overflow用户
提问于 2009-08-11 15:45:16
回答 8查看 32.1K关注 0票数 17

我有几个帮助器方法,可以将枚举值转换为适合通过HTML <select>元素显示的字符串列表。我想知道是否有可能将这些重构为一个单一的多态方法。

这是我现有方法之一的一个示例:

代码语言:javascript
复制
/**
 * Gets the list of available colours.
 * 
 * @return the list of available colours
 */
public static List<String> getColours() {
  List<String> colours = new ArrayList<String>();

  for (Colour colour : Colour.values()) {
    colours.add(colour.getDisplayValue());  
  }

  return colours;
}

我对Java泛型仍然很陌生,所以我不确定如何将泛型枚举传递给该方法并在for循环中使用它。

注意,我知道有问题的枚举都会有那个getDisplayValue方法,但不幸的是,它们没有共享一个定义它的公共类型(我也不能介绍一个),所以我猜它将不得不被反射地访问...?

提前感谢您的帮助。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-08-11 16:06:02

使用Class#getEnumConstants()很简单:

代码语言:javascript
复制
static <T extends Enum<T>> List<String> toStringList(Class<T> clz) {
     try {
        List<String> res = new LinkedList<String>();
        Method getDisplayValue = clz.getMethod("getDisplayValue");

        for (Object e : clz.getEnumConstants()) {
            res.add((String) getDisplayValue.invoke(e));

        }

        return res;
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

这并不是完全的类型安全,因为你可以有一个没有getDisplayValue方法的枚举。

票数 17
EN

Stack Overflow用户

发布于 2009-08-11 16:02:22

您可以将此方法放在某个实用程序类中:

代码语言:javascript
复制
public static <T extends Enum<T>> List<String> getDisplayValues(Class<T> enumClass) {
    try {
        T[] items = enumClass.getEnumConstants();
        Method accessor = enumClass.getMethod("getDisplayValue");

        ArrayList<String> names = new ArrayList<String>(items.length);
        for (T item : items)
            names.add(accessor.invoke(item).toString()));

        return names;
    } catch (NoSuchMethodException ex) {
        // Didn't actually implement getDisplayValue().
    } catch (InvocationTargetException ex) {
        // getDisplayValue() threw an exception.
    }
}

来源:Examining Enums

票数 10
EN

Stack Overflow用户

发布于 2009-08-11 16:34:01

这种方法避免了反射:

代码语言:javascript
复制
  public static interface Displayer<T> {
    String displayName(T t);
  }

  public static <T> List<String> getDisplayNames(Iterable<? extends T> stuff,
      Displayer<T> displayer) {
    List<String> list = new ArrayList<String>();
    for (T t : stuff) {
      list.add(displayer.displayName(t));
    }
    return list;
  }

对于您想要显示的所有内容,...but确实需要单独的类型:

代码语言:javascript
复制
  enum Foo {
    BAR("BAR"), BAZ("BAZ");
    private final String displayName;

    private Foo(String displayName) {
      this.displayName = displayName;
    }

    public String getDisplayName() {
      return displayName;
    }
  }

  public static void main(String[] args) {
    Displayer<Foo> fooDisplayer = new Displayer<Foo>() {
      public String displayName(Foo foo) {
        return foo.getDisplayName();
      }
    };

    System.out.println(getDisplayNames(Arrays.asList(Foo.BAR, Foo.BAZ),
        fooDisplayer));
  }

在这种情况下,使用匿名类型,但它可以是无状态单例或诸如此类的类型。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1261233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档