¿Es la sobrecarga realmente la única forma de obtener valores predeterminados para los parámetros de los métodos en Java?

StackOverflow https://stackoverflow.com/questions/618276

  •  03-07-2019
  •  | 
  •  

Pregunta

Soy bastante nuevo en Java y desde Python y PHP, estoy acostumbrado a los valores predeterminados para los parámetros de función.

Por lo tanto, tengo la costumbre de escribir métodos que están diseñados para ser llamados desde situaciones ligeramente diferentes en las que desea establecer solo algunos de los valores. Por ejemplo, en mi código PHP, esto sería común cuando tengo métodos de fábrica que proporcionan instancias de objetos con propiedades ligeramente diferentes.

Al parecer, en Java, tengo que tener un método que espere todos los parámetros y luego varias variaciones sobrecargadas que llamen a ese método con algunos de los parámetros establecidos en valores predeterminados y algunos proporcionados por el llamante. Lo que está bien, está bien, pero a veces me pone de los nervios.

Recuerdo que esto ya me molestó en algunas breves excursiones a C ++ y ActionScript. Ahora, ¿los desarrolladores de Java más experimentados tienen algún acceso directo para esto?

Me parece que, técnicamente, la pregunta ha sido respondida por la suma de todas las publicaciones como " Sí, es " ;. Abro una publicación wiki a continuación para recopilar las diversas soluciones alternativas, por favor contribuya si lo desea. Encontré todos estos muy útiles como inspiración y como ejemplos de aprendizaje para construcciones típicas de Java.

¿Fue útil?

Solución 6

Parece que, " Sí, es " ;, excepto:

Se podrían lograr efectos similares con varargs como se sugiere por Paul Whelan o definiendo un tipo extra que contenga los parámetros como campos con los valores predeterminados adecuados como lo sugiere Jon Skeet. Boris Pavlovic agrega que su tipo podría ser una clase estática interna para mantener las cosas ordenadamente en el lugar correcto.

Contras (Tenga en cuenta que toda esta pregunta no tiene nada que ver con implicaciones serias, solo sobre ajustes convenientes):

Los Varargs parecen más adecuados para pasar una lista de valores de longitud variable que tienen una forma muy similar y un significado mayormente equivalente, como una lista de nombres. Si se utiliza para el propósito establecido en la pregunta, el método tendría que realizar varias comprobaciones en la lista para interpretarla, lo que no parece ser más, pero menos conveniente.

Un tipo especial que lleva los parámetros parece más útil si el tipo resultante podría tener otros usos que el simple hecho de pasar a un método en particular, o cuando se trata de un conjunto de parámetros más complejo. Si hay 2-4 parámetros y algunos pueden tener valores predeterminados, todavía parece un poco más conveniente para la sobrecarga, pero eso podría ser una cuestión de gusto personal.

Otros consejos

Otra opción es una variación en el patrón del constructor: tiene un tipo que representa todos los parámetros, construye una instancia de ese tipo (que de manera predeterminada) establece las propiedades que desea y luego pasa el resultado al método original , o agregue un método en el " tipo de parámetro " para llamar al método por ti.

Puede ver esto en acción en las bibliotecas estándar, con ProcessBuilder y Proceso .

ver varargs

http : //www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html

(URL actualizada; este comentario se agregó porque stackoverflow requiere > 30 caracteres)

Para hacer esto más simple, creé una anotación para los valores predeterminados y un procesador de anotaciones que genera una superclase con los métodos sobrecargados. Por ejemplo:

protected void process(
    Processor processor,
    String item,
    @Default("Processor.Size.LARGE") Size size,
    @Default("red") String color,
    @Default("1") int quantity) {
        ...
}

que genera (en una superclase generada)

protected void process(sample.Processor processor, java.lang.String item)  {
    process(processor, item, Processor.Size.LARGE, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size)  {
    process(processor, item, size, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size, 
                       java.lang.String color)  {
    process(processor, item, size, color, 1);
}
protected abstract void process(sample.Processor processor, 
                                java.lang.String item, 
                                sample.Processor.Size size, 
                                java.lang.String color, 
                                int quantity) ;

Consulte http://code.google.com/p/javadude/wiki/ Anotaciones - Scott

Puede ser muy difícil tratar de traducir su proceso de un idioma a otro. Puede, como otros lo han señalado, hacer algunos arreglos para obtener lo que quiere ... pero cuanto antes " acepte " la forma en que Java está diseñado para funcionar mejor será cuando trabajes en Java.

He tenido que hacer algunas cosas de PHP ... me molestó hasta el extremo que no pude hacer lo que quería ... así que va en ambos sentidos.

El mayor obstáculo con el que se encontrará es la tipificación estática. Hay cosas que puedes intentar hacer para solucionarlo, pero al final serán un hack muy grande.

En los primeros días de C ++, las personas intentaban convencer a C ++ para que se comportara como Smalltalk ... no funcionó demasiado bien. En los primeros días, si la gente de Java intentaba tomar su conocimiento de C ++ y utilizarlo en Java ... no funcionó demasiado bien (lo que es doblemente frustrante ya que los lenguajes son muy similares en la superficie).

Mi consejo, para su codificación Java, aprenda a programar como un desarrollador de Java en lugar de un desarrollador de PHP.

Para su problema inmediato, ¿es posible que realmente deba volver a sintonizar diferentes clases de fábrica en lugar de crear el mismo tipo de objeto con diferentes variables establecidas?

Siempre que codifique de manera OO, no perderá los valores predeterminados en Java. Los argumentos predeterminados son útiles solo en el estilo de codificación de procedimiento.

En OO, en lugar de pasar el estado a través de los métodos / procedimientos, el estado ya está en el objeto al que llama, o los objetos que pasa como parámetros. La mayoría de las veces no necesita más de 1 o 2 parámetros en sus métodos.

Si desea configurar su objeto antes de usarlo, lo construiría con un constructor simple y luego llamaría a diferentes configuradores. Esto hace que el código sea mucho más legible (porque ve los nombres del configurador), en comparación con llamar a un constructor que tiene muchos argumentos. Y en el caso de que un nuevo atributo venga después, puede agregarlo a su objeto sin tener que modificar los métodos de fábrica existentes.

Sí por oop es su sobrecarga, que es la única forma de usar el parámetro predeterminado en java. Pero aquí está el truco para ti. Si utiliza la sobrecarga y desea tener el parámetro por defecto. Entonces terminarás

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

Pero utilizando varargs

public class DefaultValue
{
 public static void main(String[] args)
  {
       defaultParameter();
       defaultParameter(true);
  }

  public static void defaultParameter(Boolean …gender)
  {
       boolean genderBoolean = false; // It is the default value you want to give
       if(1 == gender.length)
       {
            genderBoolean = gender[0]; // Overrided Value
      }
       System.out.println(genderBoolean);
 }
}

La salida del código anterior será

false
true

Para obtener ejemplos y explicaciones más similares, visite java-default-Parameter-valores

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top