views:

342

answers:

9

If I have a class like this:

public class Whatever
{
  public void aMethod(int aParam);
}

is there any way to know that aMethod uses a parameter named aParam, that is of type int?

+2  A: 

Can I obtain method parameter name using Java reflection?

No, that's not possible. This information (the parameter name, obviously not the parameter type as most other responders here seem to misinterpret) is already lost after compiling. Only the method name, parameter types and return type are known, as outlined in the Sun's reflection tutorial and Method API.

Why would you need to know about it then?

The only way to know about them is parsing the sourcecode or the Javadocs.

BalusC
thinking of writing a text editor that supports autocompletion, and I'd like to be able to provide useful info.
Geo
Not true except for the case of interfaces. Things like java2wsdl depend on it.
bmargulies
it is not lost if you compile with debug info
flybywire
seconded. what is the use of the parameter name ? it's only used locally in the method
Valentin Rocher
java2wsdl-like tools read the java source file, if I'm not mistaken.Autocomplete in eclipse uses arg0, arg1, etc. If there was a way, it would've used it. (+1)
Bozho
@flybywire : it's still available when debugging, but not to reflection
Valentin Rocher
A: 

Check Obtaining Method Type Information from the Java Tutorial.

JuanZe
Truly that's all possible. His question was however **explicitly** about the **parameter name**. Check the topictitle.
BalusC
@BalusC Seems like you enjoy so much down vote everything. If you want to be a cop of the answers here apply as a moderator. My answer to the explicit question "is there any way to know that aMethod uses a parameter named aParam, that is of type int?" was a pointer to a resource where @Geo, a user with almost 10K reputation, could get useful insight into the subject. With @Johnco answer and mine the subject was enough covered until you come to patronize all of us...
JuanZe
To clear out a misassumption: I have **not** downvoted anything in this topic. That would not have been fair of me because I myself also have answered in this topic. Now talk about yours... :/
BalusC
@JuanZe - don't complain about being downvoted. This is not a very good answer at all, as you have only provided a related link, and regardless of that every user on the site has the express right to upvote / downvote as he sees fit. This is the point of Stack Overflow. (Caveat: I also did not downvote you)
danben
That's not to say you shouldn't engage a downvoter in rational discussion (and to be sure, a downvoter should always leave a comment explaining his vote). But this is far different than accusing someone of being "a cop of the answers" - that is everyone's job.
danben
@danben It's OK, I see your point. I did not downvote any answer here, only +1 to @Johnco 's. If today I spend time addressing this guy was because I saw this kind of behavior from him a lot of times, is a repeating pattern... And I think is a bad way to encourage participation of new guys like @Johnco
JuanZe
@JuanZe - BalusC has 113 downvotes for 5 months, so it's not that much of a "repeating pattern". P.S. one of the downvotes on your answer was mine, because it didn't answer the question in the title. (and Johnco did)
Bozho
+4  A: 

You can retrieve the method with reflection and detect it's argument types. Check http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html#getParameterTypes%28%29

However, you can't tell the name of the argument used.

Johnco
Truly that's all possible. His question was however **explicitly** about the **parameter name**. Check the topictitle.
BalusC
And I quote: "However, you can't tell the name of the argument used." just read my answer -_-
Johnco
The question wasn't formulated that way he didn't knew about obtaining the type.
BalusC
A: 

Parameter names are only useful to the compiler. When the compiler generates a class file, the parameter names are not included - a method's argument list only consists of the number and types of its arguments. So it would be impossible to retrieve the parameter name using reflection (as tagged in your question) - it doesn't exist anywhere.

However, if the use of reflection is not a hard requirement, you can retrieve this information directly from the source code (assuming you have it).

danben
Parameter name are not only useful to a compiler they also convey information to the consumer of a libary, assume I wrote a class StrangeDate which had method add(int day,int hour, int minute) if you went to use this and found a method add(int arg0, int arg1, int arg2) how useful would that be?
David Waters
I'm sorry - you misunderstood my answer entirely. Please reread it in the context of the question.
danben
+3  A: 

To summarize:

  • getting parameter names is not possible
  • getting parameter type is possible, using method.getParameterTypes()

For the sake of writing autocomplete functionality for an editor (as you stated in one of the comments) there are a few options:

  • use arg0, arg1, arg2 etc.
  • use intParam, stringParam, objectTypeParam, etc.
  • use a combination of the above - the former for non-primitive types, and the latter for primitive types.
  • don't show argument names at all - just the types.
Bozho
A: 

To add my 2 cents; parameter info is available in a class file "for debugging" when you use javac -g to compile the source. And it is available to APT but you'll need an annotation so no use to you. (Somebody discussed something similar 4-5 years ago here: http://forums.java.net/jive/thread.jspa?messageID=13467&tstart=0 )

Overall in-short you can't get it unless you work on Source files directly (similar to what APT does at compile time).

Elister
+1  A: 

It is possible and Spring MVC 3 does it, but I didn't take the time to see exactly how.

The matching of method parameter names to URI Template variable names can only be done if your code is compiled with debugging enabled. If you do have not debugging enabled, you must specify the name of the URI Template variable name in the @PathVariable annotation in order to bind the resolved value of the variable name to a method parameter. For example:

Taken from the spring documentation

flybywire
+2  A: 

The Paranamer library was created to solve this same problem.

It tries to determine method names in a few different ways. If the class was compiled with debugging it can extract the information by reading the bytecode of the class.

Another way is for it to inject a private static member into the bytecode of the class after it is compiled, but before it is placed in a jar. It then uses reflection to extract this information from the class at runtime.

http://paranamer.codehaus.org/

I had problems using this library, but I did get it working in the end. I'm hoping to report the problems to the maintainer.

sjbotha
A: 

and how does a decompiler gets the parameter name if it is not in the Byte code ?

Rupesh