La palabra clave this en Java

📅 Actualizado en febrero 2026 ✍️ Ángel López ⏱️ 14 min de lectura ✓ Nivel intermedio ★ ★ ★ ★ ★ (5/5)

🔑 ¿Qué es this en Java?

En Java, this es una referencia implícita que apunta siempre al objeto actual: la instancia concreta sobre la que se está ejecutando un método de instancia o un constructor. Cada vez que se crea un objeto con new, la JVM asigna un espacio en el heap y this es la forma que tiene el propio objeto de referirse a sí mismo.

Piensa en this como el pronombre «yo» de un objeto. Cuando una persona dice «yo me llamo Ana», yo hace referencia a esa persona concreta, no a cualquier otra. De forma análoga, cuando un objeto ejecuta this.nombre, se refiere a su propio atributo nombre, sin ambigüedad posible.

💡
Concepto clave: this solo existe dentro de métodos de instancia y constructores. En un método static no hay instancia, por lo que usar this provoca un error de compilación.

▶️ Primer vistazo: this en acción

Java
public class Persona {

    private String nombre;

    public Persona(String nombre) {
        // Sin this: nombre = nombre asigna el parámetro a sí mismo (bug)
        this.nombre = nombre; // Correcto: atributo ← parámetro
    }

    public void saludar() {
        System.out.println("Hola, soy " + this.nombre);
    }
}

En el ejemplo anterior, el parámetro nombre del constructor «oculta» (o shadow) al atributo nombre de la clase. Gracias a this.nombre, el compilador sabe que a la izquierda de la asignación nos referimos al atributo de la instancia.

📋 Resumen de los cinco usos de this

Uso Sintaxis Propósito
Desambiguación this.atributo Distinguir atributo de parámetro con el mismo nombre
Constructor encadenado this(args) Invocar otro constructor de la misma clase
Encadenamiento de métodos return this Devolver el objeto actual para llamadas fluidas
Pasar como argumento metodo(this) Enviar la referencia del objeto actual a otro método
Referencia en clases internas ClaseExterna.this Acceder a la instancia de la clase envolvente

🔀 Desambiguación de atributos y parámetros

El uso más habitual de this es resolver la ambigüedad (variable shadowing) que se produce cuando un parámetro de método o constructor tiene el mismo nombre que un atributo de la clase. Sin this, el compilador siempre da prioridad a la variable más local, por lo que el atributo queda «oculto».

❌ Sin this: bug silencioso

Java — Incorrecto
public class Rectangulo {

    private double ancho;
    private double alto;

    public Rectangulo(double ancho, double alto) {
        ancho = ancho; // ⚠️ Asigna el parámetro a sí mismo
        alto  = alto;  // ⚠️ El atributo sigue siendo 0.0
    }
}

✅ Con this: asignación correcta

Java — Correcto
public class Rectangulo {

    private double ancho;
    private double alto;

    public Rectangulo(double ancho, double alto) {
        this.ancho = ancho; // atributo ← parámetro
        this.alto  = alto;
    }

    public double area() {
        return this.ancho * this.alto;
    }
}
Buena práctica: Muchos equipos de desarrollo usan this siempre que acceden a un atributo, incluso cuando no hay ambigüedad. Esto mejora la legibilidad y deja claro que se trata de un campo de instancia, no de una variable local.

🔹 ¿Cuándo NO hace falta this?

Si los nombres de los parámetros son distintos a los de los atributos, Java resuelve las referencias sin ambigüedad. Sin embargo, la convención mayoritaria en Java es mantener los mismos nombres y usar this explícitamente, porque los IDEs (IntelliJ IDEA, Eclipse, VS Code) lo generan automáticamente y resulta más legible que inventar prefijos como _nombre o pNombre.

🏗️ this() en constructores: encadenamiento

Cuando una clase tiene varios constructores sobrecargados, es frecuente que compartan la misma lógica de inicialización. En lugar de duplicar ese código, Java permite invocar otro constructor de la misma clase usando this(argumentos). Esta técnica se denomina encadenamiento de constructores (constructor chaining).

Java
public class Libro {

    private String titulo;
    private String autor;
    private int paginas;

