Pregunta ¿Es problemático asignar un nuevo valor a un parámetro de método?


Eclipse tiene la opción de advertir sobre la asignación al parámetro de un 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 de compilación disponibles, pero en este caso no estoy seguro si vale la pena.

Veo casos legítimos para cambiar un parámetro en un método (por ejemplo: Permitir que un parámetro sea "desarmado" (por ejemplo, nulo) y sustituir automáticamente un valor predeterminado), pero pocas situaciones donde podría causar problemas, excepto que podría ser un poco confundir 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 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.


19
2018-02-09 13:36


origen


Respuestas:


Para mí, siempre y cuando lo hagas temprano y con claridad, está bien. Como dices, hacerlo enterrado profundamente en cuatro condicionales a la mitad de una función de 30 líneas es menos que ideal.

Obviamente también debe tener cuidado al hacer esto con referencias a objetos, ya que los métodos de llamada en el objeto que se le asignaron pueden cambiar su estado y comunicar la información a la persona que llama, pero, por supuesto, si ha insertado su marcador de posición, esa información no está comunicado.

La otra cara de la moneda es que declarar una nueva variable y asignar el argumento (o un argumento predeterminado si el argumento es predeterminado) puede ser más claro, y seguramente no será menos eficiente: cualquier compilador decente (ya sea el compilador primario o un JIT ) lo optimizará cuando sea posible.


9
2018-02-09 13:39



La parte confusa es la razón de la advertencia. Si reasigna un parámetro a un nuevo valor en el método (probablemente condicional), entonces no está claro, qué es a. Es por eso que se ve como un buen estilo, para dejar los parámetros del método sin cambios.


13
2018-02-09 13:42



Asignar un parámetro de método no es algo que la mayoría de las personas esperar suceder en la mayoría de los métodos. Como leemos el código asumiendo que los valores de los parámetros son fijos, una asignación generalmente se considera una práctica deficiente, aunque solo sea por convención y por principio de menor asombro.

Siempre hay alternativas a la asignación de 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 mediante la reasignación de parámetros, podría beneficiarse de la refactorización en métodos más pequeños.


8
2018-02-09 13:43



La reasignación a la variable de parámetro de método suele ser un error si el parámetro es un tipo de referencia.

Considera 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 "Bar". Por supuesto, no lo hará, porque Java no es pasar por referencia, pero pasar 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 llamada. Este es uno de los conceptos más comúnmente incomprendidos.


7
2018-02-09 13:49



Las diferentes advertencias del compilador pueden ser apropiadas para diferentes situaciones. Claro, algunos son aplicables a la mayoría o a todas las situaciones, pero este no parece ser uno de ellos.

Me gustaría pensar en esta advertencia en particular, ya que el compilador le da la opción de ser advertido sobre la reasignación de un parámetro de método cuando lo necesite, en lugar de una regla de que los parámetros del método no deberían reasignarse. Su ejemplo constituye un caso perfectamente válido para ello.


1
2018-02-09 13:40



A veces lo uso en situaciones como estas:

void countdown(int n)
{
   for (; n > 0; n--) {
      // do something
   }
}

para evitar introducir una variable yo en el bucle for. Normalmente, solo uso este tipo de 'trucos' en funciones muy breves.

Personalmente, me disgusta mucho 'corregir' los parámetros dentro de una función de esta manera. Prefiero atraparlos mediante aseveraciones y asegurarme de que el contrato sea el correcto.


0
2018-02-09 13:44



Por lo general, no es necesario 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 enfrentan códigos como:

       public void foo() {
           int a = 1;
           bar(a);
           System.out.println(a);
       }

       public void bar(int a) {
           a++;
       }

0
2018-02-09 13:46



Debes escribir el código sin ningún efecto secundario: cada método debe ser función eso no cambia De lo contrario, es un mando y puede ser peligroso.

Ver definiciones para mando y función en el sitio web de DDD:

Función :   Una operación que calcula y devuelve un resultado sin efectos secundarios observables.

Mando : Una operación que produce algún cambio en el sistema (para   ejemplo, establecer una variable). Un   operación que crea intencionalmente un   efecto secundario.


0
2018-02-09 13:55