¿Java admite valores de parámetros predeterminados?

Encontré un código Java que tenía la siguiente estructura:

public MyParameterizedFunction(String param1, int param2)
{
    this(param1, param2, false);
}

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    //use all three parameters here
}

Sé que en C ++ puedo asignar un valor predeterminado a un parámetro. Por ejemplo:

void MyParameterizedFunction(String param1, int param2, bool param3=false);

¿Java admite este tipo de sintaxis? ¿Hay alguna razón por la que sea preferible esta sintaxis de dos pasos?

preguntado el 15 de junio de 09 a las 15:06

No. Sin embargo, el patrón Builder puede ayudar. -

Realmente extraño esta característica. Ayuda mucho al modificar el código existente para llevar un parámetro adicional a una función o constructor -

@Jatin Con la refactorización "Cambiar firma del método" de Eclipse, puede agregar un parámetro y proporcionar un valor predeterminado que usarán los invocadores existentes. -

@ErwinBolwidt Gracias. Estoy usando Android Studio y también tiene la opción de refactorizar el método y proporcionar valores predeterminados. Bastante útil. -

@nombre_de_usuario_temporal public MyParameterizedFunction(String param1, int param2) es un constructor, no un método, declaración. -

25 Respuestas

No, la estructura que encontró es cómo la maneja Java (es decir, con sobrecarga en lugar de parámetros predeterminados).

Para constructores, Consulte Effective Java: Programming Language Guide's Consejo del artículo 1 (considere los métodos de fábrica estáticos en lugar de los constructores) si la sobrecarga se complica. Para otros métodos, puede resultar útil cambiar el nombre de algunos casos o utilizar un objeto de parámetro. Aquí es cuando tienes la complejidad suficiente para que la diferenciación sea difícil. Un caso definido es el que tiene que diferenciar utilizando el orden de los parámetros, no solo el número y el tipo.

Respondido el 13 de Septiembre de 13 a las 18:09

esto fue en 2009, static cualquier cosa se considera prácticamente dañina en 2015. Escriba con fluidez segura Builder Las instancias que hacen cumplir contratos de construcción completos y válidos son una solución mucho mejor ahora. - usuario177800

@JarrodRoberson: Los métodos de fábrica estáticos no son más dañinos que new. Ellos son usado todo el hora en nuevo código. Los constructores de objetos de valor simples a menudo son el resultado de una ingeniería excesiva. - lii

@JarrodRoberson: Interesante forma de forzar el uso correcto a través del compilador, ¡gracias por compartir! Sugerencia amistosa para publicaciones futuras: 300 líneas de código fuente sin comentarios probablemente sea un poco difícil de digerir para la mayoría de las personas (después de todo, el código es más difícil de leer que de escribir). ¡Gracias de nuevo! - Christian Aichinger

@JarrodRoberson: ¡Bien, estoy deseando que llegue! Lo que quería comunicar: como lector de su blog, un ejemplo de 50 líneas con una breve descripción de lo que está sucediendo me ayudaría más de 300 líneas sin contexto. - Christian Aichinger

@ user177800 En desacuerdo: los métodos estáticos, si se escriben como funciones puras, están perfectamente bien. Es cuando una función estática muta en un estado que se convierte en un problema ... - levi fuller

No, pero puedes usar el Patrón de constructor, como se describe en esta respuesta de Stack Overflow.

Como se describe en la respuesta vinculada, Builder Pattern le permite escribir código como

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

en el que algunos campos pueden tener valores predeterminados o ser opcionales.

contestado el 23 de mayo de 17 a las 13:05

Finalmente, un gran ejemplo de menos de 2 páginas del patrón Builder. - no importa

Sin embargo, tengo curiosidad, ¿por qué necesitamos una clase de constructor cuando usamos el patrón de constructor? Estaba pensando en Student s1 = new Student (). Name ("Spicolo"). Age (16) .motto ("Aloha, Mr Hand); - ivanceras

@ivanceras: es relevante cuando las clases tienen campos obligatorios y no desea poder crear una instancia de esas clases en un estado no válido. Así que si dijiste Student s1 = new Student().age(16); entonces eso te dejaría con un Estudiante sin nombre, lo que podría ser malo. Si no está mal, entonces su solución está bien. - eli cortesano

@ivanceras: otra razón es que es posible que desee que su clase sea inmutable después de la construcción, por lo que no querrá métodos en ella que cambien sus valores. - Jules

@ivanceras: utilicé Builders para 3 cosas: eliminar el argumento múltiple y la inicialización fluida, la inmutabilidad y, lo más importante, creo que validar el objeto de dominio en el método build () ¿Por qué crear una instancia de objeto si no es válido? También puede sobrecargar estática métodos de fábrica como en el caso anterior buildFreshman (), buildSenior () etc - Abhijeet Kushe

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

  1. Sobrecarga de métodos.

    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 se puede omitir cualquiera de ellos.

  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 diferentes tipos, se pierde la verificación de tipos estáticos. 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 el cuerpo de un 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 usa la clase opcional de 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.

  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 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 utilizar 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 = (String)parameters.get("a");
        } else 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.

