为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕尼黑5688855 2019-10-19 15:18:06
请看下面的代码:Method methodInfo = MyClass.class.getMethod("myMethod");此方法有效,但是方法名称作为字符串传递,因此即使myMethod不存在,也可以编译。另一方面,Java 8引入了方法引用功能。在编译时检查它。可以使用此功能获取方法信息吗?printMethodName(MyClass::myMethod);完整示例:@FunctionalInterfaceprivate 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
查看完整描述

3 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

就我而言,我正在寻找一种在单元测试中摆脱这种情况的方法:


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

    final String methodName = getMethodName(object.getClass(), getter);

    assertEquals(getter.apply(object), expected, methodName);

}


@SuppressWarnings("unchecked")

private<T> String getMethodName(final Class<?> clazz, final Function<T, ?> getter) {

    final Method[] method = new Method[1];

    getter.apply((T)Mockito.mock(clazz, Mockito.withSettings().invocationListeners(methodInvocationReport -> {

        method[0] = ((InvocationOnMock) methodInvocationReport.getInvocation()).getMethod();

    })));

    return method[0].getName();

}

不,我可以简单地使用


assertPropertyEqual(p, Point::getX, 4);

assertPropertyEqual(p, Point::getY, 6);

并确保断言的描述与代码同步。


缺点:


会比上面稍微慢一点

需要Mockito工作

除上述用例外,对其他任何功能几乎没有用。

但是,它确实显示了一种方法。


查看完整回答
反对 回复 2019-10-19
  • 3 回答
  • 0 关注
  • 639 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信