How to get the MethodInfo of a Java 8 method reference?

Rafal picture Rafal · Nov 7, 2013 · Viewed 27.3k times · Source

Please have a look at the following code:

Method methodInfo = MyClass.class.getMethod("myMethod");

This works, but the method name is passed as a string, so this will compile even if myMethod does not exist.

On the other hand, Java 8 introduces a method reference feature. It is checked at compile time. It is possible to use this feature to get method info?

printMethodName(MyClass::myMethod);

Full example:

@FunctionalInterface
private interface Action {

    void invoke();
}

private static class MyClass {

    public static void myMethod() {
    }
}

private static void printMethodName(Action action) {
}

public static void main(String[] args) throws NoSuchMethodException {
    // This works, but method name is passed as a string, so this will compile
    // even if myMethod does not exist
    Method methodInfo = MyClass.class.getMethod("myMethod");

    // Here we pass reference to a method. It is somehow possible to
    // obtain java.lang.reflect.Method for myMethod inside printMethodName?
    printMethodName(MyClass::myMethod);
}

In other words I would like to have a code which is the equivalent of the following C# code:

    private static class InnerClass
    {
        public static void MyMethod()
        {
            Console.WriteLine("Hello");
        }
    }

    static void PrintMethodName(Action action)
    {
        // Can I get java.lang.reflect.Method in the same way?
        MethodInfo methodInfo = action.GetMethodInfo();
    }

    static void Main()
    {
        PrintMethodName(InnerClass.MyMethod);
    }

Answer

Mike Strobel picture Mike Strobel · Nov 7, 2013

No, there is no reliable, supported way to do this. You assign a method reference to an instance of a functional interface, but that instance is cooked up by LambdaMetaFactory, and there is no way to drill into it to find the method you originally bound to.

Lambdas and method references in Java work quite differently than delegates in C#. For some interesting background, read up on invokedynamic.

Other answers and comments here show that it may currently be possible to retrieve the bound method with some additional work, but make sure you understand the caveats.