¿Cuándo debería usar “esto” en una clase?

Sé que this refiere a un objeto actual. Pero no sé cuándo realmente necesito usarlo. Por ejemplo, ¿habrá alguna diferencia si uso x lugar de this.x en algunos de los métodos? Puede ser x se referirá a una variable que es local para el método considerado? Me refiero a la variable que se ve solo en este método.

¿Qué hay de this.method() ? ¿Puedo usarlo? Debería usarlo Si solo uso method() , ¿no se aplicará de manera predeterminada al objeto actual?

La palabra clave this se usa principalmente en tres situaciones. El primero y más común es en los métodos setter para eliminar la ambigüedad de las referencias de variables. El segundo es cuando hay una necesidad de pasar la instancia de clase actual como un argumento a un método de otro objeto. El tercero es como una forma de llamar a constructores alternativos desde dentro de un constructor.

Caso 1: Usar this para eliminar la ambigüedad de las referencias de variables. En los métodos de establecimiento de Java, comúnmente pasamos un argumento con el mismo nombre que la variable de miembro privado que estamos intentando establecer. Luego asignamos el argumento x a this.x Esto deja en claro que está asignando el valor del parámetro “nombre” a la variable de instancia “nombre”.

 public class Foo { private String name; public void setName(String name) { this.name = name; } } 

Caso 2: Usar this como un argumento pasado a otro objeto.

 public class Foo { public String useBarMethod() { Bar theBar = new Bar(); return theBar.barMethod(this); } public String getName() { return "Foo"; } } public class Bar { public void barMethod(Foo obj) { obj.getName(); } } 

