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.

Reply via email to