Menu
CoddyTech

La palabra clave final

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 13 de 87.

La palabra clave final en Java impide las modificaciones. Puede aplicarse a variables, métodos y clases, con un efecto diferente en cada caso.

Cuando se aplica a una variable, final la convierte en una constante: una vez asignado, su valor no puede cambiar:

public class Circle {
    private final double PI = 3.14159;
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;  // Se puede asignar una vez en el constructor
    }
    
    public void setRadius(double r) {
        // this.radius = r;  // ¡Error! No se puede reasignar una variable final
    }
}

Una variable final debe inicializarse en la declaración o en el constructor. Después, cualquier intento de reasignarle un valor provoca un error de compilación.

Para los tipos de referencia, final significa que la referencia no puede apuntar a un objeto diferente, pero el contenido del objeto sí puede cambiar:

private final StringBuilder name = new StringBuilder("John");

// name = new StringBuilder("Jane");  // ¡Error! No se puede reasignar
name.append(" Doe");  // ¡Correcto! El contenido del objeto puede cambiar

Usar final con campos comunica claramente la intención: indica a otros desarrolladores que este valor nunca debe cambiar después de la inicialización. Esto resulta especialmente útil para valores de configuración, ID o cualquier dato que deba permanecer constante durante toda la vida de un objeto.

Un método final no se puede sobrescribir en una subclase:

class Base {
    public final void greet() {
        System.out.println("Hi");
    }
}
class Child extends Base {
    // public void greet() { }  // ¡Error! greet() es final en Base
}

Una final clase no se puede extender en absoluto. String es una clase final, así que ninguna clase puede extenderla:

final class Config { }
// class MyConfig extends Config { }  // ¡Error! Config es final
challenge icon

Desafío

Fácil

Vamos a crear un sistema de registro de Student que use la palabra clave final para proteger los datos que nunca deberían cambiar después de registrar a un estudiante.

Crearás dos archivos para organizar tu código:

  • Student.java: Crea una clase Student en la que cierta información quede bloqueada permanentemente una vez establecida:
    • Un campo final studentId (String): se asigna al crear el objeto y nunca puede cambiar
    • Un campo final enrollmentYear (int): el año en que se matriculó el estudiante, también permanente
    • Un campo privado normal name (String): se puede actualizar si el estudiante cambia de nombre
    • Un constructor que recibe los tres valores e inicializa los campos
    • Un método getter getStudentId() para el ID del estudiante
    • Un método getter getEnrollmentYear() para el año de matriculación
    • Un método getter getName() y un método setter setName() para el nombre
    • Un método getInfo() que devuelve: "ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
  • Main.java: Crea un objeto Student, luego actualiza su nombre y muestra su información. Recibirás cuatro entradas: el ID del estudiante, el nombre inicial, el año de matriculación y el nuevo nombre que se establecerá. Imprime dos líneas:
    • La información del estudiante antes del cambio de nombre
    • La información del estudiante después del cambio de nombre

Recibirás cuatro entradas en este orden: studentId (String), name (String), enrollmentYear (int) y newName (String).

Observa cómo los campos final protegen el ID del estudiante y el año de matriculación: son datos permanentes que no deberían cambiar, mientras que el nombre se puede actualizar mediante su método setter.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lee las entradas
        String studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // consume el salto de línea
        String newName = scanner.nextLine();
        
        // TODO: Crea un objeto Student con los valores iniciales
        
        // TODO: Muestra la información del estudiante antes del cambio de nombre
        
        // TODO: Actualiza el nombre del estudiante usando el setter
        
        // TODO: Muestra la información del estudiante después del cambio de nombre
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online