为什么Java 8为方法引用引入了新的"::"运算符?

Sha*_*jun 23 java java-8 method-reference

在Java 8中,方法引用是使用::运算符完成的.

例如

// Class that provides the functionality via it's static method
public class AddableUtil {
  public static int addThemUp(int i1, int i2){
    return i1+i2;
  }
}

// Test class
public class AddableTest {
  // Lambda expression using static method on a separate class
  IAddable addableViaMethodReference = AddableUtil::addThemUp;
  ...
}
Run Code Online (Sandbox Code Playgroud)

你可以看到addableViaMethodReference现在的行为就像是一个别名AddableUtil::addThemUp.因此addableViaMethodReference()将执行相同的操作 AddableUtil.addThemUp()并返回相同的值.

他们为什么选择引入新的运营商而不是现有运营商?我的意思是,当函数名称结束时执行函数,()并在没有尾随时返回函数引用().

方法执行

AddableUtil.addThemUp();
Run Code Online (Sandbox Code Playgroud)

方法参考

AddableUtil.addThemUp;
Run Code Online (Sandbox Code Playgroud)

这不是更简单直观吗?AFAIK,AddableUtil.addThemUp当前不(Java 7)用于任何其他目的并抛出编译错误.为什么不利用这个机会而不是创建一个全新的运营商呢?

Dun*_*nes 33

下面的代码在Java 8中编译得很好,但如果没有新的运算符,它将是不明确的:

import java.util.function.IntBinaryOperator;

public class A {

  public static IntBinaryOperator addThemUp;

  public static int addThemUp(int i1, int i2) {
    return i1 + i2;
  }

  public static void main(String[] args) throws Exception {
    IntBinaryOperator operator = A::addThemUp;
  }
}
Run Code Online (Sandbox Code Playgroud)

不知道A.addThemUp是指公共IntBinaryOperator领域还是尝试创建方法参考.

是的,它有点做作.但是你不能在编程语言语法中允许边缘情况.

  • 实际上,你可以在编程语言语法中允许边缘情况,但最终你得到了Perl,没有人想要它.;) (5认同)

Bri*_*etz 16

字段和方法具有单独的名称空间,因此方法名称和字段名称之间可能存在歧义(这可能需要更多的规则来消除歧义).对于"重用一些现有语法"方法来说这肯定是一个大问题(BTW被认为是候选者,以及其他一些可能性.)

但是,我会回答这个问题:"重载"这样的现有语法真的是一个好主意吗?(你的问题假设了这一点,但这是一个巨大的假设.)"调用方法m /读取字段f"和"按名称引用方法m /字段f"之间存在很大差异.两种表达方式不应该看起来不一样吗?重用现有语法意味着完全不同的东西有什么好处?

此外,您建议的方法存在可伸缩性问题:如果不发明新语法,我们将来永远无法进行字段引用,这会与方法引用的语法不同.虽然野外参考不是lambda的必备条件,但永远无法完成这项工作将是一个很大的减号.

这些只是影响这一决定的各种考虑因素中的一小部分.事后来看,我仍然认为我们在这里做出了正确的决定.

  • 进一步证明这不值得关闭 - 你不能排除经过权威回答的Oracle人员.+1 (6认同)
  • 我们考虑了除了::之外的各种中缀语法,以及各种前缀语法(如&Foo.bar).当lambda语法也使用#时,Foo #bar更适合,但是当语法转到更多C#/ Scala风格时,变得不那么有吸引力了. (5认同)
  • @Duncan我的记忆,作为lambda-dev邮件列表上的一个主要潜伏者,正在考虑"#",但他们决定将其保留用于未来的潜在用途.IIRC甚至还有使用它的lambda版本. (3认同)