On Mon, 15 Jun 2026 15:28:39 GMT, Alan Bateman <[email protected]> wrote:

>> src/java.base/share/classes/java/lang/reflect/Field.java line 1527:
>> 
>>> 1525: 
>>> 1526:         // strictly-initialized final fields cannot be mutated
>>> 1527:         if (isStrictInit()) {
>> 
>> I think the check is best done here, which should fix all MethodHandle too: 
>> https://github.com/AlanBateman/valhalla/blob/1890ec9eb8038d92f5fba3107085cafabdc9f21e/src/java.base/share/classes/java/lang/invoke/MethodHandles.java#L3443
>
> This is a good question. We went around this a few times during JEP 500 and 
> decided to send the conditional cases through 
> checkAllowedToUnreflectFinalSetter, the benefit being that everything related 
> to the CLI options to allow mutation of finals is in one place. You are right 
> that the strict final fields case can't be changed by the CLI options so 
> isStrictInit can be checked eariler. It means that newFieldAccessor must be 
> created without a setter, which is a good thing.

I take it that “best done here” refers to having `Field​::isTrustedFinal()` 
return `true` for strictly initialised fields, the correct fix for which would 
be to update `fieldDescriptor​::is_trusted_final()` to include `is_strict()` in 
the `||` portion of:
https://github.com/openjdk/valhalla/blob/9cd13e6903a025ee82be54217ab76256b392a9ce/src/hotspot/share/runtime/fieldDescriptor.cpp#L46-L50

e.g.:
```c++
bool fieldDescriptor::is_trusted_final() const {
  InstanceKlass* ik = field_holder();
  return is_final() && (is_static() || is_strict()
                        || ik->is_hidden() || ik->is_record() || 
ik->is_inline_klass()
                        || (ik->is_abstract() && !ik->is_identity_class() && 
!ik->is_interface()));
}

-------------

PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2548#discussion_r3414717861

Reply via email to