编译/运行时的 Java 枚举评估

标签 java enums compile-time

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

<小时/>

事实上,我的具体案例可能比这更微妙,所以 我将详细阐述这个问题。

我有课,

class Instruction

它有一个私有(private)枚举

private enum InstructionModel

其中 InstructionModel 作为原型(prototype)示例 指示。一个简单的 View 是

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

    // Some stuff

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

现在,封闭类 (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 中的示例。

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

尽管如此,我不想这样做,除非它只是一个编译时 成本。 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类可公开访问以访问 示例(或通过封闭的方法访问示例 类)让构造函数评估正确的方法是明智的 模型被实例化为相应的数字。

随后,如果指令,代码将不会编译 构造函数是“错误的”。

最佳答案

构造函数在运行时进行评估。这意味着 以下片段,

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?

没有。

关于编译/运行时的 Java 枚举评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39015075/

相关文章:

java - java、spring和maven的正确工作方式是什么?

c++ - 为什么 std::array<T,N>::begin() 自 C++17 以来是 constexpr?

c++ - [C++ 编译时断言] : Can we throw a compilation error if some condition is not met?

C++ 编译时状态变量

java - 集合投影和嵌套投影

java - android 从 PreferenceScreen 中的图库中选择图像?

java - 转换为可运行 Jar 文件时读取 .ini 文件

struct - 我们什么时候应该使用结构而不是枚举?

ios - 从值中获取枚举

swift - 变量(枚举?)在 Swift 2 中持有两种类型之一