Respondido el 15 de junio de 18 a las 00:06

Buena explicación. Nunca he visto valores de retorno usados ​​así. Para 5) ¿qué hacen los return this ¿hacer? Además, no FooBuilder().setA("a").build(); ya que (por definición) el constructor se llama primero y FooBuilder() devuelve un valor, ¿no significa esto .setA("a"): no tiene la oportunidad de ser llamado? - celeritas

@celeritas return this devuelve el mismo objeto en el que se llamó al método (en el ejemplo, FooBuilder). Esto permite el encadenamiento de métodos en una declaración que actúa sobre el mismo objeto: new FooBuilder().setA(..).setB(..).setC(..) etc en lugar de llamar a cada método en una declaración separada. - ADTC

@celeritas new FooBuilder() devuelve un FooBuilder objeto en el que el setA se llama al método. Como setB no se llama, this.b conserva el valor predeterminado. Finalmente, el build se llama al método en este FooBuilder objeto. los build El método crea y devuelve un Foo objeto que se establece en la variable Foo foo. Note que el FooBuilder El objeto no se almacena en ninguna variable. - ADTC

La anotación también se puede utilizar para crear parámetros predeterminados y es más útil cuando se requiere para colecciones polimórficas. docs.oracle.com/javase/tutorial/java/annotations/declaring.html - Martín Spamer

Más de 900 votos a favor sobre la misma respuesta en dos preguntas. Estoy impresionado: stackoverflow.com/questions/965690/java-opcional-parámetros/… - adammc331

Tristemente no.

Respondido el 15 de junio de 09 a las 19:06

Es tan triste Hacerlo introduciría firmas de funciones potencialmente ambiguas. - Trey

@Trey: los lenguajes con parámetros predeterminados a menudo eliminan la sobrecarga de funciones, ya que son menos atractivos. Así que no hay ambigüedad. Además, Scala agregó la característica en 2.8 y de alguna manera resolvió el problema de la ambigüedad (ya que mantuvieron la sobrecarga por razones de compatibilidad). - Filho

No veo cómo los valores predeterminados de los parámetros evitan la sobrecarga de funciones. C #, por ejemplo, permite anulaciones y también permite inicializaciones predeterminadas. Parece una elección arbitraria, no la restricción es la razón. - FlavorScape

Sí, vamos a hacer un intercambio de hacer que el compilador haga un trabajo adicional y en su lugar hacer que todos escribamos 100000 sobrecargas para brindar comodidad a los usuarios de nuestra biblioteca. Buena idea. - usuario562566

@ user562566: Siempre que trabajo en un proyecto de Java, tengo la impresión de que a los desarrolladores de Java se les paga / miden por la cantidad de líneas de código que producen por día. marca k cowan

Por desgracia sí.

void MyParameterizedFunction(String param1, int param2, bool param3=false) {}

podría escribirse en Java 1.5 como:

void MyParameterizedFunction(String param1, int param2, Boolean... params) {
    assert params.length <= 1;
    bool param3 = params.length > 0 ? params[0].booleanValue() : false;
}

Pero si debe o no depender de cómo se siente acerca del compilador generando un

new Boolean[]{}

para cada llamada.

Para múltiples parámetros predeterminados:

void MyParameterizedFunction(String param1, int param2, bool param3=false, int param4=42) {}

podría escribirse en Java 1.5 como:

void MyParameterizedFunction(String param1, int param2, Object... p) {
    int l = p.length;
    assert l <= 2;
    assert l < 1 || Boolean.class.isInstance(p[0]);
    assert l < 2 || Integer.class.isInstance(p[1]);
    bool param3 = l > 0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue() : 42;
}

Esto coincide con la sintaxis de C ++, que solo permite parámetros predeterminados al final de la lista de parámetros.

