Paramètres facultatifs de Java

comment utiliser les paramètres optionnels en Java? Quelle spécification supporte les paramètres optionnels?

648
demandé sur Mike Pone 2009-06-08 20:12:29

16 réponses

varargs pourrait faire cela (d'une certaine manière). En dehors de cela, toutes les variables dans la déclaration de la méthode doivent être fournies. Si vous voulez qu'une variable soit optionnelle, vous pouvez surcharger la méthode en utilisant une signature qui ne nécessite pas le paramètre.

private boolean defaultOptionalFlagValue = true;

public void doSomething(boolean optionalFlag) {
    ...
}

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}
416
répondu laginimaineb 2011-05-20 10:27:13

il y a plusieurs façons de simuler des paramètres optionnels en Java:

  1. méthode de surcharge.

    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 limites de cette approche est qu'elle ne fonctionne pas si vous avez deux paramètres optionnels du même type et l'un d'eux peut être omis.

  2. Varargs.

    a) tous les paramètres optionnels 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 facultatifs 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 optionnels sont de différents types, vous perdez le contrôle de type statique. De plus, si chaque paramètre a une signification différente, vous avez besoin d'un moyen pour les distinguer.

  3. les valeurs Null. pour répondre à la limites des approches précédentes vous pouvez autoriser des valeurs nulles et ensuite 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 toutes les valeurs d'arguments doivent être fournies, mais celles par défaut peuvent être nulles.

  4. class Facultatif. cette approche est similaire à nulls, mais utilise la classe optionnelle Java 8 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());
    

    facultatif rend un méthode contrat explicite pour un appelant, cependant, on peut trouver une telle signature trop verbeuse.

    mise à jour: Java 8 inclut la classe java.util.Optional out-of-the-box, de sorte qu'il n'est pas nécessaire d'utiliser la goyave pour cette raison particulière dans java 8. Le nom de la méthode est un peu différente.

  5. modèle de constructeur. le modèle de constructeur est utilisé pour les constructeurs et est mis en œuvre par l'introduction d'une catégorie distincte de constructeurs:

     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. des Cartes. lorsque le nombre de paramètres est trop grand et que pour la plupart d'entre eux des valeurs par défaut sont habituellement utilisées, 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 = (Integer)parameters.get("a");
        }
        if (parameters.containsKey("b")) { 
            //... 
        }
        //...
    }
    
    foo(ImmutableMap.<String, Object>of(
        "a", "a",
        "b", 2, 
        "d", "value")); 
    

veuillez noter que vous pouvez combiner l'une de ces approches pour obtenir un résultat souhaitable.

1420
répondu Vitalii Fedorenko 2016-09-02 02:36:14

Vous pouvez utiliser quelque chose comme ceci:

public void addError(String path, String key, Object... params) { 
}

la variable params est facultative. Il est traité comme un tableau d'objets nullables.

étrangement, je n'ai rien trouvé à ce sujet dans la documentation, mais ça marche!

c'est "nouveau" en Java 1.5 et au-delà (non supporté en Java 1.4 ou plus tôt).

je vois l'utilisateur bhoot mentionné ceci aussi ci-dessous.

96
répondu theninjagreg 2010-12-03 21:41:36

il y a des paramètres optionnels avec Java 5.0. Il suffit de déclarer votre fonction comme ceci:

public void doSomething(boolean... optionalFlag) {
    //default to "false"
    //boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}

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

88
répondu bhoot 2018-08-29 13:36:48

malheureusement, Java ne supporte pas les paramètres par défaut directement.

cependant, j'ai écrit un ensemble D'annotations Javabéennes, et l'un d'eux supporte les paramètres par défaut comme le suivant:

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);
}

le processeur d'annotation génère les surcharges de méthode pour supporter correctement ceci.

voir http://code.google.com/p/javadude/wiki/Annotations

exemple Complet à http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample

47
répondu Scott Stanchfield 2009-06-08 17:00:09

il n'y a pas de paramètres optionnels en Java. Ce que vous pouvez faire est de surcharger les fonctions et de passer ensuite les valeurs par défaut.

void SomeMethod(int age, String name) {
    //
}

// Overload
void SomeMethod(int age) {
    SomeMethod(age, "John Doe");
}
43
répondu Dario 2009-06-08 16:18:10

VarArgs et surcharge ont été mentionnés. Une autre option est un modèle de constructeur, qui ressemblerait à quelque chose comme ceci:

 MyObject my = new MyObjectBuilder().setParam1(value)
                                 .setParam3(otherValue)
                                 .setParam6(thirdValue)
                                 .build();

bien que ce modèle serait le plus approprié pour quand vous avez besoin de paramètres optionnels dans un constructeur.

21
répondu Yishai 2009-06-08 17:05:21

dans JDK > 1.5 vous pouvez l'utiliser comme ceci;

public class NewClass1 {

