我有一个方法,大约有十行代码。我想创建更多的方法来做完全相同的事情,除了一个会改变一行代码的小计算。这是一个传递函数指针来替换这一行的完美应用程序,但是Java没有函数指针。我最好的选择是什么?
当前回答
如果你只有一个不同的行,你可以添加一个参数,比如一个标志和一个If (flag)语句,它调用一行或另一行。
其他回答
没有一个Java 8的答案给出了一个完整的、内聚的例子,所以它就来了。
声明接受“函数指针”的方法如下:
void doCalculation(Function<Integer, String> calculation, int parameter) {
final String result = calculation.apply(parameter);
}
通过为函数提供lambda表达式来调用它:
doCalculation((i) -> i.toString(), 2);
匿名内部类
假设你想要传入一个带有String参数的函数,该参数返回一个整型。 首先,如果不能重用现有的接口,则必须定义一个接口,该接口的唯一成员是该函数。
interface StringFunction {
int func(String param);
}
接受指针的方法只接受StringFunction实例,如下所示:
public void takingMethod(StringFunction sf) {
int i = sf.func("my string");
// do whatever ...
}
并且会被这样称呼:
ref.takingMethod(new StringFunction() {
public int func(String param) {
// body
}
});
编辑:在Java 8中,你可以用lambda表达式调用它:
ref.takingMethod(param -> bodyExpression);
对于每个“函数指针”,我会创建一个小的函子类来实现你的计算。 定义一个所有类都将实现的接口,并将这些对象的实例传递到更大的函数中。这是“命令模式”和“战略模式”的结合。
@sblundy的例子很好。
在用Java编程时,我真正怀念的一件事是函数回调。在递归处理层次结构中,需要不断地呈现这些元素,您希望为每个元素执行特定的操作。比如遍历目录树,或者处理数据结构。我内心的极简主义者讨厌为每个特定的情况定义接口和实现。
有一天我发现自己在想为什么不呢?我们有方法指针——method对象。通过优化JIT编译器,反射调用实际上不再带来巨大的性能损失。此外,除了将文件从一个位置复制到另一个位置之外,反射方法调用的成本变得微不足道。
随着我对它的深入思考,我意识到OOP范式中的回调需要将对象和方法绑定在一起——进入回调对象。
请查看我的基于反射的Java回调解决方案。免费供任何用途。
如果有人试图传递一个函数,该函数使用一组参数来定义其行为,但使用另一组参数来执行,就像Scheme的:
(define (function scalar1 scalar2)
(lambda (x) (* x scalar1 scalar2)))
参见Java中参数定义行为的传递函数