Binding method for a custom class method
I have the following code:
Map<String, ReportConfig> reportConfigMap = reportFactory.getReportConfigMap();
List<String> resultList = reportConfigMap.values()
.parallelStream()
.filter(Utility::shouldReportVisibleToUser)
.map(ReportConfig::getName)
.collect(Collectors.toList());
ReportConfig class code
public class ReportConfig implements Comparable<ReportConfig> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
for a piece of code .map(ReportConfig::getName)
, I am passing a method reference to the getName method using ReportConfig::getName
, which looks like getName is a static method of the ReportConfig class, but in fact it is a non-static method of that class.
If I try to do the same in your user-defined function, then java will generate an error that says: Cannot make a static reference to the non-static method
. For example, the following code will not work:
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;
}
}
My question is, how does this work for a map
stream method and not work for my custom method? Is there something I am doing wrong, or something completely wrong?
source to share
ReportConfig::getName
roughly equivalent to:
public static String getName(ReportConfig arbitraryObject) {
...
}
The compiler looks for a class ReportConfig
for the method that matches the above signature. Since instance methods implicitly take this
as the first parameter, the compiler finds an instance method applicable getName()
. Also, this signature matches the type arguments Function<ReportConfig, String>
, so everything works fine.
On the other hand, based on the same output as above Test::test
would be equivalent to:
public static ReportConfig test(Test arbitraryObject, ReportConfig r) {
return r;
}
In this case, the compiler finds a method public ReportConfig test(ReportConfig r)
that matches the above signature, but which cannot be converted toFunction<? extends ReportConfig,? extends ReportConfig>
(it will instead be converted to BiFunction<Test, ReportConfig, ReportConfig>
). Therefore, the compiler resorts to looking for a static method test
that does not exist.
To do compilation, make a static method test
or use Test::test
instead Test::test
.
source to share