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 a un parámetro un valor predeterminado. Por ejemplo:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
¿Java admite este tipo de sintaxis? ¿Hay alguna razón por la cual esta sintaxis de dos pasos es preferible?
public MyParameterizedFunction(String param1, int param2)
es un constructor, no un método, una declaración.Respuestas:
No, la estructura que encontró es cómo Java lo maneja (es decir, con sobrecarga en lugar de parámetros predeterminados).
Para los constructores, consulte Sugerencia del artículo 1 de Java eficaz: Guía del lenguaje de programación (considere métodos de fábrica estáticos en lugar de constructores) si la sobrecarga se complica. Para otros métodos, puede ser útil cambiar el nombre de algunos casos o usar un objeto de parámetro. Esto es cuando tienes suficiente complejidad que diferenciar es difícil. Un caso definitivo es donde debe diferenciarse utilizando el orden de los parámetros, no solo el número y el tipo.
fuente
static
cualquier cosa se considera bastante dañina en 2015. LasBuilder
instancias fluidas de tipo seguro que hacen cumplir contratos de construcción completos y válidos son una solución mucho mejor ahora.new
. Se usan todo el tiempo en código nuevo. Los constructores de objetos de valor simple a menudo son el resultado de una ingeniería excesiva.No, pero puede usar el Patrón del generador , como se describe en esta respuesta de Desbordamiento de pila .
Como se describe en la respuesta vinculada, el Patrón del generador le permite escribir código como
en el que algunos campos pueden tener valores predeterminados o ser opcionales.
fuente
Student s1 = new Student().age(16);
, 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.Hay varias formas de simular parámetros predeterminados en Java:
Método de sobrecarga.
Una de las limitaciones de este enfoque es que no funciona si tiene dos parámetros opcionales del mismo tipo y cualquiera de ellos puede omitirse.
Varargs
a) Todos los parámetros opcionales son del mismo tipo:
b) Los tipos de parámetros opcionales pueden ser diferentes:
El principal inconveniente de este enfoque es que si los parámetros opcionales son de diferentes tipos, pierde la comprobación de tipo estático. Además, si cada parámetro tiene un significado diferente, necesita alguna forma de distinguirlos.
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:
Ahora se deben proporcionar todos los valores de argumentos, pero los valores predeterminados pueden ser nulos.
Clase opcional Este enfoque es similar a los nulos, pero usa la clase Java 8 Opcional para parámetros que tienen un valor predeterminado:
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.
Patrón de constructor. El patrón de constructor se utiliza para constructores y se implementa mediante la introducción de una clase de constructor separada:
Mapas Cuando el número de parámetros es demasiado grande y para la mayoría de ellos se usan valores predeterminados, puede pasar argumentos de método como un mapa de sus nombres / valores:
Tenga en cuenta que puede combinar cualquiera de estos enfoques para lograr un resultado deseable.
fuente
return this
hacer? Además,FooBuilder().setA("a").build();
desde entonces (por definición) el constructor se llama primero yFooBuilder()
devuelve un valor, ¿no significa esto.setA("a"):
que no tiene la oportunidad de ser llamado?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.new FooBuilder()
devuelve unFooBuilder
objeto en el quesetA
se llama al método. ComosetB
no se llama,this.b
conserva el valor predeterminado. Finalmentebuild
se llama al método en esteFooBuilder
objeto. Elbuild
método crea y devuelve unFoo
objeto que se establece en la variableFoo foo
. Tenga en cuenta que elFooBuilder
objeto no está almacenado en ninguna variable.Tristemente no.
fuente
Por desgracia sí.
podría escribirse en Java 1.5 como:
Pero si debe o no depender de cómo se siente acerca del compilador que genera un
para cada llamada
Para múltiples parámetros predeterminados:
podría escribirse en Java 1.5 como:
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, existe una diferencia en la que esto ha llevado a cabo la comprobación del tipo de tiempo para los parámetros predeterminados pasados y el tipo C ++ los verifica durante la compilación.
fuente
assert
código en producción. Lanza una excepción.No, pero puedes emularlos muy fácilmente. Lo que en C ++ fue:
En Java, será una función sobrecargada:
Anteriormente se mencionó 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 pueden manejarse 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 razón, es otra pregunta. Pero la mayoría de nosotros no cree que use Java debido a su simplicidad.
fuente
Puede hacerlo en Scala, que se ejecuta en la JVM y es compatible con los programas Java. http://www.scala-lang.org/
es decir
fuente
No , pero la forma más sencilla de implementar esto es:
o en lugar del operador ternario , puede usar
if
:fuente
Podría estar diciendo lo obvio aquí, pero ¿por qué no simplemente implementar el parámetro "predeterminado" usted mismo?
por defecto, usted usaría
y si no desea usar el predeterminado, usaría
fuente
//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 } } }
Como se mencionó a Scala, Kotlin también vale la pena mencionar. En la función Kotlin, los parámetros también pueden tener valores predeterminados e incluso pueden referirse a otros parámetros:
Al igual que Scala, Kotlin se ejecuta en la JVM y puede integrarse fácilmente en proyectos Java existentes.
fuente
No.
Puede lograr el mismo comportamiento al pasar un objeto que tiene valores predeterminados inteligentes. Pero, de nuevo, depende de cuál sea su caso.
fuente
No. En general, Java no tiene mucho (ningún) azúcar sintáctico, ya que intentaron crear un lenguaje simple.
fuente
const
ygoto
serían palabras clave reservadas sin implementación? - Especialmenteconst
es algo que extraño mucho -final
no es un reemplazo y ellos lo sabían. - Y si tomó la decisión consciente de no implementar nuncagoto
, no tendrá que reservar la palabra clave. - Y más tarde en el Equipo Java engañó haciendo que la Etiqueta se basarabreak
y fueracontinue
tan poderosa como un Pascalgoto
.En lugar de usar:
Puede utilizar la funcionalidad opcional de Java al tener un único método:
La principal diferencia es que debe usar clases de envoltura en lugar de tipos Java primitivos para permitir la
null
entrada.Boolean
en lugar deboolean
, enInteger
lugar deint
y así sucesivamente.fuente
No es compatible, pero hay varias opciones, como usar el patrón de objeto de parámetro con algo de azúcar de sintaxis:
En este ejemplo construimos
ParameterObject
con valores predeterminados y los anulamos en la sección de inicialización de instancia de clase{ param1 = 10; param2 = "bar";}
fuente
Prueba esta solución:
fuente
Puede usar Java Method Invocation Builder para generar automáticamente el generador con valores predeterminados.
Simplemente agregue @GenerateMethodInvocationBuilder a la clase o interfaz, y @Default a los parámetros en los métodos donde desea valores predeterminados. Se generará un generador en tiempo de compilación, utilizando los valores predeterminados que especificó con sus anotaciones.
Y luego puedes invocar los métodos.
O establezca cualquiera de los valores predeterminados en otra cosa.
fuente
Un enfoque similar a https://stackoverflow.com/a/13864910/2323964 que funciona en Java 8 es utilizar una interfaz con captadores predeterminados. Esto será más detallado en espacios en blanco, pero se puede burlar, y es ideal para cuando tienes un montón de instancias en las que realmente quieres llamar la atención sobre los parámetros.
fuente
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í:
fuente
Así es como lo hice ... no es tan conveniente tal vez como tener un 'argumento opcional' contra su parámetro definido, pero hace el trabajo:
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 verdadero reemplazará todo el texto en mi TextArea con la cadena provista. Establecer wipeClean en falso o dejarlo todo junto simplemente agrega el texto proporcionado al TextArea.
También tenga en cuenta que no estoy repitiendo código en los dos métodos, simplemente estoy agregando la funcionalidad de poder restablecer 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 tendríamos que 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 a la larga es más fácil de leer en mi humilde opinión.
fuente
NO, pero tenemos una alternativa en forma de sobrecarga de funciones.
llamado cuando no pasó ningún parámetro
llamado cuando se pasó el parámetro "a"
llamado cuando pasa el parámetro b
fuente
Hay media docena o más problemas como este, eventualmente, llega al patrón de fábrica estático ... vea la API de cifrado para eso. Es 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 Boolean isValid; (junto con el nulo como valor predeterminado v constructor fallido) o arroje una excepción que nunca sea informativa al recuperarlo de los usuarios de campo.
Código Correcto, maldita sea, escribo mil constructores de líneas y hago lo que necesito. Encuentro usar 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 estático de fábrica. Parece que puede hacer mucho si en una llamada al método, todavía hay problemas de sync (), pero los valores predeterminados se pueden 'sustituir' mejor (más seguro)
Creo que lo que tenemos que hacer aquí es abordar el problema de nulo como valor predeterminado frente a algo String one = new String (""); como una variable miembro, luego realiza una comprobación de nulo antes de asignar la cadena pasada al constructor.
Muy notable la cantidad de informática en bruto estratosférica realizada en Java.
C ++ y demás tiene librerías de proveedores, sí. Java puede superarlos en servidores a gran escala debido a que es una caja de herramientas masiva. Estudie los bloques de inicializador estático, quédese con nosotros.
fuente
No es compatible en Java como en otro idioma para ex. Kotlin
fuente
Puedes usar lo siguiente:
fuente