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

在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; ... } 

您可以看到addableViaMethodReference现在就像AddableUtil::addThemUp的别名。 因此addableViaMethodReference()将执行与AddableUtil.addThemUp()相同的操作并返回相同的值。

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

方法执行

 AddableUtil.addThemUp(); 

方法参考

 AddableUtil.addThemUp; 

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

下面的代码在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; } } 

尚不清楚A.addThemUp是指公共IntBinaryOperator字段还是尝试创建方法引用。

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

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

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

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

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

也许他们这样做是为了让C ++程序员在Java中更受欢迎? / *在我看来(用作怀疑论者的危险词),operator ::在静态方法上使用更自然,因为它是C ++中的范围解析运算符* /