Java Record - Tests - Modify Fields

Viewed 257

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?

1 Answers

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 record instance 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 record has 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.

Related