Parametri opzionali Java

Come utilizzare i parametri opzionali in Java? Quali specifiche supportano i parametri opzionali?

varargs potrebbe farlo (in un certo senso). Oltre a ciò, devono essere fornite tutte le variabili nella dichiarazione del metodo. Se si desidera che una variabile sia facoltativa, è ansible sovraccaricare il metodo utilizzando una firma che non richiede il parametro.

private boolean defaultOptionalFlagValue = true; public void doSomething(boolean optionalFlag) { ... } public void doSomething() { doSomething(defaultOptionalFlagValue); } 

Esistono diversi modi per simulare i parametri facoltativi in ​​Java:

  1. Sovraccarico di metodi.

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

    Uno dei limiti di questo approccio è che non funziona se si hanno due parametri opzionali dello stesso tipo e nessuno di essi può essere omesso.

  2. Varargs.

    a) Tutti i parametri opzionali sono dello stesso tipo:

     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) I tipi di parametri facoltativi possono essere diversi:

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

    Lo svantaggio principale di questo approccio è che se i parametri opzionali sono di tipi diversi si perde il controllo di tipo statico. Inoltre, se ogni parametro ha un significato diverso, è necessario un modo per distinguerli.

  3. Null. Per affrontare i limiti degli approcci precedenti è ansible consentire valori nulli e quindi analizzare ciascun parametro nel corpo di un metodo:

     void foo(String a, Integer b, Integer c) { b = b != null ? b : 0; c = c != null ? c : 0; //... } foo("a", null, 2); 

    Ora devono essere forniti tutti i valori degli argomenti, ma quelli di default possono essere nulli.

  4. Classe opzionale Questo approccio è simile a null, ma utilizza la class opzionale Java 8 per i parametri che hanno un valore predefinito:

     void foo(String a, Optional bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... } foo("a", Optional.of(2)); foo("a", Optional.absent()); 

    Facoltativo rende esplicito un contratto di metodo per un chiamante, tuttavia, si può trovare tale firma troppo prolissa.

    Aggiornamento: Java 8 include la class java.util.Optional out-of-the-box, quindi non c’è bisogno di usare guava per questo particolare motivo in java 8. Il nome del metodo è un po ‘diverso però.

  5. Modello di generatore. Il modello di builder viene utilizzato per i costruttori e viene implementato introducendo una class Builder separata:

      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. Mappe. Quando il numero di parametri è troppo grande e per la maggior parte di solito vengono utilizzati i valori predefiniti, è ansible passare gli argomenti del metodo come una mappa dei loro nomi / valori:

     void foo(Map 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.of( "a", "a", "b", 2, "d", "value")); 

Si noti che è ansible combinare uno qualsiasi di questi approcci per ottenere un risultato desiderabile.

Puoi usare qualcosa come questo:

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

La variabile params è opzionale. Viene considerato come una serie di oggetti nullable.

Stranamente, non ho trovato nulla a riguardo nella documentazione, ma funziona!

Questo è “nuovo” in Java 1.5 e successivi (non supportato in Java 1.4 o precedente).

Vedo che l’utente bhoot ha menzionato questo anche sotto.

Ci sono parametri opzionali con Java 5.0. Dichiara semplicemente la tua funzione in questo modo:

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

puoi chiamare con doSomething(); o doSomething(true); adesso.

Sfortunatamente Java non supporta direttamente i parametri predefiniti.

Tuttavia, ho scritto una serie di annotazioni JavaBean e una supporta i parametri predefiniti come segue:

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

Il processore di annotazione genera sovraccarichi del metodo per supportarlo correttamente.

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

Esempio completo su http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample

Non ci sono parametri opzionali in Java. Quello che puoi fare è sovraccaricare le funzioni e quindi passare valori predefiniti.

 void SomeMethod(int age, String name) { // } // Overload void SomeMethod(int age) { SomeMethod(age, "John Doe"); } 

VarArgs e sovraccarico sono stati menzionati. Un’altra opzione è un modello Builder, che assomiglierebbe a questo:

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

Anche se questo modello sarebbe più appropriato quando hai bisogno di parametri opzionali in un costruttore.

In JDK> 1.5 puoi usarlo in questo modo;

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

Dipende da ciò che si vuole raggiungere, varargs o overloading del metodo dovrebbe risolvere la maggior parte degli scenari.

ma tieni a mente di non usare troppo il metodo di sovraccarico. porta confusione.

Versione breve :

Usando tre punti :

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

(basato sulla risposta di @ VitaliiFedorenko)

Puoi fare qualcosa usando il sovraccarico del metodo in questo modo.

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

Inoltre puoi usare l’annotazione @Nullable

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

semplicemente passa null come primo parametro.

Se stai passando lo stesso tipo di variabile puoi usare questo

 public void load(String name...){} 

Il sovraccarico va bene, ma se ci sono molte variabili che necessitano di un valore predefinito, si finirà con:

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

Quindi suggerirei di usare l’argomento variabile fornito da Java. Ecco un link per la spiegazione.

Java ora supporta gli optionals in 1.8, sono bloccato con la programmazione su Android, quindi sto usando nulls fino a quando non posso refactoring il codice per utilizzare tipi opzionali.

 Object canBeNull() { if (blah) { return new Object(); } else { return null; } } Object optionalObject = canBeNull(); if (optionalObject != null) { // new object returned } else { // no new object returned } 

Puoi usare una class che funziona molto come un costruttore per contenere i tuoi valori opzionali come questo.

 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 consumer) { Options options = new Options(); consumer.accept(options); System.out.println("someString = " + options.someString + ", someInt = " + options.someInt); } 

Usa come

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

L’output è

 someString = something, someInt = 5 

Per saltare tutti i valori opzionali dovresti chiamarlo come foo(o -> {}); o se preferisci, puoi creare un secondo metodo foo() che non accetta i parametri opzionali.

Utilizzando questo approccio, è ansible specificare valori opzionali in qualsiasi ordine senza alcuna ambiguità. Puoi anche avere parametri di classi diverse a differenza dei vararg. Questo approccio sarebbe ancora meglio se si possono usare le annotazioni e la generazione del codice per creare la class Options.

Gli argomenti predefiniti non possono essere utilizzati in Java e C #. Dove in C ++ e Python, possiamo usarli ..

In Java, dobbiamo usare 2 metodi (funzioni) invece di uno con i parametri predefiniti.

Esempio:

 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-

Possiamo impostare parametri opzionali tramite l’overloading del metodo o l’utilizzo di DataType …

| * | Sovraccarico del metodo:

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

Il modo più semplice è

| * | DataType … può essere un parametro facoltativo

 RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar) { if(SrgOpnPsgVar.length == 0) SrgOpnPsgVar = DefSrgVar; // |* CodTdo *| return RetVar; }