Más allá de la sintaxis, hay una diferencia en la que se realiza una verificación de tipo en tiempo de ejecución para los parámetros pasados ​​por defecto y el tipo de C ++ los verifica durante la compilación.

Respondido 03 Oct 13, 22:10

Inteligente, pero varargs (...) solo se puede usar para el parámetro final, que es más limitante de lo que le brindan los lenguajes que admiten los parámetros predeterminados. - CortinaPerro

eso es inteligente pero un poco complicado en comparación con la versión C ++ - Alguien en alguna parte

Java definitivamente necesita parámetros opcionales predeterminados como C # y otros lo permiten ... la sintaxis es obvia y supongo que pueden implementar esto de manera bastante simple incluso compilando todas las combinaciones posibles ... No puedo imaginar por qué no lo han agregado al lenguaje ¡aún! - jwl

Uno nunca debe usar un assert en código de producción. Lanza una excepción. - miguel dorst

-1 Esto realmente no es para lo que son los varargs. Este es un truco. - en este caso, el uso de sobrecargas será mucho más legible (lo cual es desafortunado, ya que tres caracteres adicionales son más legibles que 5 líneas adicionales de fuente ...). - pero Java no es compatible con los parámetros predeterminados. - BrainSlugs83

No, pero puedes emularlos muy fácilmente. Lo que en C ++ era:

public: void myFunction(int a, int b=5, string c="test") { ... }

En Java, será una función sobrecargada:

public void myFunction(int a, int b, string c) { ... }

public void myFunction(int a, int b) {
    myFunction(a, b, "test");
}

public void myFunction(int a) {
    myFunction(a, 5);
}

Se mencionó anteriormente que los parámetros predeterminados causaron casos ambiguos en la sobrecarga de funciones. Eso simplemente no es cierto, podemos ver en el caso de C ++: sí, tal vez pueda crear casos ambiguos, pero estos problemas se pueden manejar fácilmente. Simplemente no se desarrolló en Java, probablemente porque los creadores querían un lenguaje mucho más simple como lo era C ++; si tenían derecho, es otra cuestión. Pero la mayoría de nosotros no creemos que use Java debido a su simplicidad.

Respondido 18 Oct 17, 04:10

La idea principal de la notación de valor predeterminado de C # es precisamente evitar esta codificación repetitiva y tener un solo constructor en lugar de muchos. - Kolia Ivankov

@KolyaIvankov No sé C #, pero sé C ++ donde el razonamiento es el mismo. No sé qué es mejor, pero creo que, en realidad, el compilador genera el mismo código repetitivo en el caso de C ++ / C # y va al binario final. - peterh - Reincorporar a Monica

Cada lenguaje de programación es (en particular) un medio para evitar una repetición de ensamblador, ¿me equivoco? La pregunta es solo si ofrece una funcionalidad útil o no. - Kolia Ivankov

La primera oración es una pregunta retórica. La palabra "pregunta" en la segunda oración no tiene nada que ver con la pregunta retórica en la primera. - Kolia Ivankov

Siendo más específico: los lenguajes son herramientas que nos permiten escribir programas de una manera que podamos tener control sobre lo que está escrito, compilar es una forma de decirle a una máquina lo que queremos de ella. Una herramienta es más útil si nos permite evitar la repetición. En efecto, gnavi preguntó, si pueden evitar precisamente el tipo de código repetitivo que propones como respuesta, ya que C # lo permite. - Kolia Ivankov

Puede hacer esto en Scala, que se ejecuta en la JVM y es compatible con los programas Java. http://www.scala-lang.org/

es decir,

class Foo(var prime: Boolean = false, val rib: String)  {}

Respondido 03 Abr '12, 14:04

¿Trae un lenguaje completamente nuevo para obtener una característica no tan común? - Om nom nom

@ om-nom-nom: Java nunca debería existir. Decir que una característica no se usa es equivalente a que nadie la necesita es decir que Java no era popular antes de que fuera inventado significa que Gosling no debería comenzar a diseñarlo. - ola

@Val solo dice que esto es como disparar pájaros con cañones - Om nom nom

eso no tiene nada que ver con la pregunta del OP - épico

También funciona en Kotlin. Y Groovy. Y C#. Y Javascript. Y casi todos los demás lenguajes que están hechos para personas y problemas reales. - spyro

No, pero la forma más sencilla de implementar esto es:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    param3 = param3 == null ? false : param3;
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

or en vez de operador ternario, puedes usar if:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    if (param3 == null) {
        param3 = false;
    }
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

Respondido el 27 de junio de 19 a las 12:06

Sí, este enfoque parece ser el mejor de las otras alternativas. Aún así, sería bueno que Java adoptara valores predeterminados; Kotlin demostró que esto se puede hacer, por lo que no estoy seguro de por qué Oracle no ingresa a la era moderna y sigue diseñando Java como si fuera la década de 1990. :D - shevy

Podría estar diciendo lo obvio aquí, pero ¿por qué no simplemente implementar el parámetro "predeterminado" usted mismo?

public class Foo() {
        public void func(String s){
                func(s, true);
        }
        public void func(String s, boolean b){
                //your code here
        }
}

por defecto, usaría

func("my string");

y si no quisiera usar el predeterminado, usaría

func("my string", false);

Respondido 24 Oct 19, 21:10

El cartel preguntó si este patrón (bastante feo) se puede evitar ... ;-) En lenguajes más modernos (como c #, Scala) no necesitas estas sobrecargas adicionales que solo crean más líneas de código. Hasta cierto punto, puede usar varargs mientras tanto (static int max (int ... array) {}), pero son solo una solución muy fea. - Oferta

La sobrecarga no es fea y tiene muchos beneficios, como que diferentes llamadas a métodos con diferentes firmas pueden realizar diferentes funciones. //This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } } //Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } } - Cabina de antony

Bueno, si uno quiere un comportamiento diferente. Si la única diferencia es un ligero cambio en los cálculos, etc., es seguro que crear múltiples firmas es una pérdida de esfuerzo. Los valores predeterminados tienen sentido donde los necesita ... y la falta de ellos no debe clasificarse como un requisito "inútil". - Kapil

Los parámetros predeterminados de @Offler no tienen nada que ver con el "lenguaje moderno". Los usé en Delphi hace 20 años y probablemente ya existían en Turbo Pascal. - El increíble Jan

Estoy de acuerdo con Offler y en desacuerdo con Antony Booth. No solo lo encuentro feo sino también bastante ineficiente. Los lenguajes como ruby ​​o python hacen que sea trivial el uso de parámetros predeterminados; Supongo que lo que Java requiere que hagas es encontrar (y usar) soluciones alternativas. El cheque explícito versus nulo parece ser la opción menos fea, ya que también puedo llamarlo desde la línea de comandos (simplemente no proporcionar nada, y luego manejar la variante sensata); el enfoque de sobrecarga del operador parece ... muy detallado (como al menos +3 líneas, en comparación con la verificación nula, y más líneas si el código es más complejo). - shevy

En lugar de usar:

void parameterizedMethod(String param1, int param2) {
    this(param1, param2, false);
}

void parameterizedMethod(String param1, int param2, boolean param3) {
    //use all three parameters here
}

Puede utilizar la funcionalidad opcional de Java teniendo un solo método:

void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
    param3 = Optional.ofNullable(param3).orElse(false);
    //use all three parameters here
}

La principal diferencia es que debe usar clases contenedoras en lugar de tipos primitivos de Java para permitir null entrada.Boolean en lugar de boolean, Integer en lugar de int y así sucesivamente.

Respondido 14 Feb 20, 11:02

Como se mencionó a Scala, Kotlin también vale la pena mencionarlo. En Kotlin, los parámetros de la función también pueden tener valores predeterminados e incluso pueden hacer referencia a otros parámetros:

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
    ...
}

Al igual que Scala, Kotlin se ejecuta en JVM y se puede integrar fácilmente en proyectos Java existentes.

respondido 26 nov., 17:19

No. En general, Java no tiene mucho (ningún) azúcar sintáctico, ya que intentaron hacer un lenguaje simple.

Respondido el 15 de junio de 09 a las 19:06

No exactamente. La amarga verdad es que el equipo tenía una agenda apretada y no tenía tiempo para el azúcar sintáctico. ¿Por qué más lo haría? const y goto ¿Serán palabras clave reservadas las cuales no implementarán? - Especialmente const es algo que extraño amargamente - final no es un reemplazo y ellos lo sabían. - Y si hiciste el consciente decisión de nunca implementar goto no necesitará reservar la palabra clave. - Y más tarde, el equipo de Java hizo trampa al hacer que la etiqueta se basara break y continue tan poderoso como un pascal goto. - Martin

"Simple, orientado a objetos y familiar" era de hecho un objetivo de diseño; consulte oracle.com/technetwork/java/intro-141325.html - mikera

