A Palavra-chave final
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 13 de 87.
A palavra-chave final em Java impede a modificação. Ela pode ser aplicada a variáveis, métodos e classes, cada um com um efeito diferente.
Quando aplicado a uma variável, final torna-a uma constante - uma vez atribuída, seu valor não pode mudar:
public class Circle {
private final double PI = 3.14159;
private final double radius;
public Circle(double radius) {
this.radius = radius; // Pode ser atribuído uma vez no construtor
}
public void setRadius(double r) {
// this.radius = r; // Erro! Não é possível reatribuir uma variável final
}
}Uma variável final deve ser inicializada na declaração ou no construtor. Depois disso, qualquer tentativa de reatribuí-la causará um erro de compilação.
Para tipos de referência, final significa que a referência não pode apontar para um objeto diferente, mas o conteúdo do objeto ainda pode mudar:
private final StringBuilder name = new StringBuilder("John");
// name = new StringBuilder("Jane"); // Erro! Não é possível reatribuir
name.append(" Doe"); // OK! O conteúdo do objeto pode mudarO uso de final com campos comunica a intenção claramente - informa a outros desenvolvedores que este valor nunca deve mudar após a inicialização. Isso é especialmente útil para valores de configuração, IDs ou quaisquer dados que devam permanecer constantes durante todo o tempo de vida de um objeto.
Desafio
FácilVamos construir um sistema de registro de Student que utiliza a palavra-chave final para proteger dados que nunca devem mudar após um estudante ser registrado.
Você criará dois arquivos para organizar seu código:
Student.java: Crie uma classe Student onde certas informações são permanentemente bloqueadas uma vez definidas:- Um campo
finalstudentId(String) - atribuído na criação e que nunca pode mudar - Um campo
finalenrollmentYear(int) - o ano em que o estudante se matriculou, também permanente - Um campo privado regular
name(String) - pode ser atualizado se o estudante mudar de nome - Um construtor que recebe todos os três valores e inicializa os campos
- Um getter
getStudentId()para o ID do estudante - Um getter
getEnrollmentYear()para o ano de matrícula - Um getter
getName()e um settersetName()para o nome - Um método
getInfo()que retorna:"ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
- Um campo
Main.java: Crie um objeto Student, depois atualize seu nome e exiba suas informações. Você receberá quatro entradas: o ID do estudante, o nome inicial, o ano de matrícula e um novo nome para atualização. Imprima duas linhas:- As informações do estudante antes da mudança de nome
- As informações do estudante após a mudança de nome
Você receberá quatro entradas em ordem: studentId (String), name (String), enrollmentYear (int) e newName (String).
Observe como os campos final protegem o ID e o ano de matrícula do estudante - estes são registros permanentes que não devem mudar, enquanto o nome pode ser atualizado através de seu setter.
Folha de consulta
A palavra-chave final impede a modificação em Java. Ela pode ser aplicada a variáveis, métodos e classes.
Quando aplicada a uma variável, final a torna uma constante - uma vez atribuída, seu valor não pode ser alterado:
public class Circle {
private final double PI = 3.14159;
private final double radius;
public Circle(double radius) {
this.radius = radius; // Pode atribuir uma vez no construtor
}
public void setRadius(double r) {
// this.radius = r; // Erro! Não é possível reatribuir uma variável final
}
}Uma variável final deve ser inicializada na declaração ou no construtor. Depois disso, qualquer tentativa de reatribuí-la causará um erro de compilação.
Para tipos de referência, final significa que a referência não pode apontar para um objeto diferente, mas o conteúdo do objeto ainda pode mudar:
private final StringBuilder name = new StringBuilder("John");
// name = new StringBuilder("Jane"); // Erro! Não é possível reatribuir
name.append(" Doe"); // OK! O conteúdo do objeto pode mudarUsar final com campos comunica a intenção - indica que um valor nunca deve mudar após a inicialização, o que é útil para valores de configuração, IDs ou dados constantes.
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String studentId = scanner.nextLine();
String name = scanner.nextLine();
int enrollmentYear = scanner.nextInt();
scanner.nextLine(); // consumir nova linha
String newName = scanner.nextLine();
// TODO: Criar um objeto Student com os valores iniciais
// TODO: Imprimir as informações do estudante antes da alteração do nome
// TODO: Atualizar o nome do estudante usando o setter
// TODO: Imprimir as informações do estudante após a alteração do nome
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator