Java 8 Parameternamen via Reflection auslesen

Thomas Darimont

Erfahrenes Mitglied
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)


Java:
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:
Code:
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:
Code:
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
 

Neue Beiträge

Zurück