Reflective Record Field Write
ID |
java.reflective_record_field_write |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability |
Description
Reports field.set(target, value) where field was obtained, in the same method, from X.class.getDeclaredField(..) and X is a record.
Rationale
A record’s components have no writable backing field at the bytecode level — they are exposed only through their generated accessor. Calling Field.set(..) on one always throws IllegalAccessException at runtime, whether or not setAccessible(true) was called first: the call can never succeed, on any input.
record Traveler(String name, int age) {}
Traveler traveler = new Traveler("A", 26);
Field field = Traveler.class.getDeclaredField("name");
field.setAccessible(true);
field.set(traveler, "B"); // Bad - always throws IllegalAccessException
Remediation
Records are immutable by design: build a new instance with the changed value instead of trying to mutate an existing one. Reflectively reading a record field is legitimate and unaffected by this rule.
record Traveler(String name, int age) {}
Traveler traveler = new Traveler("A", 26);
Traveler updated = new Traveler("B", traveler.age()); // Good - a new instance with the changed value