Java 8 Fournisseur avec des arguments dans le constructeur
Pourquoi fournisseurs de soutien non-arg constructeurs?
Si le constructeur par défaut est présent, je peux le faire:
create(Foo::new)
Mais si le seul constructeur prend une Chaîne de caractères, j'ai pour ce faire:
create(() -> new Foo("hello"))
- Comment le compilateur suppose que l'argument est censé être "bonjour"?
- Votre question n'a simplement aucun sens. Vous écrivez “Pourquoi les fournisseurs de travailler uniquement avec les non-arg constructeurs?”, ensuite, vous vous prouver qu'un
Supplier
ne fonctionne pas avec les arguments fournis, c'est à dire lors de l'utilisation d'une expression lambda. Il semble donc votre question est “pourquoi est-ce une référence à une méthode de travail que si le fonctionnel paramètres correspondent aux paramètres cible” et la réponse est, parce que c'est ce que la méthode références sont pour. Si la liste de paramètres ne correspondent pas, l'utilisation d'une expression lambda comme vous l'avez indiqué dans votre question. Parce que c'est ce que l'expression lambda sont pour (pas exclusivement)...
Vous devez vous connecter pour publier un commentaire.
C'est juste une limitation de la méthode référence de la syntaxe -- que vous ne pouvez pas passer dans l'un des arguments. C'est juste la façon dont la syntaxe fonctionne.
Mais, une 1-arg constructeur de
T
qui prend unString
est compatible avecFunction<String,T>
:Constructeur qui est sélectionnée est considérée comme une surcharge de sélection de problème, basé sur la forme du type de cible.
Si vous aimez la méthode de référence pour beaucoup, vous pouvez écrire un
bind
méthode par vous-même et de l'utiliser:Parce que 1-arg constructeur est isomorphe à un SAM interface avec 1 argument et 1 valeur de retour, comme
java.util.function.Function<T,R>
'sR apply(T)
.D'autre part
Supplier<T>
'sT get()
est isomorphe à un zéro arg constructeur.Ils sont tout simplement pas compatibles. Votre
create()
méthode doit être polymorphe à accepter différentes interfaces fonctionnelles et agir différemment selon laquelle les arguments sont fournis ou que vous avez à écrire un corps de lambda, à agir comme une colle de code entre les deux signatures.Qu'est-ce que vos attentes non satisfaits ici? Ce devrait se passer à votre avis?
La
Supplier<T>
interface représente une fonction avec une signature de() -> T
en ce sens qu'elle ne prend aucun paramètre et renvoie à quelque chose de typeT
. Méthode des références que vous fournissez comme arguments doivent suivre cette signature pour passer en.Si vous souhaitez créer un
Supplier<Foo>
qui travaille avec le constructeur, vous pouvez en général, utiliser la méthode bind que @Tagir Valeev suggère, ou vous faire un plus spécialisée.Si vous voulez un
Supplier<Foo>
qui utilise toujours que"hello"
Chaîne, vous pouvez définir de deux manières différentes: comme une méthode ou unSupplier<Foo>
variable.méthode:
variable:
Vous pouvez passer à la méthode avec une méthode de référence(
create(WhateverClassItIsOn::makeFoo);
), et la variable peut être transmis en utilisant simplement le nom decreate(WhateverClassItIsOn.makeFoo);
.La méthode est un peu plus préférable car il est plus facile à utiliser en dehors du contexte de son adoption en tant que méthode de référence, et il est également capable d'être utilisé dans le cas où quelqu'un aura besoin de sa propre spécialisés interface fonctionnelle qui est aussi
() -> T
ou est() -> Foo
spécifiquement.Si vous souhaitez utiliser un
Supplier
qui peut prendre n'importe quelle Chaîne de caractères comme argument, vous devriez utiliser quelque chose comme la méthode bind @Tagir mentionné, en contournant la nécessité de fournir à laFunction
:Vous pouvez la passer en argument comme ceci:
create(makeFooFromString("hello"));
Bien que, peut-être que vous devriez changer tous les "faire de la..." appels d'offre "..." appels, juste pour rendre les choses un peu plus claires.
Paire le Fournisseur avec un FunctionalInterface.
Voici un exemple de code que j'ai mis ensemble pour démontrer la "liaison" est un constructeur de référence à un constructeur avec la Fonction et aussi différentes façons de définir et de l'invocation de la "fabrique" du constructeur références.