    // Constructor principal (toda la lógica aquí)
    public Libro(String titulo, String autor, int paginas) {
        this.titulo  = titulo;
        this.autor   = autor;
        this.paginas = paginas;
    }

    // Constructor con valores por defecto → delega en el principal
    public Libro(String titulo, String autor) {
        this(titulo, autor, 0); // Encadenamiento con this()
    }

    // Constructor mínimo
    public Libro(String titulo) {
        this(titulo, "Desconocido"); // Encadena con el anterior
    }
}
⚠️
Regla del compilador: this() debe ser la primera instrucción del constructor. No se puede poner código antes de ella ni combinar this() y super() en el mismo constructor.

📊 Flujo de encadenamiento

Llamada Cadena de ejecución Valores finales
new Libro("Java") Libro(String) → Libro(String, String) → Libro(String, String, int) titulo="Java", autor="Desconocido", paginas=0
new Libro("Java", "Gosling") Libro(String, String) → Libro(String, String, int) titulo="Java", autor="Gosling", paginas=0
new Libro("Java", "Gosling", 450) Libro(String, String, int) directo titulo="Java", autor="Gosling", paginas=450

El beneficio principal es el principio DRY (Don't Repeat Yourself): la validación y la asignación de atributos se escriben una sola vez en el constructor más completo y los demás delegan en él.

⛓️ return this: encadenamiento de métodos (fluent API)

Una de las aplicaciones más elegantes de this es el patrón fluent (fluent interface), donde cada método de configuración devuelve this para poder encadenar llamadas en una sola expresión. Este patrón es muy utilizado en builders, configuradores y APIs como la de Streams o StringBuilder.

Java
public class ConsultaSQL {

    private String tabla;
    private String condicion;
    private String orden;

    public ConsultaSQL from(String tabla) {
        this.tabla = tabla;
        return this; // Devuelve el objeto actual
    }

    public ConsultaSQL where(String condicion) {
        this.condicion = condicion;
        return this;
    }

    public ConsultaSQL orderBy(String orden) {
        this.orden = orden;
        return this;
    }

    public String build() {
        return "SELECT * FROM " + tabla
             + " WHERE " + condicion
             + " ORDER BY " + orden;
    }
}

// Uso encadenado (fluent):
String sql = new ConsultaSQL()
    .from("empleados")
    .where("salario > 30000")
    .orderBy("nombre ASC")
    .build();

System.out.println(sql);
// SELECT * FROM empleados WHERE salario > 30000 ORDER BY nombre ASC
💡
¿Dónde se ve este patrón? En la API estándar de Java: StringBuilder.append().append(), Stream.filter().map().collect(), y en librerías populares como Lombok (@Builder) y Mockito.

📤 Pasar this como argumento a otro método

Un objeto puede pasarse a sí mismo como parámetro a cualquier método que acepte su tipo. Esto es útil en patrones como Observer, Mediator y en registros de objetos. Es el uso original que describía el artículo antiguo: «añadir el objeto actual a una relación de publicaciones prestadas».

Java
import java.util.ArrayList;
import java.util.List;

public class Sensor {

    private String id;

    public Sensor(String id) {
        this.id = id;
    }

    public void registrarEn(CentralMonitoreo central) {
        central.agregarSensor(this); // Se pasa a sí mismo
    }

    public String getId() { return id; }
}

class CentralMonitoreo {

    private List<Sensor> sensores = new ArrayList<>();

    public void agregarSensor(Sensor sensor) {
        sensores.add(sensor);
        System.out.println("Sensor registrado: " + sensor.getId());
    }
}

Al invocar central.agregarSensor(this), el sensor se pasa a sí mismo para ser incluido en la lista de sensores monitoreados. Este patrón permite que un objeto se «auto-registre» sin que un tercero tenga que coordinar la operación.

🧩 this en clases internas y anónimas

Cuando una clase interna (inner class) necesita acceder a los miembros de su clase envolvente (outer class), this solo no basta porque dentro de la clase interna this se refiere a la instancia interna. La solución es anteponer el nombre de la clase externa seguido de .this.

Java
public class Ventana {

    private String titulo = "Mi aplicación";

    class Boton {
        private String titulo = "Aceptar";

        public void mostrarTitulos() {
            System.out.println("Botón: " + this.titulo);
            // this.titulo → "Aceptar" (clase interna)

            System.out.println("Ventana: " + Ventana.this.titulo);
            // Ventana.this.titulo → "Mi aplicación" (clase externa)
        }
    }
}
Consejo: Con las lambdas de Java 8+, this se comporta de forma diferente: dentro de una lambda, this hace referencia a la instancia de la clase que contiene la lambda, no a la propia lambda (que no es una clase). Esto evita la necesidad de usar ClaseExterna.this.

🛒 Ejemplo integrador: builder de pedidos

Este ejemplo combina los tres usos principales de this: desambiguación en constructores, encadenamiento con return this y paso como argumento. Simula un sistema de pedidos de una tienda online.

Java — Sistema de pedidos completo
import java.util.ArrayList;
import java.util.List;

public class Pedido {

    private String cliente;
    private List<String> productos;
    private double total;
    private boolean envioUrgente;

    // 1. Desambiguación con this en constructor
    public Pedido(String cliente) {
        this.cliente     = cliente;
        this.productos   = new ArrayList<>();
        this.total       = 0;
        this.envioUrgente = false;
    }

    // 2. return this → encadenamiento fluido
    public Pedido agregarProducto(String producto, double precio) {
        this.productos.add(producto);
        this.total += precio;
        return this;
    }

    public Pedido conEnvioUrgente() {
        this.envioUrgente = true;
        this.total += 5.99;
        return this;
    }

    // 3. Pasar this como argumento
    public void confirmar(SistemaPago sistema) {
        sistema.procesar(this); // El pedido se pasa a sí mismo
    }

    public String getCliente()  { return cliente; }
    public double getTotal()    { return total; }
    public boolean isUrgente() { return envioUrgente; }

    @Override
    public String toString() {
        return "Pedido de " + cliente + ": " + productos
             + " | Total: " + total + "€"
             + (envioUrgente ? " [URGENTE]" : "");
    }

    // --- Demo ---
    public static void main(String[] args) {

        SistemaPago pago = new SistemaPago();

        Pedido pedido = new Pedido("Ana García")
            .agregarProducto("Teclado mecánico", 89.99)
            .agregarProducto("Ratón ergonómico", 45.50)
            .conEnvioUrgente();

        System.out.println(pedido);
        pedido.confirmar(pago);
    }
}

class SistemaPago {
    public void procesar(Pedido pedido) {
        System.out.println("Procesando pago de "
            + pedido.getTotal() + "€ para "
            + pedido.getCliente()
            + (pedido.isUrgente() ? " (envío prioritario)" : ""));
    }
}

Salida del programa:

Salida
Pedido de Ana García: [Teclado mecánico, Ratón ergonómico] | Total: 141.48€ [URGENTE]
Procesando pago de 141.48€ para Ana García (envío prioritario)

⚖️ Diferencia entre this y super

Ambas son referencias especiales que apuntan al mismo objeto en memoria, pero acceden a niveles diferentes de la jerarquía de herencia.

Aspecto this super
Referencia a Instancia actual de la clase en curso Parte heredada del objeto (clase padre)
Acceso a miembros this.atributo / this.metodo() super.atributo / super.metodo()
Constructor this(args) → otro constructor de la misma clase super(args) → constructor de la clase padre
Restricción Solo en métodos de instancia y constructores Solo en métodos de instancia y constructores
Combinación No se puede usar this() y super() en el mismo constructor
Java
public class Animal {
    protected String nombre;

    public Animal(String nombre) {
        this.nombre = nombre;
    }

    public String describir() {
        return "Animal: " + nombre;
    }
}

public class Perro extends Animal {
    private String raza;

    public Perro(String nombre, String raza) {
        super(nombre);     // Llama al constructor de Animal
        this.raza = raza;  // Desambigua en la clase actual
    }

    @Override
    public String describir() {
        return super.describir() + ", Raza: " + this.raza;
        // super.describir() → versión de Animal
        // this.raza → atributo propio de Perro
    }
}

📏 Reglas y restricciones de this

A pesar de su sencillez aparente, this tiene reglas que el compilador hace cumplir de forma estricta:

Regla Descripción Consecuencia si se viola
No en static Los métodos estáticos no tienen instancia asociada Error de compilación: non-static variable this cannot be referenced from a static context
this() primera línea La llamada a otro constructor debe ser la primera instrucción Error de compilación: call to this must be first statement in constructor
No combinar this() y super() Solo se puede invocar uno de los dos por constructor Error de compilación
No recursión directa this() no puede llamarse a sí mismo Error de compilación: recursive constructor invocation
this es final No se puede reasignar this = otroObjeto Error de compilación: cannot assign a value to final variable this

❌ Errores frecuentes con this

Error 1: olvidar this en el constructor (shadowing)

Java — Incorrecto
public Cuenta(String titular, double saldo) {
    titular = titular; // ❌ El atributo sigue siendo null
    saldo   = saldo;   // ❌ El atributo sigue siendo 0.0
}
Java — Correcto
public Cuenta(String titular, double saldo) {
    this.titular = titular; // ✅
    this.saldo   = saldo;   // ✅
}

Error 2: usar this en un método static

Java — Error de compilación
public static void metodoEstatico() {
    System.out.println(this.nombre); // ❌ No compila
}

Error 3: poner código antes de this()

Java — Error de compilación
public Libro(String titulo) {
    System.out.println("Creando libro"); // ❌ Código antes de this()
    this(titulo, "Desconocido");
}

Error 4: confundir this con super en herencia

Java — Incorrecto
public class Gato extends Animal {
    public Gato(String nombre) {
        this(nombre); // ❌ Llama a Gato(String) → recursión infinita
        // Debería ser: super(nombre);
    }
}

✏️ Ejercicios prácticos con solución

Ejercicio 1: clase CuentaBancaria con constructores encadenados

Crea una clase CuentaBancaria con atributos titular (String), saldo (double) y moneda (String). Implementa tres constructores: uno completo (3 parámetros), uno con moneda por defecto "EUR" (2 parámetros) y uno con saldo 0 y moneda "EUR" (1 parámetro). Usa this() para encadenarlos sin duplicar lógica.

Ejercicio 2: fluent API para configurar un email

Crea una clase Email con atributos de, para, asunto y cuerpo (todos String). Implementa métodos setter que devuelvan this para permitir encadenamiento. Añade un método enviar() que imprima los datos del email. Demuestra su uso con una cadena de llamadas.

Ejercicio 3: patrón Observer con this

Crea una interfaz Observador con el método notificar(String mensaje). Crea una clase Empleado que implemente Observador con atributos nombre y departamento. Crea una clase TableroBulletins con una lista de observadores y método publicar(String). El Empleado debe auto-registrarse en el tablero usando this en el constructor.

❓ Preguntas frecuentes sobre La palabra clave this en Java

Las dudas más comunes respondidas de forma clara y directa.

this es una referencia implícita al objeto actual sobre el que se está ejecutando un método o constructor. Permite acceder a los atributos y métodos de la instancia, distinguiéndolos de parámetros locales con el mismo nombre.
No. Los métodos estáticos (static) pertenecen a la clase, no a una instancia concreta, por lo que no existe un objeto actual al que this pueda hacer referencia. Intentar usar this dentro de un método estático produce un error de compilación.
this hace referencia al objeto actual de la clase en curso, mientras que super hace referencia a la parte heredada del objeto, es decir, a los miembros de la clase padre. this() invoca otro constructor de la misma clase y super() invoca un constructor de la clase padre.
this() es una llamada explícita a otro constructor de la misma clase. Permite reutilizar la lógica de inicialización sin duplicar código. Debe aparecer siempre como la primera instrucción del constructor que la invoca.
Es obligatorio cuando un parámetro o variable local tiene el mismo nombre que un atributo de la instancia (shadowing). Sin this, el compilador asigna el valor del parámetro a sí mismo en lugar de al atributo. También es necesario para invocar otro constructor con this() y para devolver el objeto actual con return this.
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre La palabra clave this en Java? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!