自定义类方法的方法引用



我有以下代码:

    Map<String, ReportConfig> reportConfigMap = reportFactory.getReportConfigMap();
    List<String> resultList = reportConfigMap.values()
            .parallelStream()
            .filter(Utility::shouldReportVisibleToUser)
            .map(ReportConfig::getName)
            .collect(Collectors.toList());

报告配置类代码

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流方法而不是不适用于我的自定义方法,该怎么办?我做错了什么,或者我完全误解了什么?

ReportConfig::getName大致相当于:

public static String getName(ReportConfig arbitraryObject) {
    ...
}

编译器在 ReportConfig 类中搜索与上述签名匹配的方法。由于实例方法隐式将this作为第一个参数,因此编译器发现实例方法getName()适用。此外,此签名匹配Function<ReportConfig, String>的类型参数,因此一切正常。

另一方面,使用与上述相同的推论,Test::test等效于:

public static ReportConfig test(Test arbitraryObject, ReportConfig r) {
    return r;
}

在这种情况下,编译器找到与上述签名匹配的方法public ReportConfig test(ReportConfig r),但是无法转换为Function<? extends ReportConfig,? extends ReportConfig> (而是转换为BiFunction<Test, ReportConfig, ReportConfig>(。因此,编译器求助于查找不存在的静态test方法。

要使其编译,请将test方法设置为静态,或使用test::test而不是Test::test

最新更新