2017-04-07 3 views
1

J'ai un objet foncteur:Comment appeler la fonction des objets foncteur sans invoquer la méthode d'appel

private static Func1<MyEvent, Observable<Data>> getDataOnEvent = new Func1<MyEvent, Observable<Data>>() { 
    @Override 
    public Observable<Data> call(MyEvent event) { 
     return ApiFactory.get().getData() 
    } 
}; 

Pour son invocation que je dois faire ceci:

result = getDataOnEvent.call(someEvent) 

Est-il possible de le faire à la place:

result = getDataOnEvent(someEvent) 

Comme il est fait avec Python et Javascript? Peut-être une nouvelle version de Java OU une bibliothèque comme Lombok?

+0

Ce type de fonctionnalité est pris en charge dans les fermetures de Groovy, mais je ne peux pas penser à quoi que ce soit où il est pris en charge en Java. – Brian

+0

Vous pouvez créer une méthode contenant l'appel, mais je pense que ce n'est pas vraiment ce que vous voulez – SilverNak

+0

Également supporté par Kotlin. –

Répondre

1

utiliser juste,

private static Observable<Data> getDataOnEvent(MyEvent event) { 
    return ApiFactory.get().getData() 
} 

et vous pouvez appeler result = getDataOnEvent(someEvent); chaque fois que vous en avez besoin. Comme vous pouvez le voir, en écrivant de cette façon, vous économiserez encore plus de code de chaudière que les cinq lettres .call du côté de l'invocation.

Si Func1 est une interface fonctionnelle, vous pouvez utiliser ContainingClass::getDataOnEvent partout où un Func1<MyEvent, Observable<Data>> est prévu. Vous pouvez également enregistrer dans une variable static, si vous préférez utiliser l'identifiant simple, getDataOnEvent en fonction:

private static Func1<MyEvent, Observable<Data>> getDataOnEvent 
               = ContainingClass::getDataOnEvent; 

Ensuite, vous pouvez utiliser getDataOnEvent(event) appeler ou getDataOnEvent de s'y référer comme Func1 exemple chaque fois que vous en avez besoin .

Si Func1 n'est pas une interface fonctionnelle, alors vous ne pouvez pas créer la fonction sous cette forme compacte, mais d'autre part, dans ce cas, il ne serait pas raisonnable de demander un support pour appeler une méthode arbitraire sans le nommer explicitement non plus.

+0

Salut, Holger. après avoir lu votre solution, je trouve que je peux fournir une autre réponse à OP, ai-je raison? –

1

Je sais ce que vous entendez, le code groovy call a closure comme ceci:

def code = { 123 }; 

//can be called like any other method if the variable is a closure. 
assert code() == 123; 
//can be call explicitly by using `call` method 
assert code.call() == 123; 

code javascript call a function comme ceci:

let code =() => 123; 

//can be called like any other function if the variable is a function. 
assert code() == 123; 
//can be call explicitly by using `call` method 
assert code.call() == 123; 

Mais je peux vous dire java Gammar pas en charge cette fonctionnalité pour les champs/variables, peut-être dans le prochain jdk sera activer cette fonctionnalité dont un champ/variable se référer à Callable.

Heureusement, Single-Static-Import Declarations soutient appeler une méthode directement si le membre statique est une méthode, par exemple:

import static java.lang.Math.abs; 

assert abs(-1) == 1; 

Si vous voulez vraiment faire un identifiant appelé comme un appel de méthode, vous pouvez faux quelque chose comme ceci:

class ApiFactory { 

    public static Func1<MyEvent, Observable<Data>> getDataOnEvent = new Func1<MyEvent, Observable<Data>>() { 
     public Observable<Data> call(MyEvent event) { 
      return ApiFactory.get().getData(); 
     } 
    }; 

    public static Observable<Data> getDataOnEvent(MyEvent event) { 
     return getDataOnEvent.call(event); 
    } 

} 

vous pouvez appeler comme ceci:

import static ${package}.ApiFactory.getDataOnEvent; 
// which is calling a static method 
result = getDataOnEvent(event); 
// which is calling a static field 
result = getDataOnEvent.call(event); 
+0

Vous avez toujours le choix entre "une méthode et une fonction appelant la méthode" et "une fonction et une méthode appelant la fonction". Depuis Java, la fonction est toujours une classe ayant une méthode et la méthode appelant la fonction appelle fondamentalement une autre méthode, je préfère définir la fonction authentique Java, c'est-à-dire une méthode qui contient le code, surtout si le type de fonction est interface fonctionnelle qui peut être implémentée via une référence de méthode. Mais même si je considère ma variante plus naturelle, il vaut la peine de mentionner l'alternative. – Holger

+0

@Holger^_ ^, Merci de donner autant d'informations valables. J'apprends plus des commentaires. –