是否有一种方法可以在Java方法中传递回调函数?

我试图模拟的行为是一个。net委托被传递给一个函数。

我看到有人建议创建一个单独的对象,但这似乎有点过分,但我意识到有时过度是做事的唯一方法。


当前回答

你也可以使用委托模式进行回调:

Callback.java

public interface Callback {
    void onItemSelected(int position);
}

PagerActivity.java

public class PagerActivity implements Callback {

    CustomPagerAdapter mPagerAdapter;

    public PagerActivity() {
        mPagerAdapter = new CustomPagerAdapter(this);
    }

    @Override
    public void onItemSelected(int position) {
        // Do something
        System.out.println("Item " + postion + " selected")
    }
}

CustomPagerAdapter.java

public class CustomPagerAdapter {
    private static final int DEFAULT_POSITION = 1;
    public CustomPagerAdapter(Callback callback) {
        callback.onItemSelected(DEFAULT_POSITION);
    }
}

其他回答

我最近开始做这样的事情:

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);
    }
}

它有点旧了,但不管怎样……我发现Peter Wilkinson的答案很好,除了它不适用于像int/Integer这样的原始类型。 问题是参数[i]的. getclass(),它返回实例java.lang。整数,另一方面,getMethod(methodName,parameters[])不会正确解释(Java的错误)…

我结合了丹尼尔·斯皮沃克(Daniel Spiewak)的建议(在他的回答中);成功的步骤包括:捕捉NoSuchMethodException -> getMethods() ->通过method.getName() ->查找匹配的一个,然后显式遍历参数列表并应用Daniels解决方案,例如识别类型匹配和签名匹配。

在Java 8中,这个任务很简单,如果你想在多线程场景中使用回调,你可以像下面这样做:

public  void methodA (int n, IntConsumer consumer) {
    
    // create a thread
    Thread t = new Thread(() -> {
        // some time consuming operation
        int result = IntStream.range(0, n).sum();
        // after the result is ready do something with it.
        consumer.accept(result);
    });
    t.start();
}

使用这个方法:

methodA(1000000, System.out::println);

当我在Java中需要这种功能时,我通常使用观察者模式。它确实意味着一个额外的对象,但我认为这是一种干净的方式,而且是一种被广泛理解的模式,有助于提高代码的可读性。

public class HelloWorldAnonymousClasses {

    //this is an interface with only one method
    interface HelloWorld {
        public void printSomething(String something);
    }

    //this is a simple function called from main()
    public void sayHello() {

    //this is an object with interface reference followed by the definition of the interface itself

        new HelloWorld() {
            public void printSomething(String something) {
                System.out.println("Hello " + something);
            }
        }.printSomething("Abhi");

     //imagine this as an object which is calling the function'printSomething()"
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp =
                new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }
}
//Output is "Hello Abhi"

基本上,如果你想让一个接口的对象 不可能,因为接口不能有对象。

选择是让某个类实现接口,然后使用该类的对象调用该函数。 但是这种方法非常冗长。

或者,编写新的HelloWorld() (*oberserve这是一个接口而不是一个类),然后接着定义接口方法本身。(*这个定义实际上是匿名类)。 然后获得对象引用,通过它可以调用方法本身。