如何处理 Java 中的泛型枚举?

发布于 2024-09-08 05:09:46 字数 1453 浏览 1 评论 0 原文

所以,我有一个抽象类,例如:

public abstract class AbstractParent <E extends Enum<E>> {...}

在 AbstractParent 内的非抽象方法中的某个位置,我想迭代 E 的值。这可能吗?

举一个更好的例子:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

编辑:

所以,感谢 mdma,这效果非常好:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        Type t = pt.getActualTypeArguments()[0];
        E[] enumValues = ((Class<E>)t).getEnumConstants();
        // enumValues is now an iterable array of the values inside Index
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

感谢 LOADS to mdma,你应该得到比我能给的更多的积分。

So, I have an abstract class like:

public abstract class AbstractParent <E extends Enum<E>> {...}

Somewhere in a non-abstract method inside AbstractParent, I would like to iterate over the values of E. Is this possible?

For a better example:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

EDIT:

So, thanks to mdma, this works awesomely:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        Type t = pt.getActualTypeArguments()[0];
        E[] enumValues = ((Class<E>)t).getEnumConstants();
        // enumValues is now an iterable array of the values inside Index
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

Thanks LOADS to mdma, you deserve more points than I can give.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

腻橙味 2024-09-15 05:09:46

EDIT2:超类和接口上的泛型不会被删除。您可以在运行时获取泛型类型并使用它来获取枚举值。请参阅 Class.getGenericSuperclass。这将使您不必在构造函数中传递值或类。

原来的:
你不能用泛型来做到这一点。但是,如果您还传递相应的类,例如像

AbstractParent(Class<E> enumClass)
{
   this.enumClass = enumClass;
}

“Then”这样的构造函数,您可以使用它通过编辑获取相应的枚举值

public E[] getValues()
{
    return this.enumClass.getEnumConstants();
}

:尽管客户不是专业程序员,但编译器将确保传递正确的类。您还可以通过提供示例和单元测试来清楚地说明用法。

您还可以让构造函数获取 Enum 的实际值,并从中派生类。这可能更容易使用,因为参数是 E 而不是更“可怕”的 Class

例如

AbstractParent(E enumValue)
{
   this.enumClass = enumValue.getClass();
}

EDIT2: Generics on superclasses and interfaces are not erased. You can get the generic type at runtime and use that to fetch the enum values. See Class.getGenericSuperclass. This will save you having to pass the value or a class in the constructor.

Original:
You cannot do this with generics. However, if you pass in the corresponding class also, e.g. a constructor like

AbstractParent(Class<E> enumClass)
{
   this.enumClass = enumClass;
}

Then you can use that to fetch the corresponding enum values via

public E[] getValues()
{
    return this.enumClass.getEnumConstants();
}

EDIT: Although the clients are not professional programmers, the compiler will ensure the correct class is passed. You can also make the usage clear by providing examples, and unit tests.

You could also have the constructor take and actual value of the Enum, and derive the class from that. This might be simpler to use, since the parameter is then an E rather than the more "scary" Class<E>.

E.g.

AbstractParent(E enumValue)
{
   this.enumClass = enumValue.getClass();
}
趁微风不噪 2024-09-15 05:09:46

由于泛型在运行时被删除,因此唯一可能的方法是使用一个需要 Class 参数的构造函数,然后您可以在该参数上调用 getEnumConstants()

Since generics are erased at runtime, the only way this is possible is by having a constructor that requires a Class<E> parameter on which you can then call getEnumConstants().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文