1041 votes

Volitelné parametry

Comment utiliser des paramètres optionnels dans Java ? Quelle spécification prend en charge les paramètres facultatifs ?

1934voto

Vitalii Fedorenko Points 17469

Il existe plusieurs façons de simuler les paramètres facultatifs en Java:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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();
    
  6. 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é.

591voto

laginimaineb Points 3049

varargs pourrait faire cela (de manière). Other than that, toutes les variables dans la déclaration de la méthode doivent être fournies. Si vous voulez une variable comme étant facultatif, vous pouvez surcharger la méthode à l’aide d’une signature qui ne requiert pas le paramètre.

149voto

bhoot Points 353

Il y a des paramètres facultatifs avec Java 5.0. Simplement déclarer votre fonction comme ceci :

vous pouvez maintenant appeler avec doSomething() ou doSomething(true).

106voto

theninjagreg Points 884

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.

54voto

Scott Stanchfield Points 15863

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X