Pregunta Parámetros opcionales de Java


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


621
2018-06-08 16:12


origen


Respuestas:


varargs podría hacer eso (de alguna manera). Aparte de eso, todas las variables en la declaración 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);
}

410
2018-06-08 16:14



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<Integer> bOpt) {
        Integer b = bOpt.isPresent() ? bOpt.get() : 0;
        //...
    }
    
    foo("a", Optional.of(2));
    foo("a", Optional.<Integer>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, así que no hay necesidad de usar guayaba por 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<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.


1389
2017-10-21 01:16



Puedes usar algo como esto:

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

los params variable 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.


93
2017-12-03 21:41



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 : false;
}

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


84
2018-04-02 12:02



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


47
2018-06-08 17:00



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
2018-06-08 16:18



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.


21
2018-06-08 17:05



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

11
2017-08-24 10:44