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

cam*_*mil 19 java generics reflection enums

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

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

但是我收到以下错误:

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>>   
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 20

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

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

这似乎有效.完整的例子:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*rey 7

问题是你有两个?,他们可能是不同的,他们必须是相同的.

你要么必须使用非泛型声明泛型类似的

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;
}
Run Code Online (Sandbox Code Playgroud)

但是,调用这种方法也是一个噩梦.;)


Tom*_*ine 5

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;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Java SE 8 中,您可能能够使用 lambda 和抽象控制流做一些聪明的事情。

笔记:

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