java - resultado - ¿Es problemático asignar un nuevo valor a un parámetro de método?
obtener int de un jtextfield (8)
Eclipse tiene una opción para advertir sobre la asignación a un parámetro del método (dentro del método), como en:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
Normalmente trato de activar (y prestar atención) a casi todas las advertencias del compilador disponibles, pero en este caso no estoy realmente seguro de que valga la pena.
Veo casos legítimos para cambiar un parámetro en un método (por ejemplo: Permitir que un parámetro esté "sin establecer" (por ejemplo, nulo) y sustituir automáticamente un valor predeterminado), pero hay algunas situaciones en las que podría causar problemas, excepto que podría ser un poco confuso para reasignar un parámetro en el medio del método.
¿Usas tales advertencias? ¿Por qué por qué no?
Nota:
Evitar esta advertencia es, por supuesto, equivalente a hacer que el parámetro del método sea final
(solo entonces es un error del compilador :-)). Entonces, esta pregunta ¿Por qué debería usar la palabra clave "final" en un parámetro de método en Java? podría estar relacionado.
A veces lo uso en situaciones como estas:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
para evitar introducir una variable i en el bucle for. Por lo general, solo uso este tipo de ''trucos'' en funciones muy cortas.
Personalmente me disgustan mucho "corregir" los parámetros dentro de una función de esta manera. Prefiero atraparlos por aseveraciones y asegurarme de que el contrato sea correcto.
Asignar un parámetro de método no es algo que la mayoría de la gente espera que ocurra en la mayoría de los métodos. Ya que leemos el código con el supuesto de que los valores de los parámetros son fijos, una asignación generalmente se considera una mala práctica, aunque solo sea por convención y el principio de menos asombro .
Siempre hay alternativas para asignar parámetros de método: por lo general, una copia temporal local está bien. Pero en general, si encuentra que necesita controlar la lógica de su función a través de la reasignación de parámetros, podría beneficiarse de la refactorización en métodos más pequeños.
Debes escribir código sin efectos secundarios: cada método debe ser una función que no cambie. De lo contrario es un comando y puede ser peligroso.
Vea las definiciones de command y function en el sitio web de DDD:
Función : Una operación que calcula y devuelve un resultado sin efectos secundarios observables.
Comando : una operación que efectúa algún cambio en el sistema (por ejemplo, configurando una variable). Una operación que intencionalmente crea un efecto secundario.
Diferentes advertencias del compilador pueden ser apropiadas para diferentes situaciones. Claro, algunos son aplicables a la mayoría o a todas las situaciones, pero esto no parece ser una de ellas.
Pensaría en esta advertencia en particular como el compilador que le brinda la opción de recibir una advertencia sobre la reasignación de un parámetro del método cuando lo necesite, en lugar de una regla de que los parámetros del método no deben ser reasignados. Tu ejemplo constituye un caso perfectamente válido para ello.
La parte confusa es la razón de la advertencia. Si reasigna a un parámetro un nuevo valor en el método (probablemente condicional), entonces no está claro qué es. Es por eso que se ve como un buen estilo, para dejar los parámetros de método sin cambios.
La reasignación a la variable de parámetro del método suele ser un error si el parámetro es un tipo de referencia.
Considere el siguiente código:
MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);
// what''s the value of myObject.Foo here?
public void doFoo(MyObject myFoo){
myFoo = new MyObject("Bar");
}
Mucha gente esperará que después de la llamada a doFoo, myObject.Foo sea igual a "Barra". Por supuesto, no lo hará, ya que Java no se pasa por referencia , sino por valor de referencia , es decir, se pasa una copia de la referencia al método. La reasignación a esa copia solo tiene un efecto en el ámbito local, y no en el sitio de la llamada. Este es uno de los conceptos más comúnmente mal entendidos.
Normalmente no necesito asignar nuevos valores a los parámetros del método.
En cuanto a las mejores prácticas, la advertencia también evita confusiones cuando se enfrenta a un código como:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}
Para mí, siempre que lo hagas temprano y claramente, está bien. Como usted dice, hacerlo por debajo de cuatro condicionales a mitad de camino en una función de 30 líneas no es lo ideal.
Obviamente, también debe tener cuidado al hacer esto con las referencias de objetos, ya que los métodos de llamada en el objeto que se le proporcionó pueden cambiar su estado y comunicar la información a la persona que llama, pero, por supuesto, si ha sustituido en su propio marcador de posición, esa información no se comunica
La otra cara es que declarar una nueva variable y asignar el argumento (o un valor predeterminado si el argumento requiere un incumplimiento) puede ser más claro y casi seguro que no será menos eficiente: cualquier compilador decente (ya sea el compilador principal o un JIT). ) lo optimizará cuando sea posible.