猿问

如何获取Java 8方法参考的MethodInfo?

请看下面的代码:


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

此方法有效,但是方法名称作为字符串传递,因此即使myMethod不存在,也可以编译。


另一方面,Java 8引入了方法引用功能。在编译时检查它。可以使用此功能获取方法信息吗?


printMethodName(MyClass::myMethod);

完整示例:


@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);

}

换句话说,我希望有一个等效于以下C#代码的代码:


    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);

    }

Java  反射 lambda  java-8


慕尼黑5688855
浏览 640回答 3
3回答

汪汪一只猫

就我而言,我正在寻找一种在单元测试中摆脱这种情况的方法:Point p = getAPoint();assertEquals(p.getX(), 4, "x");assertEquals(p.getY(), 6, "x");如您所见,有人正在测试Method getAPoint并检查坐标是否符合预期,但是在每个断言的描述中均已复制并且与所检查的内容不同步。最好只写一次。根据@ddan的想法,我使用Mockito构建了代理解决方案:private<T> void assertPropertyEqual(final T object, final Function<T, ?> getter, final Object expected) {&nbsp; &nbsp; final String methodName = getMethodName(object.getClass(), getter);&nbsp; &nbsp; assertEquals(getter.apply(object), expected, methodName);}@SuppressWarnings("unchecked")private<T> String getMethodName(final Class<?> clazz, final Function<T, ?> getter) {&nbsp; &nbsp; final Method[] method = new Method[1];&nbsp; &nbsp; getter.apply((T)Mockito.mock(clazz, Mockito.withSettings().invocationListeners(methodInvocationReport -> {&nbsp; &nbsp; &nbsp; &nbsp; method[0] = ((InvocationOnMock) methodInvocationReport.getInvocation()).getMethod();&nbsp; &nbsp; })));&nbsp; &nbsp; return method[0].getName();}不,我可以简单地使用assertPropertyEqual(p, Point::getX, 4);assertPropertyEqual(p, Point::getY, 6);并确保断言的描述与代码同步。缺点:会比上面稍微慢一点需要Mockito工作除上述用例外,对其他任何功能几乎没有用。但是,它确实显示了一种方法。
随时随地看视频慕课网APP

相关分类

Java
我要回答