Je cherche à implémenter une fonctionnalité dans une liste d'objets comme je le ferais en C # en utilisant une méthode d'extension.
Quelque chose comme ça:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Comment faire cela en Java?
java
extension-methods
Fabio Milheiro
la source
la source
Réponses:
Java ne prend pas en charge les méthodes d'extension.
Au lieu de cela, vous pouvez créer une méthode statique régulière ou écrire votre propre classe.
la source
Les méthodes d'extension ne sont pas seulement des méthodes statiques et pas seulement du sucre de syntaxe pratique, en fait, elles sont des outils assez puissants. L'essentiel est de pouvoir remplacer différentes méthodes basées sur l'instanciation de différents paramètres génériques. Ceci est similaire aux classes de types de Haskell, et en fait, il semble qu'elles soient en C # pour supporter les monades de C # (c'est-à-dire LINQ). Même en abandonnant la syntaxe LINQ, je ne connais toujours aucun moyen d'implémenter des interfaces similaires en Java.
Et je ne pense pas qu'il soit possible de les implémenter en Java, à cause de la sémantique d'effacement de type Java des paramètres génériques.
la source
Project Lombok fournit une annotation
@ExtensionMethod
qui peut être utilisée pour obtenir la fonctionnalité que vous demandez.la source
java.lang.String
. Démonstration: http://manifold.systems/images/ExtensionMethod.mp4Techniquement, l'extension C # n'a pas d'équivalent en Java. Mais si vous souhaitez implémenter de telles fonctions pour un code plus propre et une maintenabilité, vous devez utiliser le framework Manifold.
la source
Le langage XTend - qui est un super-ensemble de Java, et se compile en code source Java 1 - le prend en charge.
la source
Manifold fournit à Java des méthodes d'extension de style C # et plusieurs autres fonctionnalités. Contrairement à d' autres outils, collecteur n'a pas de limites et ne pas souffrir de problèmes avec les génériques, lambdas, etc. IDE fournit plusieurs Manifold d' autres fonctions telles que F # -style types personnalisés , tapuscrit de style interfaces de structure et de style Javascript types expando .
De plus, IntelliJ fournit une prise en charge complète de Manifold via le plugin Manifold .
Manifold est un projet open source disponible sur github .
la source
Une autre option consiste à utiliser les classes ForwardingXXX de la bibliothèque google-guava.
la source
Java n'a pas une telle fonctionnalité. Au lieu de cela, vous pouvez créer une sous-classe régulière de votre implémentation de liste ou créer une classe interne anonyme:
Le problème est d'appeler cette méthode. Vous pouvez le faire "sur place":
la source
Il semble qu'il y a peu de chances que les méthodes Defender (c'est-à-dire les méthodes par défaut) soient intégrées à Java 8. Cependant, pour autant que je les comprends, elles permettent uniquement à l' auteur d'un
interface
de l'étendre rétroactivement, pas aux utilisateurs arbitraires.Defender Methods + Interface Injection serait alors capable d'implémenter pleinement les méthodes d'extension de style C #, mais AFAICS, Interface Injection n'est même pas encore sur la feuille de route de Java 8.
la source
Un peu tard à la fête sur cette question, mais au cas où quelqu'un le trouverait utile, je viens de créer une sous-classe:
la source
Nous pouvons simuler l'implémentation des méthodes d'extension C # en Java en utilisant l'implémentation de méthode par défaut disponible depuis Java 8. Nous commençons par définir une interface qui nous permettra d'accéder à l'objet support via une méthode base (), comme ceci:
Nous retournons null car les interfaces ne peuvent pas avoir d'état, mais cela doit être corrigé ultérieurement via un proxy.
Le développeur d'extensions devrait étendre cette interface par une nouvelle interface contenant des méthodes d'extension. Disons que nous voulons ajouter une interface forEach consumer sur List:
Comme nous étendons l'interface d'extension, nous pouvons appeler la méthode base () dans notre méthode d'extension pour accéder à l'objet de support auquel nous nous attachons.
L'interface d'extension doit avoir une méthode de fabrique qui créera une extension d'un objet de support donné:
Nous créons un proxy qui implémente l'interface d'extension et toute l'interface implémentée par le type de l'objet de support. Le gestionnaire d'appel donné au proxy distribuerait tous les appels à l'objet de support, à l'exception de la méthode "base", qui doit renvoyer l'objet de support, sinon son implémentation par défaut renvoie null:
Ensuite, nous pouvons utiliser la méthode Extension.create () pour attacher l'interface contenant la méthode d'extension à l'objet de support. Le résultat est un objet qui peut être transtypé vers l'interface d'extension par laquelle nous pouvons toujours accéder à l'objet de support appelant la méthode base (). Une fois la référence castée vers l'interface d'extension, nous pouvons maintenant appeler en toute sécurité les méthodes d'extension qui peuvent avoir accès à l'objet de support, de sorte que nous pouvons maintenant attacher de nouvelles méthodes à l'objet existant, mais pas à son type de définition:
C'est donc une façon de simuler la capacité d'étendre des objets en Java en leur ajoutant de nouveaux contrats, ce qui nous permet d'appeler des méthodes supplémentaires sur les objets donnés.
Vous trouverez ci-dessous le code de l'interface d'extension:
la source
On pourrait utiliser le modèle de conception orienté objet du décorateur . Un exemple de ce modèle utilisé dans la bibliothèque standard de Java serait le DataOutputStream .
Voici du code pour augmenter les fonctionnalités d'une liste:
PS Je suis un grand fan de Kotlin . Il a des méthodes d'extension et fonctionne également sur la JVM.
la source
Vous pouvez créer une méthode d'extension / d'assistance de type C # en (RE) implémentant l'interface Collections et en ajoutant un exemple pour Java Collection:
la source
Java
8 prend désormais en charge les méthodes par défaut , qui sont similaires auxC#
méthodes d'extension de.la source