如果我在编译时不知道该类,如何获取枚举的值?

发布于 2024-10-21 00:42:21 字数 681 浏览 1 评论 0原文

我正在尝试执行以下操作:

Class<?> cls = unknownClass;
if(cls.isEnum()){
    @SuppressWarnings("unchecked")
    Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) cls;
    Object val = Enum.valueOf(enumClass, "NAME1");
}

但出现以下错误:

Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is 
not applicable for the arguments (Class<capture#5-of ? extends Enum<?>>, String). 
The inferred type capture#5-of ? extends Enum<?> is not a valid substitute for 
the bounded parameter <T extends Enum<T>>   

有人可以告诉我我做错了什么吗?

I'm trying to do the following:

Class<?> cls = unknownClass;
if(cls.isEnum()){
    @SuppressWarnings("unchecked")
    Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) cls;
    Object val = Enum.valueOf(enumClass, "NAME1");
}

But I get the following error:

Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is 
not applicable for the arguments (Class<capture#5-of ? extends Enum<?>>, String). 
The inferred type capture#5-of ? extends Enum<?> is not a valid substitute for 
the bounded parameter <T extends Enum<T>>   

Can someone tell me what I am doing wrong?

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

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

发布评论

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

评论(5

坚持沉默 2024-10-28 00:42:21

鉴于演员阵容不会真正检查事情,我会选择完全原始的版本:

if (cls.isEnum()){
    @SuppressWarnings("unchecked")
    Object val = Enum.valueOf(cls, "NAME1");
}

这似乎有效。完整示例:

public class Test
{
    enum Foo
    {
        BAR, BAZ
    }


    public static void main(String[] args)
    {
        @SuppressWarnings("rawtypes")
        Class cls = Foo.class;

        if (cls.isEnum())
        {        
            @SuppressWarnings("unchecked")
            Object value = Enum.valueOf(cls, "BAR");
            System.out.println(value);
        }
    }
}

Given that the cast won't really be checking things, I'd go with the completely raw version:

if (cls.isEnum()){
    @SuppressWarnings("unchecked")
    Object val = Enum.valueOf(cls, "NAME1");
}

That seems to work. Complete example:

public class Test
{
    enum Foo
    {
        BAR, BAZ
    }


    public static void main(String[] args)
    {
        @SuppressWarnings("rawtypes")
        Class cls = Foo.class;

        if (cls.isEnum())
        {        
            @SuppressWarnings("unchecked")
            Object value = Enum.valueOf(cls, "BAR");
            System.out.println(value);
        }
    }
}
神也荒唐 2024-10-28 00:42:21

问题是你有两个 ? 并且它们可能不同但必须相同。

您要么必须使用非泛型或声明泛型类型,例如

public static <T extends Enum<T>> T val(Class<T> cls) {
    if(cls.isEnum()) { // is redundant when the compiler checks this.
        @SuppressWarnings("unchecked")
        Class<T> enumClass = (Class<T>) cls;
        T val = Enum.valueOf(enumClass, "NAME1");
        return val;
    }
    return null;
}

但是,调用此方法也有点噩梦。 ;)

The problem is that you have two ? and they could be different and they have to be the same.

You either have to use a non generic of declare a generic type like

public static <T extends Enum<T>> T val(Class<T> cls) {
    if(cls.isEnum()) { // is redundant when the compiler checks this.
        @SuppressWarnings("unchecked")
        Class<T> enumClass = (Class<T>) cls;
        T val = Enum.valueOf(enumClass, "NAME1");
        return val;
    }
    return null;
}

However, calling this method is a bit of a nightmare as well. ;)

深巷少女 2024-10-28 00:42:21

Class.getEnumConstants 将给出所有枚举,然后您可以找到您感兴趣的枚举。

修改 Jon 的代码:

public class Test {
    private enum Foo {
        BAR, BAZ
    } 

    public static void main(String[] args) {
        Class<?> cls = Foo.class;

        if (cls.isEnum()) { 
            for (Object constant : cls.getEnumConstants()) { 
                Enum<?> enumConstant = (Enum<?>)constant;
                if (enumConstant.name().equals("BAR")) {
                    System.out.println(constant);
                    break;
                }
            }
        }
    }
}

在 Java SE 8 中,您可能能够使用 lambda 做一些巧妙的事情,并且抽象的控制流。

注意:

  • 反射几乎总是一个非常糟糕的主意。
  • 不需要未经检查的警告或抑制这些有效警告。
  • 不需要原始类型(无论拼写和语义)警告或抑制这些有效警告。
  • 无需毫无根据的咆哮。
  • 无需否决此答案。

Class.getEnumConstants will give all the enums, which you can then find the one you are interested in.

Modifying Jon's code:

public class Test {
    private enum Foo {
        BAR, BAZ
    } 

    public static void main(String[] args) {
        Class<?> cls = Foo.class;

        if (cls.isEnum()) { 
            for (Object constant : cls.getEnumConstants()) { 
                Enum<?> enumConstant = (Enum<?>)constant;
                if (enumConstant.name().equals("BAR")) {
                    System.out.println(constant);
                    break;
                }
            }
        }
    }
}

In Java SE 8, you'll possibly be able do something clever with a lambda and abstracted control flow.

Note:

  • Reflection is almost always a really bad idea.
  • No need for unchecked warning or suppression of those valid warnings.
  • No need for rawtypes (which ever spelling and semantics) warning or suppression of those valid warnings.
  • No need for an unfounded rant.
  • No need to downvote this answer.
み青杉依旧 2024-10-28 00:42:21

使用原始类型很好。虽然 Java 不愿意添加原始类型,但事实证明,除了向后兼容性问题之外,它是必要且不可或缺的。

如果没有原始类型,为了以理论上完美的方式解决问题,Java 必须变得更加复杂。它可能需要一个类型变量变量。到那时,代码就不再是为了取悦人类,而是为了取悦机器。 (我们可能已经到了这一点,考虑到所有无法理解的泛型代码)

Using raw type is good. While Java was reluctant to add raw type, it has been proven to be necessary and indispensable, beyond backward compatibility issues.

Without raw types, to solve your problem in a theoretically perfect way, Java has to be way more complicated. It probably needs a type-variable-variable. At that point, the code is no longer to please the humans, it is to please the machines. (We are probably already at this point, considering all the generics code that are impossible to understand)

时光倒影 2024-10-28 00:42:21
    class EnumValues<P extends Enum<P>>
    {
        public static <P extends Enum<P>> P [] getValues( Class<P> keyType)
        {
            return keyType.getEnumConstants();
        }
    }

用法:

    Class cls = Thread.State.class;
    for( Enum en : EnumValues.getValues( cls)) 
        System.out.println( en.name()); 
    class EnumValues<P extends Enum<P>>
    {
        public static <P extends Enum<P>> P [] getValues( Class<P> keyType)
        {
            return keyType.getEnumConstants();
        }
    }

Usage:

    Class cls = Thread.State.class;
    for( Enum en : EnumValues.getValues( cls)) 
        System.out.println( en.name()); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文