205 votes

Les fonctions de rappel en Java

Est-il un moyen de passer un appel de retour de la fonction dans une méthode en Java?

Le comportement que j'essaie d'imiter est une .Net Délégué passé à une fonction.

J'ai vu des gens en suggérant la création d'un objet distinct, mais qui semble exagéré, mais je suis conscient que, parfois, overkill est la seule façon de faire les choses.

175voto

Gant Points 9920

Si vous voulez dire quelque chose comme .NET délégué anonyme, je pense que Java de la classe anonyme peut être utilisé ainsi.

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

    }
}

44voto

cprcrack Points 3040

Pour plus de simplicité, vous pouvez utiliser un Exécutable:

private void runCallback(Runnable callback)
{
    // Run callback
    callback.run();
}

Utilisation:

runCallback(new Runnable()
{
    @Override
    public void run()
    {
        // Running callback
    }
});

23voto

Alex Fort Points 9961

Vous pouvez utiliser une interface. Voir ici: http://www.javaworld.com/javaworld/javatips/jw-javatip10.html

Alex

17voto

Michael Borgwardt Points 181658

Un peu tatillon:

J'ai semblent les gens suggérant la création d'un objet distinct, mais qui semble overkill

Le passage d'un rappel inclut la création d'un objet distinct dans pratiquement n'importe quel langage OO, de sorte qu'il peut à peine être considéré comme excessif. Tu veux sans doute dire qu'en Java, il vous oblige à créer une catégorie distincte, qui est plus détaillé (et de plus en plus gourmands en ressources) que dans les langues explicite de première classe de fonctions ou de fermetures. Cependant, anonyme classes au moins de réduire la verbosité et peut être utilisé en ligne.

7voto

Peter Wilkinson Points 2228

J'ai trouvé l'idée de la mise en œuvre de l'aide de l'refléter la bibliothèque intéressante et est venu avec ce qui, je pense, fonctionne très bien. Le seul inconvénient, c'est perdre le temps de compilation de vérifier que vous êtes de passage des paramètres valides.

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

Vous l'utiliser comme ceci

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X