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

时间:2009-07-30 20:34:35

标签: java serialization enums

今天一位同事遇到了一个有趣的问题,虽然我认为实际的,大局的答案是“我们遇到这个问题意味着我们做错了什么”,我想我会无论如何都要问这个。

鉴于以下内容:

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);
  }
}

在调用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(),是否可以获得对相应枚举类型对象的引用作为枚举?

2 个答案:

答案 0 :(得分:9)

编译错误告诉您Class<?>Class<? extends Enum>不同。尝试:

Enum<?> value1 =
        Enum.valueOf((Class<? extends Enum>) Class.forName(className), enumValue);

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

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);
}

当然,无论如何,你都会在“new EnumeratedThing(value1)”上收到原始类型警告。

答案 1 :(得分:1)

在调用方法之前,只需转换您创建的类, 这样它符合方法签名:

Class<?> c = Class.forName(className);
Class<? extends Enum> ce = (Class<? extends Enum>)c;
Enum<?> value1 = Enum.valueOf(ce, enumValue);

现在该类被视为Enum的子类。

备注:

  • 无论如何它是运行时正确的类,但编译器不知道
  • 为此发明了一个铸造:在编译时创建一个运行时已知的类型