我可以在Java中运行时添加和删除枚举元素吗?

在运行时可以添加和删除Java中的枚举元素?

例如,我可以从文件中读取枚举的标签和构造函数参数吗?


@saua,这只是一个问题,它是否可以做出真正的兴趣。 我希望能有一些干净的方式来改变运行的字节码,也许使用BCEL或其他东西。 我也跟着这个问题,因为我意识到我不完全确定何时应该使用枚举。

我相当确信,如果我希望能够在运行时安全地更改内容,那么正确的答案就是使用一个确保唯一性而不是枚举的集合。

不,枚举应该是一个完整的静态枚举。

在编译时,你可能想要从另一个源文件生成你的枚举.java文件。 你甚至可以像这样创build一个.class文件。

在某些情况下,您可能需要一组标准值,但允许扩展。 通常的做法是为interface提供一个interface ,并为标准值实现interface 。 当然,当你只有一个参考interface时候,你就失去了switch的能力。

在幕后,枚举是具有私有构造函数的POJO,以及一系列枚举types的公共静态最终值(参见这里的示例)。 事实上,直到Java5之前,以这种方式构build自己的枚举被认为是最佳实践,并且Java5引入了enum关键字作为简写。 查看Enum <T>的来源以了解更多信息。

因此,用常量的公共静态最终数组编写自己的“TypeSafeEnum”应该没有问题,这些常量可以由构造函数读取或传递给它。

另外,自己动手,重写equalshashCodetoString ,如果可能的话创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,并通过使用加载的属性文件进行静态构造。 大破解,但它的作品:)