¿Cuál es el estilo aceptado para usar la palabra clave `this` en Java?

37

Vengo de lenguajes como Python o Javascript (y otros que están menos orientados a objetos) y estoy tratando de mejorar mi conocimiento práctico de Java, que solo conozco de manera superficial.

¿Se considera una mala práctica anteponer siempre thisa los atributos de la instancia actual? Me parece más natural escribir

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

que

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

ya que me ayuda a distinguir los atributos de instancia de las variables locales.

Por supuesto, en un lenguaje como Javascript tiene más sentido usarlo siempre this, ya que uno puede tener más funciones de anidamiento, por lo tanto, las variables locales provienen de ámbitos más grandes. En Java, por lo que entiendo, no es posible anidar como este (excepto para las clases internas), por lo que probablemente no sea un gran problema.

En cualquier caso, preferiría usar this. ¿Se sentiría raro y no idiomático?

Andrea
fuente
Utilizamos una herramienta para stadardise que en nuestra empresa. La herramienta reescribe el código con nuestro sin esto dependiendo de la política de la empresa. Así que todos codifican cómo les gusta y el código se formatea de la manera correcta en el momento de la confirmación.
deadalnix
2
"dado que uno puede tener más funciones de anidamiento, de ahí que las variables locales provengan de ámbitos más grandes". Además, el hecho de que "esto" no es realmente uno de los lugares de donde puede venir una variable no calificada en una función en JS.
Random832
2
Prefijo todas las variables de instancia con guión bajo para poder distinguir fácilmente las variables locales y de instancia sin usar this.
WuHoUnited
44
En C # StyleCop quiere que lo pongas this.al referirte a variables miembro, métodos, etc. Me gusta, estoy de acuerdo con esta regla. Creo que es mejor que nombrar algo con un guión bajo al principio. Seguiría la misma regla si estuviera codificando en Java.
Trabajo

Respuestas:

40

En la mayoría de los IDEs, simplemente puede pasar el mouse sobre la variable si quiere saber. Además, realmente, si está trabajando en un método de instancia, realmente debería conocer todas las variables involucradas. Si tienes demasiados, o sus nombres chocan, entonces necesitas refactorizar.

Es realmente bastante redundante.

DeadMG
fuente
77
Además: un IDE sano debería hacer que los campos y las variables / parámetros locales sean visualmente distintos. Por ejemplo, en Eclipse (por defecto) los campos son azules, mientras que las variables locales son negras.
Joachim Sauer
1
@Joachim Buen punto, Eclipse puede incluso colorear los parámetros y las variables locales de manera diferente si el usuario lo desea (sin embargo, esto no es por defecto).
Eric-Karl
3
Aunque estoy de acuerdo, cuando encuentro el código de otros desarrolladores (y aunque no estoy familiarizado a primera vista), encuentro this.mucho más útil. Esto probablemente también se deba a que no tengo un IDE que codifique con colores las variables locales / objeto de manera diferente.
Brad Christie
3
+1 para (parafrasear) "refactorizar si necesita usar esto para deducir que es un miembro". Justo lo que quería señalar.
Yam Marcovic
No creo que sea más difícil de leer y, a cambio, el código sigue siendo legible en editores que tienen un resaltado de sintaxis menos sofisticado que no distingue entre campos y locales. Siempre he tenido la opinión de que debes esforzarte por que tu código sea fácilmente legible en el editor de texto más básico, y si no es así, debería haber una buena razón para ello.
Kevin
26

Yo prefiero usar this. Facilita la lectura del código en varios editores que colorean las variables locales y de instancia de la misma manera. También facilita la lectura del código en una página impresa durante una revisión del código. También es un recordatorio bastante fuerte en cuanto al alcance de la variable para otros desarrolladores.

Sin embargo, hay argumentos en contra de esto. En los IDE modernos, puede averiguar el alcance de una variable al pasar el mouse sobre ella o verla en una estructura similar a un árbol. También puede cambiar el color y / o la fuente de las variables dependiendo de su alcance (incluso de tal manera que, cuando se imprime, sea evidente cuál es el alcance de la variable).

Creo que la última oración de ChrisF es acertada : sea consistente en su uso.

Thomas Owens
fuente
77
"También es un recordatorio bastante fuerte en cuanto al alcance de la variable para otros desarrolladores". - la razón por la que suelo usar y me gusta ver this.en el código. Tarda medio segundo en escribir y puede ahorrar largos minutos cuando tiene que averiguar si el tipo antes de usted realmente tenía la intención de usar la propiedad pascal-case en lugar del camel-case local cuando hizo ese estallido de cambios de último minuto hace 20 revisiones.
scrwtp
18

Un lugar en el que siempre uso 'this' es setters y / o constructores:

public void setFoo(String foo) {
    this.foo = foo;
}

