是否有一种方法可以在Java方法中传递回调函数?
我试图模拟的行为是一个。net委托被传递给一个函数。
我看到有人建议创建一个单独的对象,但这似乎有点过分,但我意识到有时过度是做事的唯一方法。
是否有一种方法可以在Java方法中传递回调函数?
我试图模拟的行为是一个。net委托被传递给一个函数。
我看到有人建议创建一个单独的对象,但这似乎有点过分,但我意识到有时过度是做事的唯一方法。
当前回答
方法在Java中还不是一级对象;不能将函数指针作为回调函数传递。相反,创建一个对象(通常实现一个接口),其中包含您需要的方法并传递该方法。
对于Java中的闭包(它将提供您正在寻找的行为)已经提出了建议,但在即将发布的Java 7中不会包含任何建议。
其他回答
当我在Java中需要这种功能时,我通常使用观察者模式。它确实意味着一个额外的对象,但我认为这是一种干净的方式,而且是一种被广泛理解的模式,有助于提高代码的可读性。
如果你指的是。net匿名委托,我认为Java的匿名类也可以使用。
public class Main {
public interface Visitor{
int doJob(int a, int b);
}
public static void main(String[] args) {
Visitor adder = new Visitor(){
public int doJob(int a, int b) {
return a + b;
}
};
Visitor multiplier = new Visitor(){
public int doJob(int a, int b) {
return a*b;
}
};
System.out.println(adder.doJob(10, 20));
System.out.println(multiplier.doJob(10, 20));
}
}
我最近开始做这样的事情:
public class Main {
@FunctionalInterface
public interface NotDotNetDelegate {
int doSomething(int a, int b);
}
public static void main(String[] args) {
// in java 8 (lambdas):
System.out.println(functionThatTakesDelegate((a, b) -> {return a*b;} , 10, 20));
}
public static int functionThatTakesDelegate(NotDotNetDelegate del, int a, int b) {
// ...
return del.doSomething(a, b);
}
}
检查闭包是如何在lambdaj库中实现的。它们实际上有一个非常类似于c#委托的行为:
http://code.google.com/p/lambdaj/wiki/Closures
从Java 8开始,有lambda和方法引用:
Oracle文档:Lambda表达式 Oracle文档:方法引用
例如,如果你想要一个功能接口a -> B,你可以使用:
import java.util.function.Function;
public MyClass {
public static String applyFunction(String name, Function<String,String> function){
return function.apply(name);
}
}
你可以这样称呼它:
MyClass.applyFunction("42", str -> "the answer is: " + str);
// returns "the answer is: 42"
你也可以通过类方法。例如:
@Value // lombok
public class PrefixAppender {
private String prefix;
public String addPrefix(String suffix){
return prefix +":"+suffix;
}
}
然后你可以这样做:
PrefixAppender prefixAppender= new PrefixAppender("prefix");
MyClass.applyFunction("some text", prefixAppender::addPrefix);
// returns "prefix:some text"
注意:
这里我使用了函数接口Function<A,B>,但是包java.util.function中还有许多其他的接口。最值得注意的是
供应商:void -> 消费者:A ->无效 双消费者:(A,B) ->无效 功能:A -> B biffunction:(A,B) -> C
以及许多其他专门研究某些输入/输出类型的程序。然后,如果它不提供你需要的,你可以创建自己的FunctionalInterface:
@FunctionalInterface
interface Function3<In1, In2, In3, Out> { // (In1,In2,In3) -> Out
public Out apply(In1 in1, In2 in2, In3 in3);
}
使用示例:
String computeAnswer(Function3<String, Integer, Integer, String> f){
return f.apply("6x9=", 6, 9);
}
computeAnswer((question, a, b) -> question + "42");
// "6*9=42"
你也可以用抛出异常来实现:
@FunctionalInterface
interface FallibleFunction<In, Out, Ex extends Exception> {
Out get(In input) throws Ex;
}
public <Ex extends IOException> String yo(FallibleFunction<Integer, String, Ex> f) throws Ex {
return f.get(42);
}