我有一个映射字符串-> 整数的表。
我不想静态创建枚举,而是想用数据库中的值填充枚举。这可能吗 ?
因此,而不是静态地对此进行处理:
public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };
我想动态创建这个枚举,因为数字 {0,1,2,3} 基本上是随机的(因为它们是由数据库的 AUTOINCREMENT 列自动生成的)。
我有一个映射字符串-> 整数的表。
我不想静态创建枚举,而是想用数据库中的值填充枚举。这可能吗 ?
因此,而不是静态地对此进行处理:
public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };
我想动态创建这个枚举,因为数字 {0,1,2,3} 基本上是随机的(因为它们是由数据库的 AUTOINCREMENT 列自动生成的)。
不,枚举总是在编译时固定的。您可以做到这一点的唯一方法是动态生成相关的字节码。
话虽如此,您可能应该弄清楚您真正感兴趣的枚举的哪些方面。大概您不想对switch
它们使用语句,因为这意味着静态代码并且您不知道静态值。 .. 代码中的任何其他引用也是如此。
如果您真的只想要一个从String
to的地图Integer
,您可以使用Map<String, Integer>
在执行时填充的 a ,然后就完成了。如果您想要这些EnumSet
功能,以相同的效率重现它们会有些棘手,但通过一些努力可能是可行的。
因此,在进一步考虑实施之前,我建议您弄清楚您的真正需求是什么。
(编辑:我一直假设这个枚举是完全动态的,即您不知道名称,甚至不知道有多少值。如果名称集是固定的,您只需要从数据库中获取 ID ,这是一个非常不同的问题 - 见安德烈亚斯的回答。)
这有点棘手,因为这些值的填充发生在类加载时。因此,您将需要对数据库连接的静态访问。
尽管我很重视他的回答,但我认为 Jon Skeet 这次可能错了。
看看这个:
public enum DbEnum {
FIRST(getFromDb("FIRST")), SECOND(getFromDb("second"));
private static int getFromDb(String s) {
PreparedStatement statement = null;
ResultSet rs = null;
try {
Connection c = ConnectionFactory.getInstance().getConnection();
statement = c.prepareStatement("select id from Test where name=?");
statement.setString(1, s);
rs = statement.executeQuery();
return rs.getInt(1);
}
catch (SQLException e) {
throw new RuntimeException("error loading enum value for "+s,e);
}
finally {
try {
rs.close();
statement.close();
} catch (SQLException e) {
//ignore
}
}
throw new IllegalStateException("have no database");
}
final int value;
DbEnum(int value) {
this.value = value;
}
}
改进Andreas 所做的,您可以将数据库的内容加载到地图中,以减少所需的数据库连接数。
public enum DbEnum {
FIRST(getFromDb("FIRST")),
SECOND(getFromDb("second"));
private Map<String,Integer> map;
private static int getFromDB(String s)
{
if (map == null)
{
map = new HashMap<String,Integer>();
// Continue with database code but get everything and
// then populate the map with key-value pairs.
return map.get(s);
}
else {
return map.get(s); }
}
}
枚举不是动态的,所以简短的回答是你不能这样做。
另请查看 Stack Overflow 问题Dynamic enum in C#。
您需要在代码中复制数据库中的内容(反之亦然)。有关一些好的建议,请参阅此问题。
在我知道的所有语言中,枚举都是静态的。编译器可以对它们进行一些优化。因此,简短的回答是否定的,你不能。
问题是为什么要以这种方式使用枚举。你能指望什么?或者换句话说,为什么不使用集合呢?