C'est peut-être quelque chose de commun et d'insignifiant, mais il me semble que j'ai du mal à trouver une réponse concrète. En C #, il existe un concept de délégués, qui est fortement lié à l'idée des pointeurs de fonction de C ++. Existe-t-il une fonctionnalité similaire en Java? Étant donné que les pointeurs sont quelque peu absents, quelle est la meilleure façon de procéder? Et pour être clair, nous parlons de première classe ici.
java
pointers
delegates
function-pointers
dreadwail
la source
la source
this::myMethod
est sémantiquement identique à la création d'un lambdaparamA, paramB -> this.myMethod(paramA, paramB)
.Réponses:
L'idiome Java pour la fonctionnalité de type pointeur de fonction est une classe anonyme implémentant une interface, par ex.
Mise à jour: ce qui précède est nécessaire dans les versions Java antérieures à Java 8. Nous avons maintenant des alternatives beaucoup plus agréables, à savoir les lambdas:
et références de méthode:
la source
std::bind
, qui lie les paramètres aux fonctions et renvoie un objet appelable. Je ne peux pas défendre C pour ces raisons, mais C ++ est vraiment meilleur que Java pour cela.Vous pouvez remplacer un pointeur de fonction par une interface. Disons que vous voulez parcourir une collection et faire quelque chose avec chaque élément.
C'est l'interface que nous pourrions passer à certains, disons CollectionUtils2.doFunc (Collection c, IFunction f).
À titre d'exemple, disons que nous avons une collection de nombres et que vous souhaitez ajouter 1 à chaque élément.
la source
Vous pouvez utiliser la réflexion pour le faire.
Passez en paramètre l'objet et le nom de la méthode (sous forme de chaîne) puis invoquez la méthode. Par exemple:
Et puis utilisez-le comme dans:
Bien sûr, vérifiez toutes les exceptions et ajoutez les transtypages nécessaires.
la source
Non, les fonctions ne sont pas des objets de première classe en java. Vous pouvez faire la même chose en implémentant une classe de gestionnaire - c'est ainsi que les rappels sont implémentés dans le Swing, etc.
Il y a cependant des propositions de fermetures (le nom officiel de ce dont vous parlez) dans les futures versions de java - Javaworld a un article intéressant.
la source
Cela me rappelle l' exécution de Steve Yegge dans le royaume des noms . Il déclare essentiellement que Java a besoin d'un objet pour chaque action, et n'a donc pas d'entités "verb-only" comme les pointeurs de fonction.
la source
Pour obtenir des fonctionnalités similaires, vous pouvez utiliser des classes internes anonymes.
Si vous deviez définir une interface
Foo
:Créez une méthode
bar
qui recevra un 'pointeur de fonction' comme argument:Appelez enfin la méthode comme suit:
la source
Java8 a introduit des lambdas et des références de méthode . Donc, si votre fonction correspond à une interface fonctionnelle (vous pouvez créer la vôtre), vous pouvez utiliser une référence de méthode dans ce cas.
Java fournit un ensemble d' interfaces fonctionnelles communes . alors que vous pouvez faire ce qui suit:
la source
alias
: egpublic List<T> collect(T t) = Collections::collect
Une telle chose n'existe pas en Java. Vous devrez envelopper votre fonction dans un objet et passer la référence à cet objet afin de passer la référence à la méthode sur cet objet.
D'un point de vue syntaxique, cela peut être facilité dans une certaine mesure en utilisant des classes anonymes définies sur place ou des classes anonymes définies en tant que variables membres de la classe.
Exemple:
la source
J'ai implémenté le support de rappel / délégué en Java en utilisant la réflexion. Les détails et la source de travail sont disponibles sur mon site Web .
Comment ça fonctionne
Nous avons une classe principale nommée Callback avec une classe imbriquée nommée WithParms. L'API qui a besoin du rappel prendra un objet Callback comme paramètre et, si nécessaire, créera un Callback.WithParms comme variable de méthode. Comme un grand nombre d'applications de cet objet seront récursives, cela fonctionne très proprement.
Les performances étant toujours une priorité pour moi, je ne voulais pas être obligé de créer un tableau d'objets jetables pour contenir les paramètres de chaque appel - après tout, dans une grande structure de données, il pourrait y avoir des milliers d'éléments, et dans un traitement de message scénario, nous pourrions finir par traiter des milliers de structures de données par seconde.
Afin d'être sûr pour les threads, le tableau de paramètres doit exister de manière unique pour chaque invocation de la méthode API, et pour plus d'efficacité, le même doit être utilisé pour chaque appel du rappel; J'avais besoin d'un deuxième objet qui serait bon marché à créer afin de lier le rappel avec un tableau de paramètres pour l'invocation. Mais, dans certains scénarios, l'invocateur aurait déjà un tableau de paramètres pour d'autres raisons. Pour ces deux raisons, le tableau de paramètres n'appartenait pas à l'objet Callback. Le choix de l'invocation (passer les paramètres sous forme de tableau ou d'objets individuels) appartient également à l'API en utilisant le callback lui permettant d'utiliser l'invocation la mieux adaptée à son fonctionnement interne.
La classe imbriquée WithParms est donc facultative et sert à deux fins, elle contient le tableau d'objets de paramètres nécessaire pour les appels de rappel, et elle fournit 10 méthodes invoke () surchargées (avec de 1 à 10 paramètres) qui chargent le tableau de paramètres, puis appeler la cible de rappel.
la source
Vérifiez les fermetures comment elles ont été implémentées dans la bibliothèque lambdaj. Ils ont en fait un comportement très similaire aux délégués C #:
http://code.google.com/p/lambdaj/wiki/Closures
la source
Par rapport à la plupart des gens ici, je suis nouveau sur Java, mais comme je n'ai pas vu de suggestion similaire, j'ai une autre alternative à suggérer. Je ne sais pas si c'est une bonne pratique ou non, ou même suggérée avant et je ne l'ai tout simplement pas comprise. Je l'aime juste car je pense que c'est auto-descriptif.
puis selon l'application, attribuez
etc.
et appeler
la source