Aparte de eso, no creo que sea necesario agregarlo. Al leer el cuerpo de un método, los parámetros y los locales están ahí, y son bastante fáciles de seguir (incluso sin la ayuda del IDE). También los locales y los campos tienden a ser de diferente naturaleza (estado del objeto versus almacenamiento transitorio o parámetro)

Si existe alguna confusión sobre qué es una variable y qué es un campo, probablemente significa que un método tiene demasiadas variables / parámetros, es demasiado largo y demasiado complejo, y debe simplificarse.

Si elige usar 'esto' para etiquetar campos, recomendaría asegurarse de que la convención siempre se siga estrictamente; sería realmente fácil comenzar asumiendo que no 'esto' significa que es un local y romper cosas según la suposición.

editar: También termino usando esto en iguales, clon o cualquier cosa que tenga un parámetro 'ese' del mismo tipo de objeto:

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}
ptyx
fuente
8

Es discutible

Tomando C # como analogía, ya que tiene una sintaxis y una estructura muy similares a Java, encontramos que C # StyleCop tiene una regla predeterminada que insiste en agregar this, pero ReSharper tiene una regla predeterminada que dice que thises redundante (que es) y puede ser remoto.

Entonces, si está usando una herramienta, las agregará, pero si usa otra, las eliminará. Si está utilizando ambas herramientas, deberá elegir y deshabilitar una de las reglas.

Sin embargo, lo que las reglas significan es que usted es consistente en su uso, lo cual es probablemente lo más importante.

ChrisF
fuente
8

¿Se considera una mala práctica siempre anteponer esto a los atributos de la instancia actual?

Sí, por algunos, no, por otros.

Me gusta y uso thispalabras clave en mis proyectos en Java y C #. Se puede argumentar que IDE siempre resaltará los parámetros y campos por diferentes colores, sin embargo, no siempre trabajamos en IDE: tenemos que hacer muchas fusiones / diferencias / algunos cambios rápidos en un bloc de notas / verificar algunos fragmentos de código en el correo electrónico . Es mucho más fácil para mí detectar desde el primer vistazo dónde se cambia el estado de la instancia, por ejemplo, para revisar algunos posibles problemas de concurrencia.

Andrey Taptunov
fuente
7

Creo que si necesita usar esto, tiene un método que es demasiado largo, o una clase que está tratando de hacer demasiado, o ambos.

Los métodos nunca deben tener más de unas pocas líneas de código, use una o dos variables locales, determinando qué es lo que se vuelve fácil; incluso con solo el contexto de 3 líneas de la mayoría de las herramientas diff. Si sus métodos son demasiado largos y sus clases tienen demasiadas responsabilidades (a menudo significan demasiados campos), la solución es dividirlos en su lugar.

Creo que "esto" solo abarrota el código. Especialmente con IDEs modernos que colorearán los parámetros locales / variables locales / campos de manera diferente.

Eric-Karl
fuente
5

Creo que respondiste tu propia pregunta con esto:

Me parece más natural escribir

... this.foo ...

que

... foo ...

ya que me ayuda a distinguir los atributos de instancia de las variables locales.

Si se siente más cómodo usando this.mientras mejora su conocimiento de trabajo con Java, entonces, por supuesto, use la cosa ( creo que es, de alguna manera, el familiar Python con el que se está relacionando ).

La cuestión es que, aunque las personas darán argumentos sólidos / pertinentes sobre usar o no usar this., todavía suena como un debate, ejemplo dado:

  • aclara el propósito de las variables en comparación con el que debería reescribir el código si no está claro cuál es cada variable;
  • this.es redundante si pasa todo el día en el IDE vs. Realizo revisiones de código y hago diferencias en diferentes versiones usando un comparador sin resaltado de sintaxis;
  • no escribir this.me gana importantes milisegundos de productividad vs. me pagan con la tecla presionada y agregar this.es como un aumento de sueldo: D;
  • etcétera etcétera

Pero la conclusión es que, al final del día, aún se resume a las preferencias personales y al entorno laboral .


fuente
5

Normalmente agregar esto es innecesario. No creo que sea una mala práctica per se, pero el uso excesivo de esto probablemente se consideraría inusual en la mayoría de las bases de código Java que he visto.

Sin embargo, me parece valioso en un par de situaciones específicas:

Anulación de parámetros locales : a veces es necesario especificar que desea utilizar una variable de instancia en lugar de un parámetro / variable local del mismo nombre. Esto es bastante común en los constructores, donde desea que el nombre del parámetro coincida con el nombre interno de la variable de instancia que se usa para inicializar, por ejemplo

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

Al manejar otras instancias de la misma clase , creo que hace que el código sea más claro y más comprensible para ser explícito a qué instancia de la clase se refiere, por ejemplo

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
mikera
fuente