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

发布于 2024-07-29 22:34:26 字数 924 浏览 4 评论 0 原文

今天,一位同事遇到了一个有趣的问题,虽然我认为实际的、宏观的答案是“我们遇到这个问题的事实意味着我们做错了什么”,但我想我还是会问这个。

鉴于以下情况:

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, String) of type Enum; 不适用于参数(Class, String)。 推断类型 capture#1-of ? 不是有界参数 > 的有效替代

所以,我的问题是:仅给出枚举类型名称的 String 表示形式以及 .name 是否可以() 其值之一,获取对相应枚举类型对象的引用作为 Enum?

A co-worker ran into an interesting issue today, and while I think the actual, big-picture answer is "the fact that we're having this problem means we're doing something wrong", I figured I'd ask this anyway.

Given the following:

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

I get the following compile error on the call to 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>>

So, my question is: is it possible to, given only the String representation of a enumerated type name as well as the .name() of one of its values, get a reference to the corresponding enumerated type object as an Enum?

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

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

发布评论

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

评论(2

过去的过去 2024-08-05 22:34:26

编译错误告诉您 ClassClass。 尝试:

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

请注意,您将收到未经检查的强制转换警告,因此请确保 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);
}

当然,您会在“new EnumeratedThing(value1)<”上收到原始类型警告/代码>”无论如何。

The compile error is telling you that Class<?> is not the same as Class<? extends Enum>. Try:

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

Note that you'll get an unchecked cast warning, so make sure that className actually does represent an enum. You could check by calling the isEnum() method on the Class object, like this:

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

Of course, you'll get a raw type warning on "new EnumeratedThing(value1)" anyway.

今天小雨转甜 2024-08-05 22:34:26

只需在调用该方法之前强制转换您创建的类,
以便它符合方法签名:

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

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

备注:

  • 无论如何,它在运行时是正确的类,但编译器不知道
  • 为此发明了强制转换:使运行时已知的类型在编译时已知

Just cast the class you create before you call the method,
so that it conforms to the method signature :

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

Now the class is seen as a subclass of Enum.

Remark :

  • it was anyway the correct class at runtime, but the compiler didn't know
  • casting was invented for that : making a runtime-known type known at compile-time
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文