我可以在Java中运行时添加和删除枚举元素吗?
在运行时可以添加和删除Java中的枚举元素?
例如,我可以从文件中读取枚举的标签和构造函数参数吗?
@saua,这只是一个问题,它是否可以做出真正的兴趣。 我希望能有一些干净的方式来改变运行的字节码,也许使用BCEL或其他东西。 我也跟着这个问题,因为我意识到我不完全确定何时应该使用枚举。
我相当确信,如果我希望能够在运行时安全地更改内容,那么正确的答案就是使用一个确保唯一性而不是枚举的集合。
不,枚举应该是一个完整的静态枚举。
在编译时,你可能想要从另一个源文件生成你的枚举.java文件。 你甚至可以像这样创build一个.class文件。
在某些情况下,您可能需要一组标准值,但允许扩展。 通常的做法是为interface
提供一个interface
,并为标准值实现interface
。 当然,当你只有一个参考interface
时候,你就失去了switch
的能力。
在幕后,枚举是具有私有构造函数的POJO,以及一系列枚举types的公共静态最终值(参见这里的示例)。 事实上,直到Java5之前,以这种方式构build自己的枚举被认为是最佳实践,并且Java5引入了enum
关键字作为简写。 查看Enum <T>的来源以了解更多信息。
因此,用常量的公共静态最终数组编写自己的“TypeSafeEnum”应该没有问题,这些常量可以由构造函数读取或传递给它。
另外,自己动手,重写equals
, hashCode
和toString
,如果可能的话创build一个values
方法
问题是如何使用这样一个dynamic枚举…你不能从文件中读取值“PI = 3.14”来创buildenum MathConstants
,然后继续使用MathConstants.PI
无论你想要的地方…
我需要做这样的事(为了unit testing的目的),我碰到了这个 – EnumBuster: http : //www.javaspecialists.eu/archive/Issue161.html
它允许枚举值被添加,删除和恢复。
编辑 :我只是刚刚开始使用这个,发现有一些需要稍微改变的Java 1.5,我目前坚持:
- 添加数组copyOf静态帮助器方法(例如,采取这些1.6版本: http : //www.docjar.com/html/api/java/util/Arrays.java.html )
- 将EnumBuster.undoStack更改为Stack
<Memento>
- 在undo()中,将undoStack.poll()更改为undoStack.isEmpty()? null:undoStack.pop();
- stringVALUES_FIELD需要为“ENUM $ VALUES”为我已经尝试过的java 1.5枚举
在我年轻的职业生涯中,我遇到了这个问题。
我采取的方法是从外部保存枚举的值和名称,最终目标是能够编写尽可能接近语言枚举的代码。
我想我的解决scheme看起来像这样:
enum HatType { BASEBALL, BRIMLESS, INDIANA_JONES } HatType mine = HatType.BASEBALL; // prints "BASEBALL" System.out.println(mine.toString()); // prints true System.out.println(mine.equals(HatType.BASEBALL));
最后我得到了这样的结果:
// in a file somewhere: // 1 --> BASEBALL // 2 --> BRIMLESS // 3 --> INDIANA_JONES HatDynamicEnum hats = HatEnumRepository.retrieve(); HatEnumValue mine = hats.valueOf("BASEBALL"); // prints "BASEBALL" System.out.println(mine.toString()); // prints true System.out.println(mine.equals(hats.valueOf("BASEBALL"));
由于我的要求是必须在运行时向枚举中添加成员,所以我还实现了这个function:
hats.addEnum("BATTING_PRACTICE"); HatEnumRepository.storeEnum(hats); hats = HatEnumRepository.retrieve(); HatEnumValue justArrived = hats.valueOf("BATTING_PRACTICE"); // file now reads: // 1 --> BASEBALL // 2 --> BRIMLESS // 3 --> INDIANA_JONES // 4 --> BATTING_PRACTICE
我把它称为dynamic枚举“模式”,并且您阅读了原始devise 及其修订版 。
两者之间的区别在于修订版是在我开始注意OO和DDD之后devise的。 当我还在写名义上的程序性DDD时,我devise的第一个DDD在时间压力下不下于。
您可以在运行时从源代码加载Java类。 (使用JCI,BeanShell或JavaCompiler)
这将允许您根据需要更改Enum值。
注意:这不会改变任何引用这些枚举的类,所以这在现实中可能不是很有用。
您可以尝试将属性分配给要创build的ENUM,并通过使用加载的属性文件进行静态构造。 大破解,但它的作品:)