【问题标题】:Calling Enum.values() on a generic type在泛型类型上调用 Enum.values()
【发布时间】:2017-07-26 03:24:08
【问题描述】:

目标是实现一个通用的枚举转换器。 我知道 Enum1Enum2 具有相同的值和相同的顺序。

我们的目标是实现这样的东西:(这行得通)

private static Enum1 translateEnum(Enum2 originalEnum) {
    return Enum1.values()[originalEnum.ordinal()];
}

但我有几个枚举,所以我想做一个通用方法:(这不起作用)

private static < T extends Enum<T>,G extends Enum<G>> T translateEnum(G originalEnum) {
    return T.values()[originalEnum.ordinal()];        
}

我的问题是在 T.values() 编译器告诉我:

类型 T 的方法 values() 未定义

你们知道我该如何解决这个问题吗?或者你们对我的问题有其他想法吗?

【问题讨论】:

  • 通过Class&lt;T&gt; clazz?尽管如此,这似乎并不是很有用。大多数系统已经包含这种东西。
  • @chrylis “大多数系统已经包含这种东西”是什么意思?
  • 如果Enum1Enum2确实有相同的值和相同的顺序,为什么会有两个?
  • 以防万一Enum1Enum2开始偏离,而不是“相同的值和相同的顺序”,最好按名称映射,所以偏离顺序是自动调整的,缺失值会抛出异常。这称为defensive programming
  • 那么我之前关于防御性编程的评论变得更加相关,因为您无法保证外部依赖项会在您没有注意到的情况下发生更改。

标签: java enums generic-programming


【解决方案1】:

执行此操作的常用方法是将目标class object(或目标类的对象)作为参数传递给函数,然后使用类对象中的方法来完成棘手的部分。对于枚举类,类对象有a method which returns the equivalent of Enum.values()。您可以使用它从目标类中获取枚举值:

public class Scratch {
    enum lower { a, b, c };
    enum upper { A, B, C };

    static <T extends Enum<T>> T translate(Enum<?> aFrom, Class<T> aTo) {
        return aTo.getEnumConstants()[aFrom.ordinal()];
    }

    public static void main(String[] args) {
        for (lower ll : lower.values()) {
            upper uu = translate(ll, upper.class);
            System.out.printf("Upper of '%s' is '%s'\n", ll, uu);
        }
        for (upper uu : upper.values()) {
            lower ll = translate(uu, lower.class);
            System.out.printf("Lower of '%s' is '%s'\n", uu, ll);
        }
    }
}

运行它会产生以下输出:

Upper of 'a' is 'A'
Upper of 'b' is 'B'
Upper of 'c' is 'C'
Lower of 'A' is 'a'
Lower of 'B' is 'b'
Lower of 'C' is 'c'

【讨论】:

    猜你喜欢
    • 2022-12-18
    • 2013-08-29
    • 2018-03-26
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多