tomjen dijo: "No. En general, Java no tiene mucho (ningún) azúcar sintáctico, ya que intentaron hacer un lenguaje simple". Entonces estás diciendo que eliminar muchas características innecesarias de C ++ hace que Java sea un lenguaje simple, entonces dime por qué Java tiene métodos variadic. ¿Por qué tiene varargs? No es necesario si simplemente puede usar una matriz de objetos en su lugar, ¿verdad? Entonces, los varargs se pueden eliminar del lenguaje, porque es innecesario. Esto hará que Java sea más simple de lo que es ahora. Estoy en lo cierto? La sobrecarga también se puede eliminar, porque tiene infinitos nombres para cada método. - usuario2133061

y es por eso que tenemos Spring y cosas que toman el lenguaje simple y convierten cualquier proyecto Java real en un clúster de sintaxis y repetición :-) - matanster

Obligar a los desarrolladores a utilizar código repetitivo y soluciones complicadas no es lo que yo entiendo de la palabra "fácil". myFunction (a, b = false, c = 3), eso es lo que yo llamo fácil. - spyro

No.

Puede lograr el mismo comportamiento pasando un objeto que tiene valores predeterminados inteligentes. Pero nuevamente depende de cuál sea su caso.

Respondido el 13 de Septiembre de 13 a las 18:09

No es compatible, pero hay varias opciones, como usar el patrón de objeto de parámetro con algo de sintaxis:

public class Foo() {
    private static class ParameterObject {
        int param1 = 1;
        String param2 = "";
    }

    public static void main(String[] args) {
        new Foo().myMethod(new ParameterObject() {{ param1 = 10; param2 = "bar";}});
    }

    private void myMethod(ParameterObject po) {
    }
}

En esta muestra construimos ParameterObject con los valores predeterminados y anótelos en la sección de inicialización de la instancia de clase { param1 = 10; param2 = "bar";}

Respondido el 13 de diciembre de 12 a las 17:12

Prueba esta solución:

public int getScore(int score, Integer... bonus)
{
    if(bonus.length > 0)
    {
        return score + bonus[0];
    }

    return score;
}

Respondido el 03 de Septiembre de 14 a las 17:09

Puedes utilizar Generador de invocaciones de métodos Java para generar automáticamente el constructor con valores predeterminados.

Simplemente agregue @GenerateMethodInvocationBuilder a la clase o interfaz, y @Default a los parámetros en los métodos en los que desea valores predeterminados. Se generará un constructor en el momento de la compilación, utilizando los valores predeterminados que especificó con sus anotaciones.

@GenerateMethodInvocationBuilder
public class CarService {
 public CarService() {
 }

 public String getCarsByFilter(//
   @Default("Color.BLUE") Color color, //
   @Default("new ProductionYear(2001)") ProductionYear productionYear,//
   @Default("Tomas") String owner//
 ) {
  return "Filtering... " + color + productionYear + owner;
 }
}

Y luego puede invocar los métodos.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .invoke(instance);

O establezca cualquiera de los valores predeterminados en otra cosa.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);

Respondido el 13 de junio de 16 a las 18:06

No es compatible con Java como en otros idiomas, por ejemplo. Kotlin.

Respondido el 15 de diciembre de 19 a las 17:12

Un enfoque similar a https://stackoverflow.com/a/13864910/2323964 que funciona en Java 8 es usar una interfaz con captadores predeterminados. Esto será más detallado en espacios en blanco, pero se puede burlar, y es ideal para cuando tiene un montón de casos en los que realmente desea llamar la atención sobre los parámetros.

public class Foo() {
    public interface Parameters {
        String getRequired();
        default int getOptionalInt(){ return 23; }
        default String getOptionalString(){ return "Skidoo"; }
    }

    public Foo(Parameters parameters){
        //...
    }

    public static void baz() {
        final Foo foo = new Foo(new Person() {
            @Override public String getRequired(){ return "blahblahblah"; }
            @Override public int getOptionalInt(){ return 43; }
        });
    }
}

contestado el 23 de mayo de 17 a las 12:05

Ahora he pasado bastante tiempo para descubrir cómo usar esto con métodos que devuelven valores, y hasta ahora no he visto ningún ejemplo, pensé que podría ser útil agregar esto aquí:

int foo(int a) {
    // do something with a
    return a;
}

int foo() {
    return foo(0); // here, 0 is a default value for a
}

respondido 12 mar '19, 12:03

