枚举值构造函数何时求值?在编译时或 在程序执行期间?
<小时/>事实上,我的具体案例可能比这更微妙,所以 我将详细阐述这个问题。
我有课,
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/