我有以下代码:
Map<String, ReportConfig> reportConfigMap = reportFactory.getReportConfigMap();
List<String> resultList = reportConfigMap.values()
.parallelStream()
.filter(Utility::shouldReportVisibleToUser)
.map(ReportConfig::getName)
.collect(Collectors.toList());
ReportConfig类代码
public class ReportConfig implements Comparable<ReportConfig> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
对于代码.map(ReportConfig::getName)
的部分,我使用ReportConfig::getName
传递getName方法的方法引用,看起来好像getName是ReportConfig类的静态方法,但实际上它是非静态方法那个班。
如果我尝试在自定义函数中执行相同的操作,那么java会给出错误,其中包含:Cannot make a static reference to the non-static method
。例如,以下代码将无效:
public class Test{
public static void main (String[] agrs){
Test test = new Test();
test.executeService(Test::test);
}
public static ReportConfig executeService(Function<? extends ReportConfig,? extends ReportConfig> mapper){
return mapper.apply(null);
}
public ReportConfig test(ReportConfig r){
return r;
}
}
我的问题是如果为map
方法工作而不是为我的自定义方法工作?有什么我做错了或者我完全误解了什么吗?
答案 0 :(得分:3)
ReportConfig::getName
is roughly equivalent to:
public static String getName(ReportConfig arbitraryObject) {
...
}
The compiler searches the ReportConfig
class for a method that matches the above signature. Since instance methods implicitly take this
as the first parameter, the compiler finds the instance method getName()
to be applicable. Furthermore, this signature matches the type arguments of a Function<ReportConfig, String>
, so everything works fine.
On the other hand, going with the same inference as above, Test::test
would be equivalent to:
public static ReportConfig test(Test arbitraryObject, ReportConfig r) {
return r;
}
In this case, the compiler finds the method public ReportConfig test(ReportConfig r)
which matches the above signature, but
which cannot be converted to a Function<? extends ReportConfig,? extends ReportConfig>
(it would be converted to a BiFunction<Test, ReportConfig, ReportConfig>
instead). Therefore the compiler resorts to finding a static test
method, which does not exist.
To make it compile, either make the test
method static, or use test::test
instead of Test::test
.