Executable.hasRealParameterData() and Parameter.isNamePresent() don't work as expected
Сергей Цыпанов
sergei.tsypanov at yandex.ru
Fri Jul 1 09:22:27 UTC 2022
Hi Daniel,
thanks, this is what I was looking for!
And what about JavaDoc of Parameter.isNamePresent()? Should we keep it as is,
I mean pointing out to 'MethodParameters' attribute of a class file?
Regards,
Sergey
> Hi Sergey,
>
> I believe you need to compile with `-parameters`
>
> https://docs.oracle.com/en/java/javase/18/docs/specs/man/javac.html
>
> best regards,
>
> -- daniel
>
> On 29/06/2022 07:54, Сергей Цыпанов wrote:
>
>> This question was asked originally here: https://stackoverflow.com/questions/72787286/executable-hasrealparameterdata-and-parameter-isnamepresent-dont-work-as-ex
>> but as soon as I got no answer I've decided to try it here adding some concerns regarding JavaDoc of Parameter.isNamePresent()
>>
>> With ad-hoc built JDK 19 (having exposed `Executable.hasRealParameterData()`) I take the code
>>
>> public class Main {
>>
>> public static void main(String[] args) throws NoSuchMethodException {
>> Method foo = Main.class.getMethod("foo", String.class, int.class);
>> System.out.println(foo.hasRealParameterData());
>> }
>>
>> public void foo(String parameter1, int parameter2) {}
>> }
>>
>> and compile it with
>>
>> % javac Main.java
>>
>> Then I run compiled Java class and it prints `false` into console. This is fine because decompiled `Main` class looks like
>>
>> public class Main {
>> //...
>> public void foo(String var1, int var2) {} // parameter names are not 'real'
>> }
>>
>> i.e. parameter names are synthetic.
>>
>> This behaviour is understandable.
>>
>> Then I take the same Java sources and recompile the class with
>>
>> javac -g:vars Main.java
>>
>> I run the same code again and again it prints `false` to console. This puzzles me, because now the compiled code looks different:
>>
>> public class Main {
>> //...
>> public void foo(String parameter1, int parameter2) {} // parameter names are 'real'
>> }
>>
>> Same happens if for recompilation I use plain -g flag (generates all auxiliary data).
>>
>> Now let's stop calling JDK's private API and rely only on the methods available out-of-the-box,
>> e.g. `Parameter.isNamePresent()` (this one calls `Executable.hasRealParameterData()` under the hood):
>>
>> public static void main(String[] args) throws NoSuchMethodException {
>> Method foo = Main.class.getMethod("foo", String.class, int.class);
>> Parameter parameter1 = foo.getParameters()[0];
>> Parameter parameter2 = foo.getParameters()[1];
>> System.out.println(parameter1.isNamePresent());
>> System.out.println(parameter2.isNamePresent());
>> }
>>
>> public void foo(String parameter1, int parameter2) {}
>>
>> And again, no matter how I compile the sources, this code prints `false false`.
>>
>> So my two questions are
>> 1) whether this is a bug or am I doing something wrong?
>> 2) is it possible somehow to change the behaviour to have at least Parameter.isNamePresent() returning true
>>
>> P.S. Parameter.isNamePresent() works unexpectedly even when I run it on conventional, not hacked JDK.
>>
>> P.P.S. In compiled code I see 'real' parameter names, but if I stop at debug point in IDEA parameter name is suddenly `arg0` in `Parameter.name` field.
>>
>> P.P.P.S. I think that JavaDoc of Parameter.isNamePresent() should be changed as soon as now it points out to 'MethodParameters' attribute of a class file
>> which is confusing to me as to end user of Java because I cannot understand from plain Java code what are those 'MethodParameters' and what will
>> be returned for any of my methods.
More information about the core-libs-dev
mailing list