# Java 8 Parameternamen via Reflection auslesen



## Thomas Darimont (22. Mai 2013)

Hallo,


hier mal ein kleines Beispiel wie man mit Java 8 per Reflection die Namen von Methoden / Konstruktor Parametern auslesen kann.
Die Funktionalität ist im JEP 118: Access to Parameter Names at Runtime genauer Beschrieben: http://openjdk.java.net/jeps/118
Dazu muss man die Java Code mit einem speziellen javac Flag kompilieren (-parameters).


In früheren Java Versionen war der Zugriff auf die Methoden/Konstruktor Parameter über bytecode Analyse von mit -g (erweiterte Debug  Informationen) kompilierten Java Code oder via expliziten  Annotation der Parameter mit 
entsprechenden Meta-Informationen (@Parameter("param1")).
Siehe auch hier: http://www.tutorials.de/java/299708...ameter-bezeichnung-ermitteln.html#post1546882


Hier ein Beispiel für Java 8 (Ausprobiert mit openjdk 1.8 B90)



```
package de.tutorials;


import java.lang.reflect.Method;
import java.lang.reflect.Parameter;


class Test{
    public void foo(String first, int second, Object third){}
}


//See http://openjdk.java.net/jeps/118
public class JEP118ExampleAccessParameterNamesAtRuntime {
    public static void main(String[] args) {
        for(Method m : Test.class.getMethods()){
            System.out.println("Method: " + m);
            for(Parameter param : m.getParameters()){
                System.out.println("Param: " + param.getName() + " " + param.getType());
            }
        }
    }
}
```


Ausgabe Ohne die javac Option -parameters:

```
D:\private\dev\java\ws\java8\src\main\java>"C:\Program Files\Java\jdk1.8.0\bin\javac" .\de\tutorials\JEP118ExampleAccessParameterNamesAtRuntime.java


D:\private\dev\java\ws\java8\src\main\java>java -cp . de.tutorials.JEP118ExampleAccessParameterNamesAtRuntime
Method: public void de.tutorials.Test.foo(java.lang.String,int,java.lang.Object)
Param: arg0 class java.lang.String
Param: arg1 int
Param: arg2 class java.lang.Object
Method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Param: arg0 long
Param: arg1 int
Method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Param: arg0 long
Method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
Method: public boolean java.lang.Object.equals(java.lang.Object)
Param: arg0 class java.lang.Object
Method: public java.lang.String java.lang.Object.toString()
Method: public native int java.lang.Object.hashCode()
Method: public final native java.lang.Class java.lang.Object.getClass()
Method: public final native void java.lang.Object.notify()
Method: public final native void java.lang.Object.notifyAll()
```


Ausgabe mit der javac Option -parameters:

```
D:\private\dev\java\ws\java8\src\main\java>"C:\Program Files\Java\jdk1.8.0\bin\javac" -parameters .\de\tutorials\JEP118ExampleAccessParameterNamesAtRuntime.java


D:\private\dev\java\ws\java8\src\main\java>java -cp . de.tutorials.JEP118ExampleAccessParameterNamesAtRuntime
Method: public void de.tutorials.Test.foo(java.lang.String,int,java.lang.Object)
Param: first class java.lang.String
Param: second int
Param: third class java.lang.Object
Method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Param: arg0 long
Param: arg1 int
Method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Param: arg0 long
Method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
Method: public boolean java.lang.Object.equals(java.lang.Object)
Param: arg0 class java.lang.Object
Method: public java.lang.String java.lang.Object.toString()
Method: public native int java.lang.Object.hashCode()
Method: public final native java.lang.Class java.lang.Object.getClass()
Method: public final native void java.lang.Object.notify()
Method: public final native void java.lang.Object.notifyAll()
```


Da der Java Runtime Code aus dem rt.jar nicht mit der Option -parameters kompiliert wurde stehen die Parameter-Namen von Methoden/Konstruktoren der JDK Bibliotheken so nicht zur Verfügung.

Derzeit (05.06.2013 B91) ist leider nicht möglich festzustellen, ob der Name der von getName() zurückgegeben worden ist der tatsächliche oder ein "berechneter" Parametername (arg7) ist.

Hier dazu noch ein entsprechendes "Working Document" dazu:
http://cr.openjdk.java.net/~abuckley/8misc.pdf

Gruß Tom


----------

