Java compile/run-time 处的枚举评估

Java enum evaluations at compile/run-time

枚举值构造函数什么时候求值?在编译时或 在程序执行期间?


事实上,我的具体情况可能比这更微妙所以 我将详细说明这个问题。

我有一个class,

class Instruction

其中有一个 private enum

private enum InstructionModel

其中 InstructionModel 作为原型示例 指示。一个简单的视图是

private enum InstructionModel {
    ADD("add $t1, $t2, $t3", 0x014b4820, // Other params
            ),
    ;

    // Some stuff

    InstructionModel(String example, int sameExample, // Other params
                            ) {
        // Some other stuff
    }

现在,封闭的 class (Instruction) 可以创建实例 本身来自字符串和数字,即

class Instruction {
    Instruction fromNumber(int number) {
        // ...
    }

    Instruction fromString(String mnemonic) {
        // ...
    }

    private enum InstructionModel { ... }
}

所以,

Instruction foo = Instruction.fromNumber(0x014b4820);
Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
assert(foo.equals(bar));

现在,我可以打开 Instruction API,这样我就可以从我的 单元测试访问编码到 InstructionModel.

中的示例

但是:(假设我的理解是正确的)因为枚举 构造函数只执行一次,我可以让值 构造函数验证字符串示例产生 数值表示,反之亦然。

虽然,我不想这样做,除非它只是一个编译时 成本。 IE。我可以

InstructionModel(String example, int sameExample, // Other params
                        ) {

    Instruction foo = Instruction.fromNumber(0x014b4820);
    Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
    assert(foo.equals(bar));

    // Some other stuff
}

不会影响最终用户?

备注

在这种情况下,以下操作至关重要

Instruction foo = Instruction.fromNumber(0x014b4820);
Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
assert(foo.equals(bar));

因为 InstructionModel 不足以确定两个 实例相等。

理由

对于那些质疑为什么的人,我的推理是:

与普通的 JUnit 测试相比,我们必须 要么对

的知识进行编码

"add $t1, $t2, $t3" <-> 0x014b4820

或使 InstructionModel class 可公开访问以访问 示例(或通过封闭的方法访问示例 class) 让构造函数评估正确的方法是明智的 模型被实例化为相应的数字。

随后,如果 Instruction 构造函数是 "wrong".

构造函数在 运行 时计算。这意味着 以下片段,

InstructionModel(String example, int sameExample, // Other params
                        ) {

    Instruction foo = Instruction.fromNumber(0x014b4820);
    Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
    assert(foo.equals(bar));

    // Some other stuff
}

在 运行 时评估。它是一个枚举构造函数并不重要。因此,只有在使用构造函数时才会对其求值。

Although, I do not want to do this unless it is simply a compile-time cost. I.e. could I have

InstructionModel(String example, int sameExample, // Other params
                        ) {

    Instruction foo = Instruction.fromNumber(0x014b4820);
    Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
    assert(foo.equals(bar));

    // Some other stuff
}

without it affecting the end-user?

没有