Java 重构枚举后db4o的奇怪行为
我们重构了模型中使用的枚举,以包含新值。现在,当应用程序执行时(使用旧应用程序创建的数据库文件),一些switch/case语句的行为非常奇怪 debug variables视图显示,例如,枚举值为“OLD”,但调试器进入“case NEW:”行 有什么想法吗?干杯 更新: 下面的代码Java 重构枚举后db4o的奇怪行为,java,enums,refactoring,db4o,Java,Enums,Refactoring,Db4o,我们重构了模型中使用的枚举,以包含新值。现在,当应用程序执行时(使用旧应用程序创建的数据库文件),一些switch/case语句的行为非常奇怪 debug variables视图显示,例如,枚举值为“OLD”,但调试器进入“case NEW:”行 有什么想法吗?干杯 更新: 下面的代码 ObjectSet<Project> set = db.query(Project.class); System.out.println("Found " + set.size()); for (Pr
ObjectSet<Project> set = db.query(Project.class);
System.out.println("Found " + set.size());
for (Project prj : set) {
// this line makes no difference
ProjectStatus otherStatus = ProjectStatus.valueOf(prj.getStatus().name());
// debug
System.out.println(otherStatus.name());
// decide via switch/case
switch (otherStatus) {
case A:
System.out.println("Project status is A (switch/case)");
break;
case B:
System.out.println("Project status is B (switch/case)");
break;
}
// decide via if
if (otherStatus == ProjectStatus.A) {
System.out.println("Project status is A (if ==)");
}
else if (otherStatus == ProjectStatus.B) {
System.out.println("Project status is B (if ==)");
}
}
我们尝试了db4o6.4和7.12
此外,根据枚举重构的类型,如果删除枚举值,将引发以下异常:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Main.$SWITCH_TABLE$model$ProjectStatus(Main.java:8)
at Main.main(Main.java:37)
所以我可以观察到这种行为: 我们有这样一个枚举:
public enum SomeState {
One,
Two
}
以及关于此的切换语句:
switch(object.getState()){
case One: doSomething("State One");break;
case Two: doSomething("State Two");break;
}
我们存储了一个状态为2的对象,因此它将“切换”到第二种情况
现在我们重构枚举。我们重命名第二个值并添加一个新值:
public enum SomeState {
One,
NewTwo,
OldTwo
}
以及新的switch语句:
switch(object.getState()){
case One: doSomething("State One");break;
case NewTwo: doSomething("State New Two");break;
case OldTwo: doSomething("State Old Two");break;
}
现在该对象将“切换”到“NewTwo”状态,这是完全错误的
不幸的是,这是一个bug:我在这里添加了一个条目(http://tracker.db4o.com/browse/COR-2268). 根本的问题是db4o的奇怪枚举处理。它实际上存储枚举对象本身。从数据库加载对象时,它会恢复枚举状态,甚至是静态变量中的内容!如果同时进行了重构,那么整个事情就会一团糟。基本上,我们使用相同的序号和混乱的名称创建多个枚举
目前,我建议避免枚举(在Java.In.Net上,db4o枚举处理工作)=(
编辑:迁移建议:您可以这样做:将“重构”枚举作为完整的新值添加到枚举中。然后加载包含该枚举的所有对象并将值更改为新值。然后删除旧的枚举值。在Java中?能否显示enum&switch语句示例?是的,Java具有更新的标记。switch只是一个常规开关(是的,我们在前面的案例块中确实想到了“中断”:以枚举作为其参数。是否仍要查看它?嗯,仅添加枚举值似乎在这里起作用?但是db4o枚举实现中存在一个巨大的问题。它确实存储枚举对象,包括序号。因此,当您从数据库加载数据时,枚举将突然包含旧的序号。只要您在t处添加值he bottum,你很好。但是当在两者之间添加内容时,这可能是一个很大的问题。或者当枚举中有值时,这是同一个问题。无论如何,要获得更多帮助,我需要一个代码示例。你重命名了枚举值吗?然后我可以生成此行为。
switch(object.getState()){
case One: doSomething("State One");break;
case NewTwo: doSomething("State New Two");break;
case OldTwo: doSomething("State Old Two");break;
}