Así es como lo hice ... quizás no sea tan conveniente como tener un 'argumento opcional' contra su parámetro definido, pero hace el trabajo:

public void postUserMessage(String s,boolean wipeClean)
{
    if(wipeClean)
    {
        userInformation.setText(s + "\n");
    }
    else
    {
        postUserMessage(s);
    }
}

public void postUserMessage(String s)
{
    userInformation.appendText(s + "\n");
}

Observe que puedo invocar el mismo nombre de método con solo una cadena o puedo invocarlo con una cadena y un valor booleano. En este caso, establecer wipeClean en true reemplazará todo el texto en mi TextArea con la cadena proporcionada. Establecer wipeClean en false o dejarlo todo junto simplemente agrega el texto proporcionado al TextArea.

También observe que no estoy repitiendo código en los dos métodos, simplemente estoy agregando la funcionalidad de poder restablecer el TextArea creando un nuevo método con el mismo nombre solo con el booleano agregado.

De hecho, creo que esto es un poco más limpio que si Java proporcionara un "argumento opcional" para nuestros parámetros, ya que necesitaríamos codificar los valores predeterminados, etc. En este ejemplo, no necesito preocuparme por nada de eso. Sí, he agregado otro método a mi clase, pero es más fácil de leer a largo plazo en mi humilde opinión.

Respondido el 18 de enero de 15 a las 15:01

NO, pero tenemos una alternativa en forma de sobrecarga de funciones.

llamado cuando no pasa ningún parámetro

void operation(){

int a = 0;
int b = 0;

} 

llamado cuando se pasó "un" parámetro

void operation(int a){

int b = 0;
//code

} 

llamado cuando pasó el parámetro b

void operation(int a , int b){
//code
} 

Respondido el 01 de Septiembre de 16 a las 07:09

Hay media docena o mejores problemas como este, eventualmente, llega al patrón de fábrica estático ... vea la API de cifrado para eso. Ordenar difícil de explicar, pero piénselo de esta manera: si tiene un constructor, predeterminado o no, la única forma de propagar el estado más allá de las llaves es tener un booleano isValid; (junto con el valor nulo como valor predeterminado v constructor fallido) o lanzar una excepción que nunca es informativa cuando se recupera de los usuarios de campo.

Code Correct al diablo, escribo miles de constructores de líneas y hago lo que necesito. Encuentro el uso de isValid en la construcción de objetos, en otras palabras, constructores de dos líneas, pero por alguna razón, estoy migrando al patrón de fábrica estático. Parece que puede hacer mucho si en una llamada a un método, todavía hay problemas de sincronización () pero los valores predeterminados se pueden 'sustituir' mejor (más seguro)

Creo que lo que tenemos que hacer aquí es abordar el problema de null como valor predeterminado frente a algo String one = new String (""); como una variable miembro, luego haciendo una verificación de nulo antes de asignar una cadena pasada al constructor.

Es muy notable la cantidad de informática pura y estratosférica realizada en Java.

C ++ y así sucesivamente tienen bibliotecas de proveedores, sí. Java puede superarlos en servidores a gran escala debido a que es una caja de herramientas masiva. Estudie los bloques de inicializadores estáticos, quédese con nosotros.

Respondido 24 Oct 19, 21:10

Una idea es usar String... args

public class Sample {
   void demoMethod(String... args) {
      for (String arg : args) {
         System.out.println(arg);
      }
   }
   public static void main(String args[] ) {
      new Sample().demoMethod("ram", "rahim", "robert");
      new Sample().demoMethod("krishna", "kasyap");
      new Sample().demoMethod();
   }
}

Salida

ram
rahim
robert
krishna
kasyap

del https://www.tutorialspoint.com/Does-Java-support-default-parameter-values-for-a-method

Respondido 25 Jul 20, 09:07

Si realmente lo desea, puede verificarlo manualmente usando null:

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    if(param3 == null) {
        param3 = false;
    }
}

Sin embargo, recomiendo usar algo más, como una sobrecarga o una fábrica estática. Tal vez pueda salirse con la suya, pero puede conducir a un comportamiento inesperado. Por ejemplo, podría tener un error en su código, de modo que su booleano nunca obtenga un valor. En este caso no obtendría un NullPointerException. En su lugar, parecerá que se estableció en falso, lo que puede ser muy confuso de depurar.

Respondido el 27 de diciembre de 20 a las 14:12

Puede utilizar lo siguiente:

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}

Respondido el 30 de diciembre de 19 a las 07:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.