Why did Java 8 introduce a new “::” operator for method references?

北慕城南 提交于 2019-11-29 06:23:15

问题


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 ?


回答1:


The following piece of code compiles fine in Java 8, but would be ambiguous without a new operator:

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

It wouldn't be clear whether A.addThemUp refers to the public IntBinaryOperator field or is an attempt to create a method reference.

Yes, it's a bit contrived. But you can't allow edge cases in programming language syntax.




回答2:


Fields and methods have separate name spaces, so there is the possibility of an ambiguity between a method name and a field name (which might then require even more rules to disambiguate). This is definitely a big problem for the "reuse some existing syntax" approach (which was, BTW, considered as a candidate, as were a number of other possibilities.)

But, I would turn the question around: is "overloading" an existing syntax like this really a good idea? (Your question assumes this, but this is an enormous assumption.) There's a big difference between "call method m / read field f" and "refer to method m / field f by name". Shouldn't the two kinds of expressions look different? What is the benefit of reusing an existing syntax to mean something completely different?

Further, there's a scalability issue with the approach you suggest: we'd never be able to do field references in the future without inventing a new syntax, which would then be different from the syntax for method references. While field references were not a must-have for lambda, never being able to finish the job here would be a big minus.

These are just a few of the various considerations that fed into this decision. In hindsight, I still think we made the right call here.




回答3:


Maybe they did it to make the C++ programmers feel more welcome in Java? /* In my opinion (dangerous words to use as a skeptic), operator:: is more natural to use on static methods, as it is the scope resolution operator in C++ */



来源:https://stackoverflow.com/questions/26590453/why-did-java-8-introduce-a-new-operator-for-method-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!