简体   繁体   English

使用String数组声明java enum

[英]Declare java enum with a String array

I'm trying to declare an enum type based on data that I'm retrieving from a database. 我正在尝试根据我从数据库中检索的数据声明枚举类型。 I have a method that returns a string array of all the rows in the table that I want to make into an enumerated type. 我有一个方法,返回表格中我想要进行枚举类型的所有行的字符串数组。 Is there any way to construct an enum with an array? 有没有办法用数组构造枚举?

This is what I tried, but from the way it looked in eclipse, it seemed like this just created a method by that name: 这是我尝试过的,但从它在eclipse中看起来的方式来看,似乎这只是通过该名称创建了一个方法:

public enum ConditionCodes{
    Condition.getDescriptions();
}

Thank you in advance! 先感谢您!

You can't. 你不能。

The values of an enum must be known at compile time . enum的值必须在编译时知道。 If you have anything else, then it's not an enum . 如果你还有别的东西,那就不是enum

You could come rather close via an implementation that's similar to the old typesafe enums that were used before the Java language introduced support for this technique via the enum keyword. 您可以通过类似于Java语言通过enum关键字引入对此技术的支持之前使用的旧类型安全枚举的实现来接近。 You could use those techniques but simply replace the static final fields with values read from the DB. 您可以使用这些技术,但只需将static final字段替换为从DB读取的值。

For your enum to be useful it has to be nailed down at compile time. 为了使你的枚举有用,必须在编译时将其固定。 Generating the enum from the database query would imply you expect to see new enum values at runtime. 从数据库查询生成枚举意味着您希望在运行时看到新的枚举值。 Even if you created a code generator to create your enum class on the fly using the database query, you wouldn't be able to reference those enum values in your code, which is the point of having them. 即使您使用数据库查询创建了代码生成器来动态创建枚举类,您也无法在代码中引用这些枚举值,这就是拥有它们的重点。

It's difficult to see how any compiler could support this. 很难看出任何编译器如何支持它。

The whole point of an enum is supposed to be that you get compile-time checking of the validity of your values. 枚举的全部意义应该是您可以通过编译时检查值的有效性。 If, say, you declare an enum "enum MyStatusCode {FOO, BAR, PLUGH}", then in your code if you write "MyStatusCode.FOO" everything is good, but if you write "MyStatusCode.ZORK" you get a compile-time error. 例如,如果您声明枚举“enum MyStatusCode {FOO,BAR,PLUGH}”,那么在您的代码中,如果您编写“MyStatusCode.FOO”,一切都很好,但如果您编写“MyStatusCode.ZORK”,您将获得编译 - 时间错误。 This protects you from mis-spelling values or getting confused about the values for one enum versus another. 这可以保护您免受错误拼写错误或对一个枚举值与另一个枚举值的混淆。 (I just had a problem recently where a programmer accidentally assigned a delivery method to a transaction type, thus magically changing a sale into an inventory adjustment when he meant to change a home delivery into a customer pick-up.) (我最近遇到了一个问题,即程序员意外地将交付方式分配给交易类型,因此当他打算将房屋交付更改为客户提货时,将销售神奇地改为库存调整。)

But if your values are defined dynamically at run-time, how could the compiler do this? 但是如果你的值是在运行时动态定义的,那么编译器怎么做呢? If you wrote MyStatusCode.ZORK in the above example, there is no way the compiler could know if this value will or will not be in the database at runtime. 如果您在上面的示例中编写了MyStatusCode.ZORK,则编译器无法知道此值是否将在运行时存在于数据库中。 Even if you imagined a compiler smart enough to figure out how the enum was being populated and checking the database to see if that value is present in the appropriate table NOW, it would have no way of knowing if it will be there when you actually run. 即使你想象一个足够聪明的编译器来弄清楚枚举是如何被填充的,并且检查数据库以查看该值是否存在于适当的表中,它也无法知道当你实际运行时它是否存在。

In short, what you want is something very different from an enum. 简而言之,你想要的是与枚举有很大不同的东西。

No, that's not possible because the enum type must be defined at compile time and what you're looking for is to dynamically create it. 不,这是不可能的,因为枚举类型必须在编译时定义,而您正在寻找的是动态创建它。

Perhaps you'll be better if use a class instead. 如果使用一个班级,也许你会更好。

If you want to get really crazy, I think annotation processing can do this. 如果你想变得非常疯狂,我认为注释处理可以做到这一点。 Annotation processing lets you hook the compiler and have it magically modify things when your @annotation is present. 注释处理允许您挂钩编译器,并在存在@annotation时神奇地修改内容。

Naturally, the values in the enum will be whatever values were available at compile time. 当然,枚举中的值将是编译时可用的任何值。

I think here you are going to need a List or Set along with some utility methods for searching and comparison. 我想在这里你需要一个List或Set以及一些用于搜索和比较的实用方法。

So here's your List 所以这是你的清单

List<String> conditionCodes = new ArrayList<String>();
//Somehow get Rows or POJO Beans from database with your favorite framework
Collection<Row> dbRows = getConditionCodes();
for(Row curRow : dbRows)
     conditionCodes.add(curRow.getName());

And to search 并搜索

public boolean conditionExists(String name) {
    return conditonCodes.contains(name);
}

public String getCondition(String name) {
    return conditionCodes.get(name);
}

(of course you would probably want to use List's own methods instead of making your own) (当然你可能想要使用List自己的方法而不是自己的方法)

More than you can't, you don't want to. 超过你不能,你不想。 Every enum, even Java's fairly cool enums, is code oriented. 每个枚举,甚至是Java相当酷的枚举,都是面向代码的。

It's exactly the same as a collection, but with an enum you tend to write duplicate code whenever you encounter it--with a collection you are more likely to write a loop. 它与集合完全相同,但是当你遇到它时,你会倾向于编写重复的代码 - 使用集合你更有可能编写一个循环。

I suggest you create a class with a private constructor and have it create the instances of itself, then provide a getInstance(String) to retrieve an instance. 我建议你创建一个带有私有构造函数的类,让它创建自己的实例,然后提供一个getInstance(String)来检索实例。 This is like the old typesafe enum pattern. 这就像旧的类型安全枚举模式。

In the long run, however, it's better if you can manage to get enough intelligence into that class where you aren't ever differentiating on a specific instance--going from the "Enum" way of doing it: 但是,从长远来看,如果你能够在这个类中获得足够的智能,而不是在特定的实例上进行区分,那就更好了 - 从“Enum”的方式来看:

if(myEnum.stringValue.equals("EnumTarget"))
    executeCode();

To the OO way of doing it: 以OO的方式做到这一点:

myEnumLikeObject.executeCode();

Moving the code you wish into the "enum"--preferably delegating directly to a contained object that is instantiated and set into the "enum" at creation time. 将您希望的代码移动到“枚举”中 - 最好直接委托给实例化的包含对象,并在创建时设置为“枚举”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM