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 la modificación. Se puede aplicar 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 volver a asignar una variable final
    }
}

Una variable final debe inicializarse al declararla o en el constructor. Después de eso, cualquier intento de reasignarla 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 todavía 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, identificadores o cualquier dato que deba permanecer constante durante toda la vida útil de un objeto.

Un final método 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 es 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 getter getStudentId() para el ID del estudiante
    • Un getter getEnrollmentYear() para el año de matriculación
    • Un getter getName() y un 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 un nombre nuevo para actualizarlo. 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 setter.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer las entradas
        String studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // consumir el salto de línea
        String newName = scanner.nextLine();
        
        // TODO: Crear un objeto Student con los valores iniciales
        
        // TODO: Imprimir la información del estudiante antes del cambio de nombre
        
        // TODO: Actualizar el nombre del estudiante usando el setter
        
        // TODO: Imprimir 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