Oma*_*eji 170 java function-pointers callback
有没有办法在Java方法中传递回调函数?
我试图模仿的行为是传递给函数的.Net委托.
我见过人们建议创建一个单独的对象,但这似乎有些过分,但我知道有时矫枉过正是唯一的做法.
Gan*_*ant 153
如果你的意思是.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));
}
}
Run Code Online (Sandbox Code Playgroud)
Juh*_*uh_ 33
从Java 8开始,有lambda和方法引用:
例如,让我们定义:
import java.util.function.Function;
public MyClass {
public static String applyFunction(String name, Function<String,String> function){
return function.apply(name);
}
}
Run Code Online (Sandbox Code Playgroud)
和
MyClass.applyFunction("42", str -> "the answer is: " + str);
// returns "the answer is: 42"
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
@Value // lombok
public class PrefixAppender {
private String prefix;
public String addPrefix(String suffix){
return prefix +":"+suffix;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以在github上找到一个例子,这里是:julien-diener/MethodReference.
cpr*_*ack 26
为简单起见,您可以使用Runnable:
private void runCallback(Runnable callback)
{
// Run callback
callback.run();
}
Run Code Online (Sandbox Code Playgroud)
用法:
runCallback(new Runnable()
{
@Override
public void run()
{
// Running callback
}
});
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 16
有点挑剔:
我似乎有人建议创建一个单独的对象,但这似乎有点过分
传递回调包括用几乎任何OO语言创建一个单独的对象,因此很难被认为是过度杀伤.你可能意味着在Java中,它需要你创建一个单独的类,它比具有显式的第一类函数或闭包的语言更冗长(并且更加资源密集).但是,匿名类至少可以减少冗长,并且可以内联使用.
Bis*_*mad 14
然而我看到最优选的方式是我正在寻找的......它基本上来自这些答案,但我不得不操纵它更多余和高效.. 我想每个人都在寻找我想出的东西
首先使界面变得简单
public interface myCallback {
void onSuccess();
void onError(String err);
}
Run Code Online (Sandbox Code Playgroud)
现在要在你希望处理结果的时候运行这个回调 - 更有可能在异步调用之后运行并且你想运行一些依赖于这些重新组合的东西
// import the Interface class here
public class App {
public static void main(String[] args) {
// call your method
doSomething("list your Params", new myCallback(){
@Override
public void onSuccess() {
// no errors
System.out.println("Done");
}
@Override
public void onError(String err) {
// error happen
System.out.println(err);
}
});
}
private void doSomething(String param, // some params..
myCallback callback) {
// now call onSuccess whenever you want if results are ready
if(results_success)
callback.onSuccess();
else
callback.onError(someError);
}
}
Run Code Online (Sandbox Code Playgroud)
doSomething 是一个函数需要一些时间你想要添加一个回调来通知你结果来了,将回调接口添加为此方法的参数
小智 9
在Java 8中使用lambdas非常容易.
public interface Callback {
void callback();
}
public class Main {
public static void main(String[] args) {
methodThatExpectsACallback(() -> System.out.println("I am the callback."));
}
private static void methodThatExpectsACallback(Callback callback){
System.out.println("I am the method.");
callback.callback();
}
}
Run Code Online (Sandbox Code Playgroud)
我发现使用反射库实现的想法很有趣,并提出了我认为非常有效的.唯一的缺点是丢失编译时检查您是否传递了有效参数.
public class CallBack {
private String methodName;
private Object scope;
public CallBack(Object scope, String methodName) {
this.methodName = methodName;
this.scope = scope;
}
public Object invoke(Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Method method = scope.getClass().getMethod(methodName, getParameterClasses(parameters));
return method.invoke(scope, parameters);
}
private Class[] getParameterClasses(Object... parameters) {
Class[] classes = new Class[parameters.length];
for (int i=0; i < classes.length; i++) {
classes[i] = parameters[i].getClass();
}
return classes;
}
}
Run Code Online (Sandbox Code Playgroud)
你这样使用它
public class CallBackTest {
@Test
public void testCallBack() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestClass testClass = new TestClass();
CallBack callBack = new CallBack(testClass, "hello");
callBack.invoke();
callBack.invoke("Fred");
}
public class TestClass {
public void hello() {
System.out.println("Hello World");
}
public void hello(String name) {
System.out.println("Hello " + name);
}
}
}
Run Code Online (Sandbox Code Playgroud)
方法不是(还)Java中的第一类对象; 你不能将函数指针作为回调传递.相反,创建一个包含所需方法并传递的对象(通常实现一个接口).
已经提出了Java中的闭包建议 - 这将提供您正在寻找的行为 - 但是没有一个将包含在即将发布的Java 7版本中.