java - 重构枚举后 db4o 的奇怪行为

标签 java enums refactoring db4o

我们重构了模型中使用的枚举以包含新值。现在,当应用程序执行时(使用旧应用程序创建的数据库文件),一些 switch/case 语句的行为非常奇怪。

调试变量 View 显示,例如枚举的值为“OLD”,但调试器会进入“case NEW:”行。

有什么想法吗?干杯!

更新:

以下代码

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 ==)");
    }
}

产生输出

Found 1
B
Project status is B (if ==)

我们尝试了 db4o 6.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 语句:

switch(object.getState()){ 
 case One: doSomething("State One");break; 
 case Two: doSomething("State Two");break; 
} 

我们存储了一个状态为“Two”的对象,因此它将“切换”到第二种情况。

现在我们重构枚举。我们重命名第二个值并添加一个新值:

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”状态,这是完全错误的!

不幸的是,有一个错误:我在此处添加了一个条目 (http://tracker.db4o.com/browse/COR-2268)。根本问题是 db4o 的奇怪枚举处理。它实际上存储枚举对象本身。当从数据库加载对象时,它会恢复枚举状态,甚至是静态变量中的内容!如果同时进行了重构,那么整个事情就会变得一团糟。基本上我们使用多个具有相同序数和困惑名称的枚举。

目前我建议避免使用枚举(在 Java 上。在 .Net 中,db4o 枚举处理有效)=(。

编辑:迁移建议:您可以这样做:将“重构”枚举作为完整的新值添加到枚举中。然后加载包含该枚举的所有对象并将值更改为新值。之后,您删除旧的枚举值。

关于java - 重构枚举后 db4o 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8405706/

相关文章:

java - 用于提取包含管道字符的文本的正则表达式

java - 如何从主应用程序的 init() 方法调用 JavaFX 应用程序预加载器实例中的方法

c# - 是否可以将项目从 Enum 加载到 .NET 3.5 中的 ComboBox?

eclipse - 我无法使用 Eclipse 重构删除方法?

java - “If”语句未通过检查涉及字符串数组

java - 如何优先考虑在信号量中等待的线程?

java - 为什么在 java 枚举中声明为 Enum<E extends Enum<E>>

python: object() 不带参数错误

java - 重构 if/else 逻辑

eclipse - 在 Eclipse Java 编辑器中突出显示搜索字符串的所有出现位置