当前位置: 首页 > 知识库问答 >
问题:

为什么要编译此方法引用赋值?

刘修能
2023-03-14

我很难理解为什么要编译以下代码:

public class MethodRefs {

    public static void main(String[] args) {
        Function<MethodRefs, String> f;

        f = MethodRefs::getValueStatic;

        f = MethodRefs::getValue;
    }

    public static String getValueStatic(MethodRefs smt) {
        return smt.getValue();
    }

    public String getValue() {
        return "4";
    }

}

我可以理解为什么第一个赋值是有效的-getValueStatic显然与指定的函数类型匹配(它接受一个MethodRefs对象并返回一个字符串),但第二个赋值让我很困惑-getValue方法不接受任何参数,那么为什么将其赋值给f仍然有效呢?


共有3个答案

孔正文
2023-03-14

非静态方法本质上将其this引用作为一种特殊的参数。通常该参数以特殊的方式编写(在方法名称之前,而不是在它之后的括号中),但概念是相同的。getValue方法接受一个omeodRefs对象(其this)并返回一个字符串,因此它与函数兼容

华星驰
2023-03-14

让我们把它充实一点:

import java.util.function.Function;

public class MethodRefs {

  public static void main(String[] args) {
    Function<MethodRefs, String> f;


    final MethodRefs ref = new MethodRefs();

    f = MethodRefs::getValueStatic;
    f.apply(ref);
    //is equivalent to 
    MethodRefs.getValueStatic(ref);

    f = MethodRefs::getValue;
    f.apply(ref);
    //is now equivalent to 
    ref.getValue();
  }

  public static String getValueStatic(MethodRefs smt) {
    return smt.getValue();
  }

  public String getValue() {
    return "4";
  }
}
班昱
2023-03-14

第二张

f = MethodRefs::getValue;

与相同

f = (MethodRefs m) -> m.getValue();

对于非静态方法,始终有一个隐式参数,在被调用方中表示为this。

注意:实现在字节码级别略有不同,但它做的是相同的事情。

 类似资料:
  • 问题内容: 在方法或类范围内,下面的行进行编译(带有警告): 在类范围中, 变量获取其默认值 ,以下给出“未定义引用”错误: 它不是第一个应该以相同的“未定义参考”错误结束吗?还是第二行应该编译?还是我缺少什么? 问题答案: tl; dr 对于 字段 ,是非法的,因为它是对的非法前向引用。您实际上可以通过编写来解决此问题,该文件可以毫无抱怨地进行编译。 对于 局部变量 ,是非法的,因为未在使用前进

  • 问题内容: 以下Java代码无法编译: 编译器报告: 奇怪的是,标记为“ OK”的行可以正常编译,但是标记为“ Error”的行失败。它们看起来基本相同。 问题答案: 您的lambda需要与保持一致。如果您参考JLS#15.27.3(Lambda的类型): 如果满足以下所有条件,则lambda表达式与函数类型一致: […] 如果函数类型的结果为void,则lambda主体为语句表达式(第14.8节

  • 问题内容: 该程序在Java 7中(或在Java 8中带有)可以很好地编译,但是在Java 8中无法编译: 结果: 换句话说,这是Java 7和8之间的 反向 源不兼容。我已经遍历了Java SE 8和Java SE 7 列表之间的不兼容性,但是没有找到任何适合我的问题的东西。 那么,这是一个错误吗? 环境: 问题答案: 感谢您的报告。这看起来像个错误。我会照顾好它,并且一旦我们有更多关于为什么发

  • 它编译,并工作... 好的,在最后一个问题中,使用了一个类中的静态方法。 但现在不同了:是的字段,是的;它也是一个,有一个方法,在本例中,该方法恰好与的签名匹配,而所期望的是。 这里是一个完全不同的范围,因为我启动了一个新的实例,并且可以在这个实例构建后立即使用方法引用! 那么,方法引用真的是任何服从签名的方法吗?有什么限制?是否存在可以构建“@functionalinterface兼容”的方法而

  • 问题内容: 为什么要编译Python脚本?您可以直接从.py文件运行它们,并且效果很好,那么在性能上有什么优势吗? 我还注意到,我的应用程序中的某些文件被编译为.pyc,而另一些则没有,为什么? 问题答案: 它被编译为字节码,可以更快,更快速地使用。 无法编译某些文件的原因是,每次运行脚本时都会重新编译与之一起调用的主脚本。所有导入的脚本将被编译并存储在磁盘上。 Ben Blank的 重要补充:

  • 我使用比较器对流进行排序,遇到了一个我不理解的编译器错误。 假设我有以下课程: 我正在创建两个比较器,以按日期对s进行排序,一个按自然顺序,另一个按相反顺序。编译以下代码: 意识到是在上定义的,我想我会尝试以下操作: (对我来说)令人惊讶的是,rev2的代码编译正常,而rev1的代码产生以下错误: 为什么我会收到这些编译器错误?为什么我可以在从构建时有效地规避它们? (如果相关的话,我正在使用Ec