Parámetros opcionales de Java


¿Cómo uso parámetros opcionales en Java? ¿Qué especificación admite parámetros opcionales?

Author: Mike Pone, 2009-06-08

16 answers

Varargs podría hacer eso (de alguna manera). Aparte de eso, se deben proporcionar todas las variables en la declaración del método. Si desea que una variable sea opcional, puede sobrecargar el método usando una firma que no requiera el parámetro.

private boolean defaultOptionalFlagValue = true;

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

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}
 416
Author: laginimaineb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-20 10:27:13

Hay varias formas de simular parámetros opcionales en Java:

  1. Método de sobrecarga.

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

    Una de las limitaciones de este enfoque es que no funciona si tiene dos parámetros opcionales del mismo tipo y cualquiera de ellos se puede omitir.

  2. Varargs.

    A) Todos los parámetros opcionales son del mismo 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) Los tipos de parámetros opcionales pueden ser diferentes:

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

    El principal el inconveniente de este enfoque es que si los parámetros opcionales son de diferentes tipos, pierde la comprobación de tipos estáticos. Además, si cada parámetro tiene un significado diferente, necesita alguna forma de distinguirlos.

  3. Nulls. Para abordar las limitaciones de los enfoques anteriores, puede permitir valores nulos y luego analizar cada parámetro en un cuerpo de método:

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

    Ahora se deben proporcionar todos los valores de los argumentos, pero los predeterminados pueden ser nulo.

  4. Clase Opcional. Este enfoque es similar a nulls, pero usa la clase opcional Java 8 para parámetros que tienen un valor predeterminado:

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

    Opcional hace un contrato de método explícito para una persona que llama, sin embargo, uno puede encontrar dicha firma demasiado detallada.

    Actualización: Java 8 incluye la clase java.util.Optional lista para usar, por lo que no es necesario usar guayaba por esta razón en java 8. El nombre del método es un poco diferente aunque.

  5. Patrón constructor. El patrón de constructor se usa para los constructores y se implementa introduciendo una clase de constructor separada:

     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. Mapas. Cuando el número de parámetros es demasiado grande y para la mayoría de ellos se suelen usar valores predeterminados, puede pasar argumentos de método como un mapa de sus nombres/valores:

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

Tenga en cuenta que puede combinar cualquiera de estos enfoques para lograr un resultado deseable.

 1420
Author: Vitalii Fedorenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-02 02:36:14

Puedes usar algo como esto:

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

La variable params es opcional. Se trata como una matriz nullable de Objetos.

Extrañamente, no pude encontrar nada sobre esto en la documentación, ¡pero funciona!

Esto es "nuevo" en Java 1.5 y más allá (no soportado en Java 1.4 o anterior).

Veo que el usuario bhoot también mencionó esto a continuación.

 96
Author: theninjagreg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-03 21:41:36

Hay parámetros opcionales con Java 5.0. Simplemente declare su función de esta manera:

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

Puede llamar con doSomething(); o doSomething(true); ahora.

 88
Author: bhoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-29 13:36:48

Desafortunadamente Java no soporta directamente los parámetros predeterminados.

Sin embargo, he escrito un conjunto de anotaciones JavaBean, y una de ellas soporta parámetros predeterminados como los siguientes:

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

El procesador de anotación genera las sobrecargas del método para soportar esto correctamente.

Véase http://code.google.com/p/javadude/wiki/Annotations

Ejemplo Completo en http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample

 47
Author: Scott Stanchfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 17:00:09

No hay parámetros opcionales en Java. Lo que puede hacer es sobrecargar las funciones y luego pasar los valores predeterminados.

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

// Overload
void SomeMethod(int age) {
    SomeMethod(age, "John Doe");
}
 43
Author: Dario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 16:18:10

Se han mencionado VarArgs y sobrecarga. Otra opción es un patrón de constructor, que se vería algo como esto:

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

Aunque ese patrón sería el más apropiado para cuando se necesitan parámetros opcionales en un constructor.

 21
Author: Yishai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 17:05:21

En JDK > 1.5 puedes usarlo así;

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
Author: az3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-24 10:44:38

Depende de lo que quieras lograr, varargs o sobrecarga de métodos debería resolver la mayoría de los escenarios.

Pero tenga en cuenta que no debe sobrecargar el método. trae confusión.

 8
Author: Marc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-22 10:19:36

Versión corta:

Usando tres puntos :

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

(basado en la respuesta de @VitaliiFedorenko)

 5
Author: T.Todua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-27 19:18:35

Puedes hacer cosas usando el método de sobrecarga como esta.

 public void load(String name){ }

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

También puedes usar la anotación @Nullable

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

Simplemente pasa null como primer parámetro.

Si está pasando la misma variable de tipo, puede usar esta

public void load(String name...){}
 4
Author: Ishan Fernando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-19 11:33:36

La sobrecarga está bien, pero si hay muchas variables que necesitan un valor predeterminado, terminará 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) {  }

Así que sugeriría usar el Argumento Variable proporcionado por Java. Aquí hay un enlace para la explicación.

 2
Author: Jigar Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-16 02:24:37

Java ahora es compatible con los opcionales en 1.8, estoy atascado con la programación en Android, así que estoy usando nulls hasta que pueda refactorizar el código para usar tipos opcionales.

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
Author: Pellet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-20 07:04:27

Puede usar una clase que funcione como un constructor para contener sus valores opcionales como este.

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

Use como

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

La salida es

someString = something, someInt = 5

Para omitir todos los valores opcionales tendría que llamarlo como foo(o -> {}); o si lo prefiere, puede crear un segundo método foo() que no tome los parámetros opcionales.

Usando este enfoque, puede especificar valores opcionales en cualquier orden sin ninguna ambigüedad. También puede tener parámetros de diferentes clases a diferencia de con varargs. Este enfoque sería aún mejor si puede usar anotaciones y generación de código para crear la clase Options.

 1
Author: rybai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 23:49:01

Los argumentos predeterminados no se pueden usar en Java y C#. Donde en C++ y Python, podemos usarlos..

En Java, debemos tener que usar 2 métodos (funciones) en lugar de uno con parámetros predeterminados.

Ejemplo:

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
Author: Parvinder Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-11 14:22:33

Podemos hacer parámetro opcional por Método sobrecargando o Usando DataType...

/ * / Método de sobrecarga:

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

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

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

La forma más fácil es

|*| Tipo de datos... puede ser parámetro opcional

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

    // |* CodTdo *|
    return RetVar;
}

 0
Author: Sujay U N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-23 10:32:02