我正在使用Java 6.
假设我有一个文件availableFruits.txt
APPLE
ORANGE
BANANA
假设我想要一个包含FruitType
中列出的值的枚举availableFruits.txt
,我能够这样做吗?
答案 0 :(得分:3)
你不能在执行时填充枚举类型,不能 - 至少,不能没有像BCEL这样的东西,或者通过调用Java编译器。
当然,您可以编写代码来创建Java源文件,并在构建应用程序时构建它,如果之后不需要更改它。
否则,我只是创建一个包装类,它能够获取一组已知值并重用它们。当然,你需要做的确切取决于你想要如何使用枚举。
答案 1 :(得分:3)
Enum的意思是在编译时使用它。 如果您在编译时不知道您的Enum有什么值,那么它不是Enum它是一个集合。
如果你知道并且你只想根据文本文件中的值创建一个类文件,那么可以通过读取txt然后生成源代码来实现。
答案 2 :(得分:1)
通过编写自己的ClassLoader
子类,在字节数组中为枚举创建字节码,并使用defineClass
,我希望它是可能的。很难,也许,但可能。我希望一旦你知道枚举的字节序列,从JVM spec中的信息自定义生成它并不困难。
现在,这是否是一个好主意......好吧,我怀疑只是在极少数边缘情况下。 (我想不出一个;我的意思是,创建它之后,你必须生成使用它的代码,对吗?)否则,你可能会更好地使用{{3或类似的。
答案 3 :(得分:0)
不,除非您从文本文件生成枚举源文件。
答案 4 :(得分:0)
正如其他人所说 - 不。这是不可能的。最好的方法是使用注册表模式。读入值,将它们存储在某种可查询的映射中。有点像Enum。
答案 5 :(得分:0)
正如大家所指出的那样,这是不可能的。但是,您可以创建一个Map,其中地图的关键字是您从文件中读取的值(APPLE,ORANGE,BANANA)和?将是一个相关的值(例如int)。
当然,这样你基本上可以在没有类型安全的情况下实现相同的目标。
int i = fruitsMap.get("BANANA") // get the assoicated value
答案 6 :(得分:0)
您可以使用动态生成的代码。例如使用编译器API。我已经为该API编写了一个包装器,因此您可以在内存中编译类。请参阅下面的代码。
你遇到的问题是它不是很有用,因为你不能使用这些值,除了你的枚举编译后编译的类。你可以使用Enum.valueOf()等。但很多枚举值都会丢失。
正如其他人所建议的那样,使用Map会更简单并获得相同的好处。如果你有一个库必须通过一个枚举,我只会使用枚举。 (或计划更多生成的代码)
public static Class generateEnum(String className, List<String> enums) {
StringBuilder code = new StringBuilder();
code.append("package enums; public enum enums." + className + " {\n");
for (String s : enums)
code.append("\t"+s+",\n");
code.append("}");
return CompilerUtils.CACHED_COMPILER
.loadFromJava("enums."+className, code.toString());
}
我发现对文本生成代码有用的一件事是,您可以将其写入文件并在运行时调试它。 (该库支持此功能)如果生成字节码,则更难调试。
该库名为Essence JCF。 (并且它不需要自定义类加载器)
答案 7 :(得分:0)
你会如何用像JavaScript这样的动态语言来做这件事:它只是带有一个值的字符串:“APPLE”,“ORANGE”,“BANANA”。
Java类型(类,接口,枚举)仅存在于编译器进行一些优化,类型检查,使重构成为可能等等。在运行时,您既不需要优化,也不需要类型检查,也不需要重构,所以正常“ string“没关系,就像在JavaScript中一样,每个对象都是一个数字(Java中的Double),一个字符串(Java中的String)或一个复杂的对象(Java中的Map) - 这就是你在运行时甚至用Java做的所有事情