How to Get Argument Names Using Reflection

Can I obtain method parameter name using Java reflection?

To summarize:

  • getting parameter names is possible if debug information is included during compilation. See this answer for more details
  • otherwise 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.

How to get argument names using reflection

I suggest you take a look at Merb's action-args library.

require 'rubygems'
require 'merb'

include GetArgs

def foo(bar, zed=42)
end

method(:foo).get_args # => [[[:bar], [:zed, 42]], [:zed]]

If you don't want to depend on Merb, you can choose and pick the best parts from the source code in github.

How to get parameter names with Java reflection

To get the method i of a class C you call C.class.getMethods()[i].toString().

EDIT: Obtaining parameter names is not possible using the reflection API.

But wen you compiled your class with debug information, it is possible to extract the information from bytecode. Spring does it using the ASM bytecode engineering library.

See this answer for further information.

Getting method parameter names

There is no way to get the names of the parameters of a method or a function.

The reason for this is because the names are not really important for someone calling a method or a function. What matters is the types of the parameters and their order.

A Function type denotes the set of all functions with the same parameter and result types. The type of 2 functions having the same parameter and result types is identical regardless of the names of the parameters. The following code prints true:

func f1(a int) {}
func f2(b int) {}

fmt.Println(reflect.TypeOf(f1) == reflect.TypeOf(f2))

It is even possible to create a function or method where you don't even give names to the parameters (within a list of parameters or results, the names must either all be present or all be absent). This is valid code:

func NamelessParams(int, string) {
fmt.Println("NamelessParams called")
}

For details and examples, see Is unnamed arguments a thing in Go?

If you want to create some kind of framework where you call functions passing values to "named" parameters (e.g. mapping incoming API params to Go function/method params), you may use a struct because using the reflect package you can get the named fields (e.g. Value.FieldByName() and Type.FieldByName()), or you may use a map. See this related question: Initialize function fields

Here is a relevant discussion on the golang-nuts mailing list.

How to get a method's parameter values from within the method using reflection?

Getting the method name is easy via [CallerMemberName] on a helper function like:

static string Me([CallerMemberName]string caller=null) => caller;

Getting the MethodInfo, and thus the ParameterInfo definitions (including the names) is pretty easy, but not very efficient. Getting the parameter values is not a thing you can do with the reflection API, and even if it could: the performance would be catastrophically bad. Since you say

and most importantly, the values passed into the function via the parameters.

I think you need to look at alternatives. One of which might just be "add the code you need manually". IL-weaving at build-time might be an option, but that's a much more advanced topic.

Using reflection to get method name and parameters

What you're looking for is an interceptor. Like the name says, an interceptor intercepts a method invocation and allows you to perform things before and after a method is called. This is quite popular in many caching and logging frameworks.



Related Topics



Leave a reply



Submit