Java 中的回调函数
2022-08-31 06:21:57
有没有办法在Java方法中传递回调函数?
我试图模仿的行为是将 .Net 委托传递给函数。
我见过有人建议创建一个单独的对象,但这似乎有些过分,但我知道有时过度杀戮是做事的唯一方法。
有没有办法在Java方法中传递回调函数?
我试图模仿的行为是将 .Net 委托传递给函数。
我见过有人建议创建一个单独的对象,但这似乎有些过分,但我知道有时过度杀戮是做事的唯一方法。
如果你指的是.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));
}
}
从 Java 8 开始,有 lambda 和方法引用:
例如,如果你想要一个功能接口,你可以使用: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
Supplier
:void -> A
Consumer
:A -> void
BiConsumer
:(A,B) -> void
Function
:A -> B
BiFunction
:(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);
}