请查看以下代码:
Method methodInfo = MyClass.class.getMethod("myMethod");
这是可行的,但方法名是作为字符串传递的,因此即使myMethod不存在,也会编译。
另一方面,Java8引入了一个方法引用特性。它在编译时被检查。可以使用这个特性来获取方法信息吗?
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);
}
虽然我自己没有尝试过,但我认为答案是“不”,因为方法引用在语义上与lambda相同。
在我的例子中,我正在寻找一种方法来在单元测试中摆脱它:
Point p = getAPoint();
assertEquals(p.getX(), 4, "x");
assertEquals(p.getY(), 6, "x");
正如您所看到的,有人正在测试方法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);
并且断言的描述保证与代码同步。
下降趋势:
然而,它确实展示了一种如何做到这一点的方法。
不,没有可靠的、受支持的方法来做到这一点。您将方法引用分配给函数式接口的实例,但该实例是由LambdaMetaFactory
编写的,并且无法深入其中以找到您最初绑定的方法。
Java中的lambda和方法引用的工作方式与C#中的委托截然不同。有关一些有趣的背景知识,请阅读invokedynamic。
这里的其他答案和注释表明,目前可以通过一些额外的工作来检索绑定方法,但请确保您理解这些注意事项。
主要内容:1 Java8 方法引用的介绍,2 Java8 方法引用的分类,3 Java8 方法引用:引用静态方法,4 Java8 方法引用:引用实例方法,5 Java8 方法引用:引用构造方法1 Java8 方法引用的介绍 Java提供了一个新功能,称为Java 8中的方法引用。方法引用用于引用功能接口的方法。它是lambda表达式的紧凑和简单形式。每次使用lambda表达式仅引用方法时,都可以将lambda表达式替换为方法引用。在本教程中,我们将详细解释方法参考概念。 2 Java8 方法引用
我有一个Employee类,如下所示 我正在尝试使用MethodReference获得如下所示的工资 知道如何只使用MethodReference获得工资吗 现在在toString看到一个问题
本文向大家介绍使用Java8中的方法引用来引用实例方法,包括了使用Java8中的方法引用来引用实例方法的使用技巧和注意事项,需要的朋友参考一下 Java中的Lambda表达式使您可以将功能作为参数传递给方法。您也可以使用lambda表达式调用现有方法。 方法引用是简单,易于阅读的lambda表达式,可通过lambda表达式中的名称来调用/引用和现有方法。 语法 以下是在Java中引用实例方法的语法
我对方法引用在Java8中是如何工作的有些困惑。我编写了下面的代码段用于过滤文件夹中的隐藏文件。他们正在产生正确的结果。我不理解->listFiles方法的方法签名是如何在这个代码段的选项2中工作的。 这是我在Java8文档中发现的
我正在通过一个例子,它从与方法引用相关的当前目录中提取一个隐藏文件数组,如下所述 使用匿名内部类实现 使用方法参考实现 我的问题是接口只有一个抽象方法(),而实现accept-method-using-method-reference在类中使用的有效性如何。我了解到,只有当参数与抽象方法匹配时,我们才能应用方法引用,但是这里method有一个类型的参数,但是没有参数。你能解释一下它的有效性吗。
Obj.TestPredicate(list,String::Contains); 我在“String::Contains”中得到错误:不能从静态上下文引用非静态方法。但contains不是静态方法。我被那些小费弄糊涂了。 我的代码如下: (2)如果func是一个实例方法,那么someClass::func是一个lambda,它使用第一个参数作为实例,正如您所想的:(a,b,c)->a.func(