在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)没有任何其他目的,并抛出编译错误。为什么不利用这个机会而不是创建一个全新的运营商呢?
答案 0 :(得分: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;
}
}
不清楚A.addThemUp
是指公共IntBinaryOperator
字段还是尝试创建方法引用。
是的,这有点做作。但是你不能在编程语言语法中允许边缘情况。
答案 1 :(得分:16)
字段和方法具有单独的名称空间,因此方法名称和字段名称之间可能存在歧义(这可能需要更多规则来消除歧义)。对于"重用一些现有语法来说,这绝对是一个大问题。方法(BTW,被视为候选人,以及许多其他可能性。)
但是,我会回答这个问题:是"重载"像这样的现有语法真的是个好主意吗? (你的问题假设了这一点,但这是一个巨大的假设。)"呼叫方法m /读取字段f"之间存在很大差异。和"按名称"表示方法m /字段f。难道这两种表达方式看起来不一样吗?重用现有语法意味着完全不同的东西有什么好处?
此外,您建议采用的方法存在可扩展性问题:如果不发明新语法,我们将来永远无法进行字段引用,这会与方法引用的语法不同。虽然野外参考不是lambda的必备条件,但永远无法完成这项工作将是一个很大的减号。
这些只是导致这一决定的各种考虑因素中的一小部分。事后来看,我仍然认为我们在这里做出了正确的决定。
答案 2 :(得分:1)
也许他们这样做是为了让C ++程序员在Java中更受欢迎? / *在我看来(用作怀疑论者的危险词),operator ::在静态方法上使用更自然,因为它是C ++中的范围解析运算符* /