23

In Java 8 method references are done using the :: operator.

For Example

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

You can see that the addableViaMethodReference now acts like an alias to AddableUtil::addThemUp. So addableViaMethodReference() will perform the same action as AddableUtil.addThemUp() and return the same value.

Why did they choose to introduce a new operator instead of using an existing one ? I mean, execute a function when the function name ends with () and return the function reference when there is no trailing ().

Method Execution

AddableUtil.addThemUp();

Method reference

AddableUtil.addThemUp;

Wouldn't this be much simpler and intuitive ? AFAIK, AddableUtil.addThemUp doesn't currently (Java 7) serve any other purpose and throws a compilation error. Why not use that opportunity instead of creating an entirely new operator ?

4

3 回答 3

33

以下代码在 Java 8 中编译得很好,但如果没有 new 运算符会很模糊:

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字段还是尝试创建方法引用。

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

于 2014-10-27T15:40:52.130 回答
16

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

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

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

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

于 2014-10-27T16:56:46.170 回答
1

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

于 2014-10-29T05:57:03.397 回答