'Java Record - Tests - Modify Fields
I have a framework used exclusively for testing that sets fields at runtime. The purpose is to set up test cases. Looking forward to upgrading to Java 14+ records I am noticing that existing utilities such as ReflectionTestUtils.setField and PropertyAccessorFactory.forDirectFieldAccess which work on normal private final fields, do not work for record fields.
Is this a limitation of the JVM, or is a limitation of these utilities?
Solution 1:[1]
Since modifying the private final fields of a record is intentionally unsupported, it’s not a limitation of the JVM or Java execution environment, so relying on the ability to modify such fields is a limitation of these utilities.
The documentation of setAccessible says:
This method cannot be used to enable write access to a non-modifiable final field. The following fields are non-modifiable:
- static final fields declared in any class or interface
- final fields declared in a hidden class
- final fields declared in a record
The original intent of supporting to write a final instance field via access override, was to allow fixing the object state after cloning or deserializing. Neither is necessary for a record.
Deserializing a
recordinstance will invoke its constructor, so the constructor can apply all necessary validation and fixes before the final fields are assigned.Creating a shallow clone of a
recordhas no point at all. For all other copying purposes, you can read all of its components, as each field has a corresponding accessor method, adapt them, and pass the adapted values to the always existing canonical constructor.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Holger |
