Java Enums:从文件中反序列化任意枚举

Sbo*_*odd 4 java enums serialization

今天一位同事遇到了一个有趣的问题,虽然我认为实际的,大局的答案是"我们遇到这个问题意味着我们做错了什么",我想我还是会问这个问题.

鉴于以下内容:

public class CrazyEnumTest {

  public class EnumeratedThing<T extends Enum<T>> {
    public T myValue;

    public EnumeratedThing(T value) {
      myValue = value;
    }
  }

  public static void main (String[] args) {
    String className = args[0];
    String enumValue = args[1];

    Enum<?> value1 = Enum.valueOf(Class.forName(className), enumValue);
    EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
  }
}
Run Code Online (Sandbox Code Playgroud)

我在调用Enum.valueOf时遇到以下编译错误:

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

所以,我的问题是:如果只给出枚举类型名称的String表示以及其中一个值的.name(),是否可以获得对相应枚举类型对象的引用作为枚举?

Mic*_*ers 9

编译错误告诉你这Class<?>不一样Class<? extends Enum>.尝试:

Enum<?> value1 =
        Enum.valueOf((Class<? extends Enum>) Class.forName(className), enumValue);
Run Code Online (Sandbox Code Playgroud)

请注意,您将获得未经检查的强制转换警告,因此请确保className实际上代表枚举.您可以通过调用对象isEnum()上的方法来检查Class,如下所示:

Class<?> enumClass = Class.forName(className);
if (enumClass.isEnum()) {
    @SuppressWarnings("unchecked") // we just checked it, so it had better work
    Enum<?> value1 = Enum.valueOf((Class<? extends Enum>) enumClass, enumValue);
    EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
}
Run Code Online (Sandbox Code Playgroud)

当然,new EnumeratedThing(value1)无论如何,你都会在" " 上获得原始类型警告.