java枚举可以实例化吗,Java:使用reflection实例化枚举

这篇博客探讨了如何使用Java的反射API在运行时根据文本文件内容动态实例化枚举类型。作者展示了尝试通过Field对象设置枚举值的过程,并提出了在不预先知道枚举类型的情况下实例化枚举的解决方案。讨论包括错误处理、强制类型转换以及使用`Enum.valueOf()`方法。还提到了一个更高效的方法,即在枚举中创建一个静态映射来从字符串直接获取枚举实例。

Java:使用reflection实例化枚举

假设你有一个文本文件,如:

my_setting = ON some_method = METHOD_A verbosity = DEBUG ...

您希望相应地更新相应的对象:

Setting my_setting = ON; Method some_method = METHOD_A; Verbosity verbosity = DEBUG; ...

在哪里都是不同种类的枚举。

我想有一个通用的方式来实例化枚举值。 也就是说,在运行时使用reflection,而不用事先知道对象的枚举types。

我会想像这样的事情:

for (ConfigLine line : lines) { String[] tokens = line.string.split("=", 2); String name = tokens[0].trim(); String value = tokens[1].trim(); try { Field field = this.getClass().getDeclaredField(name); if(field.getType().isEnum()) { // doesn't work (cannot convert String to enum) field.set(this, value); // invalid code (some strange generics issue) field.set(this, Enum.valueOf(field.getType().getClass(), value)); } else { /*...*/ } } catch //... }

问题是:应该有什么呢? 是否有可能实例化一个未知的枚举给它的string表示?

field.set(this, Enum.valueOf((Class) field.getType(), value));

getType() getClass()之后的getClass()不应该被调用 – 它返回一个Class实例的Class

您可以强制Class ,以避免generics问题,因为您已经知道Class是一个enum

你有一个额外的getClass调用,你必须施放(每个Bozho更具体的施放):

field.set(test, Enum.valueOf((Class) field.getType(), value));

没有铸造的替代解决scheme

try { Method valueOf = field.getType().getMethod("valueOf", String.class); Object value = valueOf.invoke(null, param); field.set(test, value); } catch ( ReflectiveOperationException e) { // handle error here }

你可以编码你的枚举类似的这个:

public enum Setting { ON("ON"),OFF("OFF"); private final String setting; private static final Map stringToEnum = new ConcurrentHashMap(); static { for (Setting set: values()){ stringToEnum.put(set.setting, set); } } private Setting(String setting) { this.setting = setting; } public String toString(){ return this.setting; } public static RequestStatus fromString(String setting){ return stringToEnum.get(setting); } }

然后,你可以很容易地创build从string的枚举没有reflection:

Setting my_settings = Setting.fromString("ON");

这个解决scheme不是来自我自己。 我从其他地方读了它,但我不记得来源。

接受的答案会导致警告,因为它使用原始typesEnum而不是Enum >。

为了解决这个问题,你需要使用这样一个通用的方法:

@SuppressWarnings("unchecked") private > T createEnumInstance(String name, Type type) { return Enum.valueOf((Class) type, name); }

像这样调用它:

Enum> enum = createEnumInstance(name, field.getType()); field.set(this, enum);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值