Intellij-可以替换为方法参考


74

总是在使用这样的lambda表达式时:

.map(obj -> foo.makeSomething(obj))

IntelliJ建议:“可以用方法引用代替...”。当我尝试时:

.map(Foo::makeSomething)

我得到以下语句:“不能从静态上下文中引用非静态方法”。

为什么Idea建议我如果方法引用不正确,我应该使用方法引用?


11
它实际上建议更换吗?还是仅仅是您在写自己的东西?我本来以为foo::makeSomething会奏效。
安迪·特纳

4
foo::makeSomething。您想在对象foo上而不是在类Foo上调用方法。您也可以只让IntelliJ为您转换代码(Alt-Enter)。
JB Nizet


您正在使用哪个版本的IntelliJ IDEA?
Mike Nakis '17

@JBNizet TY表示快捷方式-jeez对我的一生我不知道该如何告诉IJ做到这一点!它给出的只是一个无用的弹出窗口,甚至是更多无用的建议,用于与该确切代码无关的设置!现在越来越多地倾向于Eclipse :(它非常具有右键单击选项
killjoy

Answers:


98

在您撰写时:

map(Foo::makeSomething)

编译器期望以下两种可能性之一:

  • Foo.makeSomething()对必须定义为的lambda的第一个参数调用实例方法Foo

  • 调用Foo.makeSomething()静态方法。

编译器消除了第一种可能性,因为声明的lambda的第一个参数obj不是a Foo

根据您的错误消息,Foo.makeSomething()是一个实例方法:

无法从静态上下文引用非静态方法”

因此,第二种可能性(调用Foo.makeSomething()静态方法)也不合法,因为makeSomething()它不是静态的。


实际上,您想要的是将makeSomething()实例方法应用于不属于lambda参数一部分的变量。
您可以做到,但是您需要使用其他语法。

不用指定Foo::,而是使用foo::
这样,实例方法makeSomething()将应用于foo变量:

map(foo::makeSomething)

IntelliJ意图

注意,报告lambda可以用方法引用替换的检查也可以由IDE通过意图自动重构。
为此,请将光标放在lambda上(在光标上的任意位置)并显示上下文意图(Alt+Enter默认情况下)。您应该看到意图:

用方法参考替换lambda

一些截图:

意向命题

意向结果


6
非常感谢,我不知道可以对对象使用引用。我在想它仅在我调用ClassName :: metohd时才有效。
用户

1
不客气:)实际上,您可以在三种情况下应用方法引用:1)静态方法,2)用于lambda参数的实例方法,以及3)用于未在lambda参数中声明的变量的实例方法。对于最后一种情况,语法确实不同。
davidxxx '17

就像@Eli已经说过的,如果方法在同一个Class中,那么您必须使用'this'而不是Class名称。
CodeSlave
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.