    public static void main(String[] args) {

        try {
            someMethod(18); // Age : 18
            someMethod(18, "John Doe"); // Age & Name : 18 & John Doe
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void someMethod(int age, String... names) {

        if (names.length > 0) {
            if (names[0] != null) {
                System.out.println("Age & Name : " + age + " & " + names[0]);
            }
        } else {
            System.out.println("Age : " + age);
        }
    }
}
12
répondu az3 2012-08-24 10:44:38

cela dépend de ce que vous voulez réaliser, varargs ou la surcharge de la méthode devrait résoudre la plupart des scénarios.

mais gardez à l'esprit de ne pas trop utiliser la méthode de surcharge. il apporte la confusion.

8
répondu Marc 2012-10-22 10:19:36

version Courte :

utilisant trois points :

public void foo(Object... x) {
    String first    =  x.length > 0 ? (String)x[0]  : "Hello";
    int duration    =  x.length > 1 ? Integer.parseInt((String) x[1])     : 888;
}   
foo("Hii", ); 
foo("Hii", 146); 

(basé sur la réponse de @VitaliiFedorenko)

5
répondu T.Todua 2017-11-27 19:18:35

vous pouvez faire quelque chose en utilisant la méthode de surcharge comme ceci.

 public void load(String name){ }

 public void load(String name,int age){}

vous pouvez aussi utiliser @Nullable annotation

public void load(@Nullable String name,int age){}

passe simplement null comme premier paramètre.

si vous passez la même variable de type vous pouvez utiliser ce

public void load(String name...){}
4
répondu Ishan Fernando 2016-08-19 11:33:36

la surcharge est très bien, mais s'il y a beaucoup de variables qui ont besoin d'une valeur par défaut, vous finirez avec:

public void methodA(A arg1) {  }
public void methodA( B arg2,) {  }
public void methodA(C arg3) {  }
public void methodA(A arg1, B arg2) {  }
public void methodA(A arg1, C arg3) {  }
public void methodA( B arg2, C arg3) {  }
public void methodA(A arg1, B arg2, C arg3) {  }

donc je suggère d'utiliser L'Argument Variable fourni par Java. Voici un lien pour explication.

2
répondu Jigar Shah 2017-06-16 02:24:37

Java prend maintenant en charge les options en 1.8, je suis coincé avec la programmation sur android donc j'utilise nulls jusqu'à ce que je puisse modifier le code pour utiliser les types optionnels.

Object canBeNull() {
    if (blah) {
        return new Object();
    } else {
        return null;
    }
}

Object optionalObject = canBeNull();
if (optionalObject != null) {
    // new object returned
} else {
    // no new object returned
}
1
répondu Pellet 2017-03-20 07:04:27

vous pouvez utiliser une classe qui fonctionne un peu comme un builder pour contenir vos valeurs optionnelles comme ceci.

public class Options {
    private String someString = "default value";
    private int someInt= 0;
    public Options setSomeString(String someString) {
        this.someString = someString;
        return this;
    }
    public Options setSomeInt(int someInt) {
        this.someInt = someInt;
        return this;
    }
}

public static void foo(Consumer<Options> consumer) {
    Options options = new Options();
    consumer.accept(options);
    System.out.println("someString = " + options.someString + ", someInt = " + options.someInt);
}

utiliser comme

foo(o -> o.setSomeString("something").setSomeInt(5));

sortie est

someString = something, someInt = 5

pour sauter toutes les valeurs optionnelles que vous devez appeler comme foo(o -> {}); ou si vous préférez, vous pouvez créer une seconde méthode foo() qui ne prend pas les paramètres optionnels.

en Utilisant cette approche, vous pouvez spécifier les valeurs facultatives dans n'importe quel ordre, sans aucune ambiguïté. Vous pouvez également avoir des paramètres de différentes classes contrairement à varargs. Cette approche serait encore meilleure si vous pouvez utiliser les annotations et la génération de code pour créer la classe Options.

1
répondu rybai 2017-12-15 23:49:01

les arguments par défaut ne peuvent pas être utilisés en Java et C#. Où en C++ et Python, on peut les utiliser..

en Java, nous devons utiliser 2 méthodes (fonctions) au lieu d'une avec des paramètres par défaut.

exemple:

Stash(int size); 

Stash(int size, int initQuantity);

http://parvindersingh.webs.com/apps/forums/topics/show/8856498-java-how-to-set-default-parameters-values-like-c -

1
répondu Parvinder Singh 2018-04-11 14:22:33

nous pouvons rendre le paramètre optionnel par la méthode de la surcharge ou en utilisant le type de données...

| * / surcharge de la méthode:

RetDtaTyp NamFnc(String NamPsgVar)
{
    // |* CodTdo *|
    return RetVar;
}

RetDtaTyp NamFnc(String NamPsgVar)
{
    // |* CodTdo *|
    return RetVar;
}

RetDtaTyp NamFnc(int NamPsgVar1, String NamPsgVar2)
{
    // |* CodTdo *|
    return RetVar;
}

la voie la plus facile est

| * / DataType... peut être le paramètre optionnel

RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar)
{
    if(SrgOpnPsgVar.length == 0)  SrgOpnPsgVar = DefSrgVar; 

    // |* CodTdo *|
    return RetVar;
}

0
répondu Sujay U N 2017-10-23 10:32:02