我有一个方法,大约有十行代码。我想创建更多的方法来做完全相同的事情,除了一个会改变一行代码的小计算。这是一个传递函数指针来替换这一行的完美应用程序,但是Java没有函数指针。我最好的选择是什么?
当前回答
哇,为什么不创建一个Delegate类,这并不难,因为我已经为java做了,并使用它来传递参数,其中T是返回类型。我很抱歉,但作为一个c++ / c#程序员,一般只学习java,我需要函数指针,因为它们非常方便。如果你熟悉任何处理方法信息的类,你可以这样做。在java库中是java。lang。reflect。method。
如果你总是使用一个接口,你就必须实现它。在事件处理中,确实没有更好的方法来从处理程序列表中注册/取消注册,但对于委托,你需要传递函数而不是值类型,使委托类处理它outclasses一个接口。
其他回答
看看lambdaj
http://code.google.com/p/lambdaj/
特别是它新的闭包特征
http://code.google.com/p/lambdaj/wiki/Closures
你会发现一种非常易读的方式来定义闭包或函数指针,而无需创建无意义的接口或使用丑陋的内部类
从Java8开始,您可以使用lambdas,它在官方SE 8 API中也有库。
用法: 您只需要使用带有一个抽象方法的接口。 创建一个实例(你可能想使用java SE 8已经提供的实例),如下所示:
Function<InputType, OutputType> functionname = (inputvariablename) {
...
return outputinstance;
}
有关更多信息,请查看文档:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
匿名内部类
假设你想要传入一个带有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);
开源安全镜像项目将上面提到的一些解决方案泛化到一个向Java添加函数、委托和事件的库中。
有关特性的小抄,请参阅README或此stackoverflow答案。
至于函数,标准库引入了一个Fun接口和一些子接口(与泛型一起),它们组成了一个流畅的API,用于将方法用作类型。
Fun.With0Params<String> myFunctionField = " hello world "::trim;`
Fun.With2Params<Boolean, Object, Object> equals = Objects::equals;`
public void foo(Fun.With1ParamAndVoid<String> printer) throws Exception {
printer.invoke("hello world);
}
public void test(){
foo(System.out::println);
}
注意:
必须选择与目标签名中的参数数量相匹配的子接口。Fx,如果它有一个参数,选择Fun.With1Param。 泛型用于定义A)返回类型和B)签名的参数。
另外,请注意传递给foo()方法调用的方法引用的签名必须与方法foo定义的Fun匹配。如果不这样做,编译器将发出一个错误。
没有一个Java 8的答案给出了一个完整的、内聚的例子,所以它就来了。
声明接受“函数指针”的方法如下:
void doCalculation(Function<Integer, String> calculation, int parameter) {
final String result = calculation.apply(parameter);
}
通过为函数提供lambda表达式来调用它:
doCalculation((i) -> i.toString(), 2);
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap