是否可以根据输入文件创建Java枚举?

时间:2010-12-10 13:03:14

标签: java enums

我正在使用Java 6.

假设我有一个文件availableFruits.txt

APPLE
ORANGE
BANANA

假设我想要一个包含FruitType中列出的值的枚举availableFruits.txt,我能够这样做吗?

8 个答案:

答案 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做的所有事情