Caso 3: usar this para llamar a constructores alternativos. En los comentarios, Trinithis señaló correctamente otro uso común de this . Cuando tiene múltiples constructores para una sola clase, puede usar this(arg0, arg1, ...) para llamar a otro constructor de su elección, siempre que lo haga en la primera línea de su constructor.

 class Foo { public Foo() { this("Some default value for bar"); //optional other lines } public Foo(String bar) { // Do something with bar } } 

También he visto this utilizado para enfatizar el hecho de que se hace referencia a una variable de instancia (sin la necesidad de desambiguación), pero ese es un caso raro en mi opinión.

El segundo uso importante de this (además de ocultar con una variable local como ya dicen muchas respuestas) es cuando se accede a una instancia externa desde una clase anidada no estática:

 public class Outer { protected int a; public class Inner { protected int a; public int foo(){ return Outer.this.a; } public Outer getOuter(){ return Outer.this; } } } 

Solo necesita usar this , y la mayoría de la gente solo lo usa, cuando hay una variable local superpuesta con el mismo nombre. (Métodos Setter, por ejemplo)

Por supuesto, otra buena razón para usar this es que hace que intellisense aparezca en IDEs 🙂

La única necesidad de usar this. calificador es cuando otra variable dentro del scope actual comparte el mismo nombre y desea hacer referencia al miembro de la instancia (como William describe). Aparte de eso, no hay diferencia en el comportamiento entre x y this.x

“esto” también es útil cuando se llama a un constructor desde otro:

 public class MyClass { public MyClass(String foo) { this(foo, null); } public MyClass(String foo, String bar) { ... } } 

this es útil en el patrón del constructor.

 public class User { private String firstName; private String surname; public User(Builder builder){ firstName = builder.firstName; surname = builder.surname; } public String getFirstName(){ return firstName; } public String getSurname(){ return surname; } public static class Builder { private String firstName; private String surname; public Builder setFirstName(String firstName) { this.firstName = firstName; return this; } public Builder setSurname(String surname) { this.surname = surname; return this; } public User build(){ return new User(this); } } public static void main(String[] args) { User.Builder builder = new User.Builder(); User user = builder.setFirstName("John").setSurname("Doe").build(); } } 

A menos que tenga nombres de variables superpuestos, es solo cuestión de claridad cuando lee el código.

Google apareció una página en el sitio de Sun que discute esto un poco.

Tienes razón sobre la variable; this puede usarse para diferenciar una variable de método de un campo de clase.

     int privado;
     public void setX (int x) {
         this.x = x;
     }

Sin embargo, realmente odio esa convención. Dando dos variables diferentes, literalmente, nombres idénticos es una receta para los errores. Yo prefiero algo como:

     int privado;
     public void setX (int newX) {
         x = newX;
     }

Los mismos resultados, pero sin posibilidad de que haya un error por el que te refieres accidentalmente a x cuando en realidad quisiste referirte a x .

En cuanto a usarlo con un método, tienes razón sobre los efectos; obtendrá los mismos resultados con o sin él. ¿Puedes usarlo? Por supuesto. ¿Deberías usarlo? Depende de usted, pero dado que personalmente creo que es una verbosidad sin sentido que no agrega ninguna claridad (a menos que el código esté repleto de declaraciones estáticas de importación), no estoy dispuesto a usarlo yo mismo.

La respuesta de @William Brendel proporcionó tres casos de uso diferentes de una manera agradable.

Caso de uso 1:

La página oficial de documentación de Java proporciona los mismos casos de uso.

Dentro de un método de instancia o un constructor, esta es una referencia al objeto actual: el objeto cuyo método o constructor se está llamando. Puede hacer referencia a cualquier miembro del objeto actual desde un método de instancia o un constructor usando esto.

Cubre dos ejemplos:

Usando esto con un campo y usándolo con un constructor

Caso de uso 2:

Otro caso de uso que no se ha citado en esta publicación: this se puede utilizar para sincronizar el objeto actual en una aplicación de subprocesos múltiples para proteger la sección crítica de datos y métodos.

 synchronized(this){ // Do some thing. } 

Caso de uso 3:

La implementación del patrón de Constructor depende del uso de this para devolver el objeto modificado.

Consulte esta publicación

Mantener el constructor en una clase separada (interfaz fluida)

Hay muchas buenas respuestas, pero hay otra razón muy pequeña para poner this todas partes. Si ha tratado de abrir sus códigos fuente desde un editor de texto normal (por ejemplo, un bloc de notas, etc.), usar this hará que sea mucho más claro de leer.

Imagina esto:

 public class Hello { private String foo; // Some 10k lines of codes private String getStringFromSomewhere() { // .... } // More codes public class World { private String bar; // Another 10k lines of codes public void doSomething() { // More codes foo = "FOO"; // More codes String s = getStringFromSomewhere(); // More codes bar = s; } } } 

Esto es muy claro para leer con cualquier IDE moderno, pero esto será una pesadilla total para leer con un editor de texto normal.

Te costará averiguar dónde reside foo , hasta que uses la función de “buscar” del editor. Luego getStringFromSomewhere() a getStringFromSomewhere() por el mismo motivo. Por último, después de haber olvidado lo que es, esa bar = s te dará el golpe final.

Compáralo con esto:

 public void doSomething() { // More codes Hello.this.foo = "FOO"; // More codes String s = Hello.this.getStringFromSomewhere(); // More codes this.bar = s; } 
  1. Sabes que foo es una variable declarada en la clase externa Hello .
  2. Sabes que getStringFromSomewhere() es un método declarado en la clase externa también.
  3. Usted sabe que la bar pertenece a World clase World , y s es una variable local declarada en ese método.

Por supuesto, cada vez que diseñas algo, creas reglas. Entonces, al diseñar su API o proyecto, si sus reglas incluyen “si alguien abre todos estos códigos fuente con un bloc de notas, él o ella debe dispararse a sí mismo en la cabeza”, entonces está totalmente bien no hacerlo.

cuando hay dos variables, una variable de instancia y otra variable local del mismo nombre, entonces usamos esto. para referir el objeto de ejecución actual para evitar el conflicto entre los nombres.

this es una referencia al objeto actual. Se usa en el constructor para distinguir entre la variable de clase local y la actual que tienen el mismo nombre. p.ej:

 public class circle { int x; circle(int x){ this.x =x; //class variable =local variable } } 

this también se puede usar para llamar a un constructor desde otro constructor. p.ej:

 public class circle { int x; circle() { this(1); } circle(int x) { this.x = x; } } 

Las siguientes son las formas de usar la palabra clave ‘this’ en java:

  1. Usar this palabra clave para referir las variables de instancia de clase actuales
  2. Usando this() para invocar el constructor de la clase actual
  3. Usar this palabra clave para devolver la instancia de la clase actual
  4. Usar this palabra clave como parámetro de método

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

¿Habrá alguna diferencia si uso “x” en lugar de “this.x” en algunos de los métodos?

Usualmente no. Pero a veces hace la diferencia:

  class A { private int i; public A(int i) { this.i = i; // this.i can be used to disambiguate the i being referred to } } 

Si solo uso “method ()”, ¿no se aplicará de manera predeterminada al objeto actual?

Sí. Pero si es necesario, this.method() aclara que la llamada es hecha por este objeto.

this no afecta el código resultante; es el operador del tiempo de comstackción y el código generado con o sin él será el mismo. Cuando tienes que usarlo, depende del contexto. Por ejemplo, tiene que usarlo, como dijo, cuando tiene una variable local que sombrea la variable de clase y desea hacer referencia a la variable de clase y no a la local.

editar: por “el código resultante será el mismo”, quiero decir, por supuesto, cuando alguna variable en el ámbito local no oculta el que pertenece a la clase. Así

 class POJO { protected int i; public void modify() { i = 9; } public void thisModify() { this.i = 9; } } 

El código resultante de ambos métodos será el mismo. La diferencia será si algún método declara la variable local con el mismo nombre

  public void m() { int i; i = 9; // i refers to variable in method's scope this.i = 9; // i refers to class variable } 

Con respecto a las preguntas de William Brendel y dbconfessions , con respecto al caso 2 . Aquí hay un ejemplo:

 public class Window { private Window parent; public Window (Window parent) { this.parent = parent; } public void addSubWindow() { Window child = new Window(this); list.add(child); } public void printInfo() { if (parent == null) { System.out.println("root"); } else { System.out.println("child"); } } } 

He visto esto usado, al construir relaciones entre padres e hijos con objetos. Sin embargo, tenga en cuenta que se simplifica en aras de la brevedad.

Para asegurarse de que se usan los miembros del objeto actual. En los casos en que la seguridad de subprocesos es una preocupación, algunas aplicaciones pueden cambiar los valores de miembro de objetos incorrectos, por lo que esto se debe aplicar al miembro para que se use el valor de miembro de objeto correcto.

Si su objeto no tiene que ver con la seguridad de subprocesos, entonces no hay ninguna razón para especificar qué valor de miembro de objeto se utiliza.