Comment utiliser des paramètres optionnels dans Java ? Quelle spécification prend en charge les paramètres facultatifs ?
Réponses
Trop de publicités?Il existe plusieurs façons de simuler les paramètres facultatifs en Java:
-
La surcharge de méthode.
void foo(String a, Integer b) { //... } void foo(String a) { foo(a, 0); // here, 0 is a default value for b } foo("a", 2); foo("a");
L'une des limitations de cette approche est qu'elle ne fonctionne pas si vous avez deux options de paramètres de même type et de même l'un d'eux peut être omis.
-
Varargs.
a) Tous les paramètres facultatifs sont du même type:
void foo(String a, Integer... b) { Integer b1 = b.length > 0 ? b[0] : 0; Integer b2 = b.length > 1 ? b[1] : 0; //... } foo("a"); foo("a", 1, 2);
b) les Types de paramètres optionnels peuvent être différents:
void foo(String a, Object... b) { Integer b1 = 0; String b2 = ""; if (b.length > 0) { if (!(b[0] instanceof Integer)) { throw new IllegalArgumentException("..."); } b1 = (Integer)b[0]; } if (b.length > 1) { if (!(b[1] instanceof String)) { throw new IllegalArgumentException("..."); } b2 = (String)b[1]; //... } //... } foo("a"); foo("a", 1); foo("a", 1, "b2");
Le principal inconvénient de cette approche est que si les paramètres facultatifs sont de différents types, vous perdez de type statique de contrôle. En outre, si chaque paramètre est différent ce qui signifie que vous devez trouver un moyen de les distinguer.
-
Les valeurs null. Pour surmonter les limites des approches précédentes, vous pouvez autoriser les valeurs null et puis d'analyser chaque paramètre dans un corps de méthode:
void foo(String a, Integer b, Integer c) { b = b != null ? b : 0; c = c != null ? c : 0; //... } foo("a", null, 2);
Maintenant, tous les arguments des valeurs doit être fournie, mais les valeurs par défaut peut être null.
-
Classe optionnelle. Cette approche est similaire à null, mais utilise à la goyave classe Optionnelle pour les paramètres qui ont une valeur par défaut:
void foo(String a, Optional<Integer> bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... } foo("a", Optional.of(2)); foo("a", Optional.<Integer>absent());
En option permet une méthode de contrat explicite pour l'appelant, toutefois, on peut trouver une telle signature trop verbeux.
-
Le générateur de modèle. Le générateur de modèle est utilisé pour les constructeurs et est mis en œuvre par l'ajout d'une nouvelle Constructeur de la classe:
class Foo { private final String a; private final Integer b; Foo(String a, Integer b) { this.a = a; this.b = b; } //... } class FooBuilder { private String a = ""; private Integer b = 0; FooBuilder setA(String a) { this.a = a; return this; } FooBuilder setB(Integer b) { this.b = b; return this; } Foo build() { return new Foo(a, b); } } Foo foo = new FooBuilder().setA("a").build();
-
Cartes. Lorsque le nombre de paramètres est trop grande et pour la plupart des valeurs par défaut sont généralement utilisés, vous pouvez passer des arguments de méthode comme une carte de leurs noms/valeurs:
void foo(Map<String, Object> parameters) { String a = ""; Integer b = 0; if (parameters.containsKey("a")) { if (!(parameters.get("a") instanceof Integer)) { throw new IllegalArgumentException("..."); } a = (String)parameters.get("a"); } if (parameters.containsKey("b")) { //... } //... } foo(ImmutableMap.<String, Object>of( "a", "a", "b", 2, "d", "value"));
Veuillez noter que vous pouvez combiner ces approches pour atteindre le résultat souhaité.
Vous pouvez utiliser quelque chose comme ceci :
Le `` variable est facultative. Il est traité comme un tableau nullable d’objets.
Étrangement, je ne trouvais rien à ce sujet dans la documentation, mais ça marche !
C’est « nouveau » en Java 1.5 et au-delà (pas pris en charge dans Java 1.4 ou plus tôt).
Je vois bhoot utilisateur mentionné cela trop bas.
Malheureusement Java ne prend pas en charge les paramètres par défaut directement.
Cependant, j'ai écrit une série de JavaBean annotations, et l'un d'eux le soutien paramètres par défaut comme suit:
protected void process(
Processor processor,
String item,
@Default("Processor.Size.LARGE") Size size,
@Default("red") String color,
@Default("1") int quantity) {
processor.process(item, size, color, quantity);
}
public void report(@Default("Hello") String message) {
System.out.println("Message: " + message);
}
L'annotation processeur génère des surcharges de méthode afin de soutenir correctement.
Voir http://code.google.com/p/javadude/wiki/Annotations
Exemple complet à http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample