是否可以根据输入文件创建 Java 枚举?
我使用的是 Java 6。
假设我有一个文件 availableFruits.txt
APPLE
ORANGE
BANANA
假设我想要一个枚举 FruitType
,其中包含 availableFruits.txt
中列出的值,我能做到吗?
I'm using Java 6.
Suppose I have a file availableFruits.txt
APPLE
ORANGE
BANANA
Suppose I want an enum FruitType
that contains values listed in availableFruits.txt
, will I be able to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你不能在执行时填充枚举类型,不 - 至少,如果没有 BCEL 之类的东西,或者通过调用 Java 编译器,就不能填充枚举类型。
当然,您可以编写代码来创建 Java 源文件,并在构建应用程序时构建该文件(如果您之后不需要更改它)。
否则,我只需创建一个包装类,它能够获取一组已知值并重用它们。当然,您到底需要做什么取决于您想要如何使用枚举。
You can't populate an enum type at execution time, no - at least, not without something like BCEL, or by calling the Java compiler.
You can write code to create a Java source file, of course, and build that when you build your app, if you don't need it to be changed afterwards.
Otherwise, I'd just create a wrapper class which is able to take a set of known values and reuse them. Exactly what you need to do will depend on how you wanted to use the enum, of course.
枚举的要点是在编译时使用它。
如果您在编译时不知道 Enum 有什么值,那么它不是 Enum,而是集合。
如果您确实知道并且只想根据文本文件中的值创建一个类文件,那么可以通过读取 txt 然后生成源代码来实现。
Well the point of an Enum is to use it at compile time.
If you don't know at compile time what values your Enum has then it's not an Enum it's a collection.
If you do know and you just want to create a class file base on the values in the text file then yes it's possible by reading the txt then generating the source code.
我希望通过编写自己的
ClassLoader
子类,为字节数组中的枚举创建字节码,并使用defineClass
。也许很难,但有可能。我希望一旦您知道枚举的字节序列,从 JVM 规范。现在,这是否是一个好主意......好吧,我怀疑只在极少数的边缘情况下。 (我想不出一个;我的意思是,创建它后,您必须生成代码来使用它,对吧?)否则,您可能最好使用
Map
或类似的。I expect it's possible, by writing your own
ClassLoader
subclass, creating the bytecode for the enum in a byte array, and usingdefineClass
. Hard, maybe, but possible. I expect once you know the byte sequence for an enum, it's not that hard to custom-generate it from the info in the JVM spec.Now, whether it's a good idea...well, I suspect only in a very small number of edge cases. (I can't think of one; I mean, having created it, you'd have to generate code to use it, right?) Otherwise, you're probably better off with a
Map
or similar.不,除非您从文本文件生成枚举源文件。
No, not unless you generate the enum source file from the text file.
正如其他人所说 - 不。这是不可能的。最好的办法是使用注册表模式。读入值,将它们存储在某种可查询的映射中。有点像枚举。
As everyone else said- no. It's not possible. Your best shot is to use the Registry pattern. Read in the values, store them in some sort of query-able map. Sort of like an Enum.
正如每个人都指出的那样,这是不可能的。但是,您可以创建一个 Map,其中地图的键将是您从文件中读取的值(苹果,橙色,香蕉)和?将是一个关联值(例如 int)。
当然,通过这种方式,您基本上可以在没有类型安全的情况下实现相同的目标。
As everyone pointed out, it's not possible. However, you could create a Map where the key of your map would be the value you read from you file (APPLE,ORANGE,BANANA) and the ? would be an associated valu (int for example).
This way you could basically achieve the same goal without the type safety, of course.
您可以使用动态生成的代码。例如使用编译器 API。我已经为该 API 编写了一个包装器,以便您可以在内存中编译类。请参阅下面的代码。
您遇到的问题是它不是很有用,因为您不能使用这些值,除非在编译枚举后编译的类中。您可以使用 Enum.valueOf() 等。但是枚举的很多值都会丢失。
正如其他人所建议的,使用地图会更简单并且具有相同的好处。如果您有一个必须传递枚举的库,我只会使用枚举。 (或计划更多生成的代码)
我发现文本生成的代码有用的一件事是您可以将其写入文件并甚至在运行时进行调试。 (该库支持此)如果生成字节代码,则更难调试。
该库称为 Essence JCF。 (并且它不需要自定义类加载器)
You can with dynamically generated code. e.g. Using the Compiler API. I have written a wrapper for that API so you can compile classes in memory. See the code below.
The problem you have is that its not very useful as you cannot use these values except in classes which were compiled AFTER your enum was compiled. You can use Enum.valueOf() etc. But a lot of the value of enums is lost.
As other have suggested, using a Map would be simpler and give the same benefit. I would only use the enum if you have a library has to be passed an Enum. (Or plan more generated code)
One of things I find useful with text generated code is that you can write it to a file and debug it even at run time. (The library supports this) If you byte code generation, its harder to debug.
The library is called Essence JCF. (And it doesn't require a custom class loader)
你会如何用像 JavaScript 这样的动态语言来做到这一点:它只是带有以下值之一的字符串:“APPLE”、“ORANGE”、“BANANA”。
Java类型(类、接口、枚举)的存在只是为了编译器做一些优化和类型检查,使重构成为可能等。在运行时,你既不需要优化,类型检查也不需要重构,所以普通的“字符串”是好的,就像在 JavaScript 中一样,每个对象要么是一个数字(Java 中的 Double)、一个字符串(Java 中的 String)或一个复杂的对象(Java 中的 Map)——这就是您在运行时需要做的所有事情,即使在 Java 中也是如此。
How would you do this in a dynamic language like JavaScript: it would be just string with one of values: "APPLE", "ORANGE", "BANANA".
Java types (classes, interfaces, enums) exist only for compiler to do some optimizations, and type checking, to make refactoring possible, etc. At runtime you don't need neither optimizations, type checking nor refactoring, so normal "string" is OK, just like in JavaScript every object is either a number (Double in Java), a string (String in Java) or a complex object (Map in Java) - that's all you need to do anything at runtime even in Java.