There is actually nothing within the class file itself that stores the name of the method parameter. If you look at section 4.3.3, you'll see the following definitions for MethodDescriptor
:
A method descriptor represents the parameters that the method takes and the value that it returns:
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
A parameter descriptor represents a parameter passed to a method:
ParameterDescriptor:
FieldType
A return descriptor represents the type of the value returned from a method. It is a series of characters generated by the grammar:
ReturnDescriptor:
FieldType
VoidDescriptor
VoidDescriptor:
V
The character V indicates that the method returns no value (its return type is void).
You can see this if you print out the bytecode for Person.class
and PersonImpl.class
using javap -c
:
Compiled from "Person.java"
public interface Person {
public abstract void setName(java.lang.String);
public abstract void setAge(int);
}
Compiled from "PersonImpl.java"
public class PersonImpl implements Person {
public PersonImpl();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void setName(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String This is my name:
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
public void setAge(int);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #9 // String This is my age:
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: iload_1
16: invokevirtual #10 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
}
You can see that the signature for the method says nothing about the name of the parameter; only its type.
What I suspect is happening is that JD-Gui is probably using some sort of heuristic based on JavaBeans conventions to derive the name of the parameter. Since the name of the method is setName
, it assumes that the name of the parameter is name
. Try changing the name of the parameter to something other than name
and see what JD-Gui prints out.
Debug information, like local variables, will show up if you compile using -g
or -g:vars
; it does not show up by default. These show up in the LocalVariableTable
attribute. From section 4.7.13:
The LocalVariableTable
attribute is an optional variable-length attribute in the attributes table of a Code
attribute (§4.7.3). It may be used by debuggers to determine the value of a given local variable during the execution of a method.
Notice the optional part; this is why you don't see it by default. Now if you look at section 4.7.3 for the Code
attribute:
The Code attribute is a variable-length attribute in the attributes table of a method_info structure (§4.6). A Code
attribute contains the Java Virtual Machine instructions and auxiliary information for a method, including an instance initialization method or a class or interface initialization method (§2.9).
If the method is either native or abstract, its method_info
structure must not have a Code
attribute in its attributes table. Otherwise, its method_info structure must have exactly one Code
attribute in its attributes table.
Since interface method-definitions are effectively abstract (unless you use default methods), you won't see a LocalVariableTable
entry for them. I used the latest version of JD-Gui against PersonImpl.class
that was not compiled with -g
, and found that it did not display name
and age
. Instead it displayed paramString
and paramInt
just like you saw for Person.class
. However, if you do compile it with the -g
flag, you will see name
and age
.