JDK-8362626 : Avoid caching synthesized names in synthesized parameters
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 26,27
  • Submitted: 2025-07-18
  • Updated: 2025-11-19
  • Resolved: 2025-11-19
Related Reports
CSR :  
Relates :  
Relates :  
Description
Summary
-------

Stop caching the synthesized names in synthesized `java.lang.reflect.Parameter` objects created by core libraries; return newly created `String` instances for the names upon demand.

Problem
-------

`java.lang.reflect.Parameter` instances may retain a lot of duplicate strings representing synthesized names, like "arg0", "arg1", etc. Each synthetic Parameter has its own synthesized names, so there are a lot of duplicate equivalent string objects observable in applications making use of parameter reflection, such as the Spring Framework.

Solution
--------

Remove the eager creation of synthesized names for completely-synthesized parameters. The content of the synthesized names is still identical to before, but repeated calls to `Parameter::getName` will now return String objects with different identities, such that `p.getName() != p.getName()`.

Note that `Parameter::getName` never made any promises about the identity of the returned String, and in some cases already exhibited the described behavior.

Currently, `MethodParameters` attribute takes three forms depending on how a Java program is compiled:

- No attribute: For no parameter, or all explicit parameters with no `-parameter` javac flag
- Attribute with all 0 names: Since JDK-8292275, for any mandated/synthesized parameter with no `-parameter` javac flag; always fell into the no attribute category before
- Attribute with full name information: Has any parameter, and `-parameter` javac flag is present

Core reflection only synthesizes `Parameter` objects for the first no attribute case. In this case, it creates and caches all synthesized names without sharing.

For any 0 name, hotspot creates a `Parameter` with `null` name, and the name is only synthesized upon `Parameter::getName` calls and is never retained. So this `!=` of two obtained synthetic names already exist with some constructors out in the wild since JDK-8292275, and apparently there is no report of incompatibility.

(In fact, back in JDK 8, core reflection had poor handling for this - a bugfix for mishandling 0 names in JDK 9 was not backported until JDK-8341145 arose.)

This solution essentially creates completely-synthesized parameters with all `null` names, as if they are all 0 named. This allows us to reuse existing routine and resolve the particular phenomenon observed in the original RFE.

Specification
-------------

No change. This is completely an implementation detail and is not expected to be relied on, as there is unlikely to have dependency around string identity here.
Comments
Approved for JDK 26 or 27 subject to reviews on the PR, etc.
19-11-2025

Moving to Provisional.
23-07-2025

I have clarified that they have different identities but are equal. This different identity behavior is already present for some constructors, such as inner class constructors, since JDK-8292275, but no one came up, so I can argue this is safe.
22-07-2025

Moving back to Draft. [~liach], please clarify if the returned names "arg0", "arg1" etc. will be the same with this change or if only the identity of the objects will be altered.
22-07-2025