Parámetros opcionales de Java

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

    varargs podría hacer eso (de alguna manera). Aparte de eso, todas las variables en la statement del método deben ser suministradas. Si desea que una variable sea opcional, puede sobrecargar el método utilizando una firma que no requiere el parámetro.

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

    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 inconveniente de este enfoque es que si los parámetros opcionales son de tipos diferentes, se pierde la comprobación del tipo estático. Además, si cada parámetro tiene un significado diferente, necesita alguna forma de distinguirlos.

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

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

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

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

      Actualización: Java 8 incluye la clase java.util.Optional out-of-the-box, por lo que no es necesario usar guayaba para este motivo en particular en java 8. Sin embargo, el nombre del método es un poco diferente.

    5. Patrón de constructor El patrón de constructor se usa para constructores y se implementa mediante la introducción de una clase de generador por separado:

        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 usan generalmente los valores predeterminados, puede pasar los argumentos del método como un mapa de sus nombres / valores:

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

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

    Puedes usar algo como esto:

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

    La variable params es opcional. Se trata como una matriz anulable 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 es compatible con Java 1.4 o anterior).

    Veo que el usuario bhoot también lo menciona a continuación.

    Hay parámetros opcionales con Java 5.0. Solo declara tu función así:

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

    puedes llamar con doSomething(); o hacer algo doSomething(true); ahora.

    Desafortunadamente, Java no admite parámetros predeterminados directamente.

    Sin embargo, he escrito un conjunto de anotaciones JavaBean, y una de ellas admite 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 de métodos para admitir esto correctamente.

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

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

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

    VarArgs y sobrecarga han sido mencionados. Otra opción es un patrón Builder, que se vería así:

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

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

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

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

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

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

    Puedes hacer cosas usando métodos de sobrecarga como este.

      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 pase null como primer parámetro.

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

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

    La sobrecarga es buena, pero si hay muchas variables que necesitan un valor predeterminado, terminarás 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 explicación.

    Java ahora admite opcionales en 1.8, estoy atascado con la progtwigción en Android, así que estoy usando valores nulos 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 } 

    Puede usar una clase que funcione de forma similar a un generador para contener sus valores opcionales de esta manera.

     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 como

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

    La salida es

     someString = something, someInt = 5 

    Para omitir todos los valores opcionales, debe 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 varargs. Este enfoque sería incluso mejor si puede usar anotaciones y generación de código para crear la clase Opciones.

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

    En Java, debemos 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-

    Podemos hacer un parámetro opcional por sobrecarga de método o usando DataType …

    | * | Sobrecarga de método:

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

    La manera más fácil es

    | * | DataType … puede ser un parámetro opcional

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