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?

+3


source to share


1 answer


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

.

+3


source







All Articles