When does enum value constructors evaluate? At compile-time or during program execution?
In fact, my specific case might be even more nuanced than this so I will expand on the question.
I have a class,
class Instruction
which has a private enum
private enum InstructionModel
where InstructionModel
serves as archetypal examples for instructions. A bare-bones view would be
private enum InstructionModel {
ADD("add $t1, $t2, $t3", 0x014b4820, // Other params
),
;
// Some stuff
InstructionModel(String example, int sameExample, // Other params
) {
// Some other stuff
}
Now, the enclosing class ( Instruction
) can create instances of itself from both Strings and numbers, ie
class Instruction {
Instruction fromNumber(int number) {
// ...
}
Instruction fromString(String mnemonic) {
// ...
}
private enum InstructionModel { ... }
}
So,
Instruction foo = Instruction.fromNumber(0x014b4820);
Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
assert(foo.equals(bar));
Now, I could open up the Instruction
API, so that I could from my unit tests access the examples encoded into the InstructionModel
.
But: (assuming my understanding is correct) since an enum constructor is only ever executed once, I could let the value constructor verify that the String example yields the numerical representation and vice versa.
Although, I do not want to do this unless it is simply a compile-time cost. Ie 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?
In this context the following operation is crucial
Instruction foo = Instruction.fromNumber(0x014b4820);
Instruction bar = Instruction.fromString("add $t1, $t2, $t3");
assert(foo.equals(bar));
as the InstructionModel
is not sufficient to ascertain whether two instances are equal.
For those that question the why my reasoning is this:
In comparison with plain JUnit tests, where we'd have to either encode the knowledge that
"add $t1, $t2, $t3" <-> 0x014b4820
or make the InstructionModel
class publicly accessible to access the examples (or access the examples through methods in the enclosing class) it felt prudent to let the constructor evaluate that the proper model is instantiated for a corresponding number.
Subsequently, the code will not does not compile if the Instruction
constructors are "wrong".
Constructors evaluate at run-time. This means that the following snippet,
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
}
is evaluated at run-time. It does not matter that it is an enum-constructor. Hence, it is only when the constructor is used that it is evaluated.
Although, I do not want to do this unless it is simply a compile-time cost. Ie 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?
No.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.