Enum.valueOf(ClassenumType, String name) 问题
我试图解决与动态枚举查找相关的编译错误(“绑定不匹配:...”)。
基本上我想实现这样的目标:
String enumName = whatever.getEnumName();
Class<? extends Enum<?>> enumClass = whatever.getEnumClass();
Enum<?> enumValue = Enum.valueOf(enumClass, enumName);
无论我做什么,我总是会遇到编译错误。老实说,泛型和枚举对我来说相当令人难以置信......
我在这里做错了什么?
I am trying to get around a compile error ("Bound mismatch: ...") relating to dynamic enum lookup.
Basically I want to achieve something like this:
String enumName = whatever.getEnumName();
Class<? extends Enum<?>> enumClass = whatever.getEnumClass();
Enum<?> enumValue = Enum.valueOf(enumClass, enumName);
Whatever I do, I always end up with that compile error. Honestly, generics and enums are quite mindboggling to me...
What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为除非您可以访问类型变量(通过类型或方法签名),否则它不会完全像这样工作。问题在于
Enum.valueOf
的方法签名:没有类型变量就无法获取 T。但是,如果您愿意抑制某些编译器警告,则可以这样做:
输出:
I think it won't work exactly like this unless you have access to a type variable (through either a type or method signature). The problem is the method signature of
Enum.valueOf
:There's no way to get a T without a type variable. But you can do it like this if you're willing to suppress some compiler warnings:
Output:
问题出在
Class>
。我们想要E extends Enum
,但我们无法得到它,因为我们有两个不同的通配符。因此,我们需要引入一个通用参数,可以通过调用方法来引入:
但是反射很糟糕,而且很少是您想要的。不要这样做。
The problem is with
Class<? extends Enum<?>>
. We wantE extends Enum<E>
, but we can't get that because we have two distinct wildcards.So we need to introduce a generic parameter, possible introduced by calling a method:
But reflection is mucky and very rarely what you want. Don't do it.
实际上有一种替代方法:您可以使用 Class.getEnumConstants 并推出您自己的 Enum.valueOf 实现,该实现不存在相同的类型问题。缺点是你会得到一个通用的
Enum
- 但如果你知道你传入的类型,你无论如何都可以使用Enum.valueOf
。(请注意,如果没有这样的常量,我的版本将返回 null,而不是抛出 IllegalArgumentException,但这是一个微不足道的更改。
There's actually an alternate approach: you can use
Class.getEnumConstants
and roll your own implementation ofEnum.valueOf
that doesn't have the same type problems. The downside is you get back a genericEnum<?>
- but if you knew what type you had coming in, you would be able to useEnum.valueOf
anyway.(Note that my version returns
null
if there's no such constant rather than throwing anIllegalArgumentException
, but that's a trivial thing to change.感谢@Sbodd 的回答。我举了这个例子,添加了我们从标准 anEnum.valueOf("ELVIS") 中知道的异常,并以我们可以这样使用它的方式更改了通用方法参数:
方法:
Thx @Sbodd for the answer. I took this example, added the exception we know from the standard anEnum.valueOf("ELVIS") and changed the generic method args in a way that we can use it like this:
Method: