Erros Checked vs Unchecked
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 61 de 87.
Você viu que a hierarquia de exceções do Java se divide em diferentes ramificações. A principal distinção que você precisa entender é entre exceções verificadas e não verificadas. Isso afeta como você deve tratá-las no seu código.
Exceções verificadas são exceções que o compilador obriga você a tratar. Elas estendem Exception diretamente (não por meio de RuntimeException). Você deve capturá-las ou declará-las com throws:
// Deve tratar IOException - é checked
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // Pode lançar IOException
}
// Ou capture-a
public void readFileSafe(String path) {
try {
FileReader reader = new FileReader(path);
} catch (IOException e) {
System.out.println("File error: " + e.getMessage());
}
}exceções não verificadas estendem RuntimeException. O compilador não exige que você as trate. Elas normalmente indicam erros de programação, como referências nulas ou acesso inválido a arrays:
// Nenhuma declaração throws necessária
public int divide(int a, int b) {
return a / b; // Pode lançar ArithmeticException (não verificada)
}
String name = null;
name.length(); // NullPointerException (não verificada)Ao criar exceções personalizadas, escolha a classe pai com base em como você deseja que os chamadores as tratem. Use exceções verificadas para condições recuperáveis que o chamador deve antecipar. Use exceções não verificadas para erros de programação que não deveriam ocorrer em um código correto.
Desafio
FácilVamos criar um sistema de verificação de idade que demonstra a principal diferença entre exceções verificadas e não verificadas! Você criará exceções personalizadas dos dois tipos e verá como o compilador as trata de maneira diferente.
Você organizará seu código em quatro arquivos:
InvalidAgeException.java: Crie uma exceção verificada para falhas na validação da idade. Essa exceção deve estenderExceptiondiretamente, o que significa que os chamadores serão obrigados a tratá-la. Inclua um construtor que aceite uma mensagem e a passe para a classe pai.NegativeAgeException.java: Crie uma exceção não verificada para quando alguém fornecer uma idade negativa (um erro de programação que não deveria ocorrer com uma entrada correta). Ela deve estenderRuntimeException. Inclua um construtor que aceite e passe uma mensagem para a classe pai.AgeVerifier.java: Crie uma classe que valide idades usando os dois tipos de exceção. Inclua dois métodos estáticos:verifyAge(int age)- Este método deve lançarNegativeAgeException(não verificada) com a mensagem"Age cannot be negative: [age]"se a idade for menor que 0. Se a idade for menor que 18, lanceInvalidAgeException(verificada) com a mensagem"Must be 18 or older: [age]". Caso contrário, imprimaAge [age] verified successfully. Como este método lança uma exceção verificada, você deve declará-lo comthrows InvalidAgeException.verifyAgeUncheckedOnly(int age)- Este método usa apenas exceções não verificadas. Se a idade for negativa, lanceNegativeAgeExceptioncom o mesmo formato de mensagem. Se a idade for menor que 18, lance umaIllegalArgumentExceptioncom a mensagem"Too young: [age]". Caso contrário, imprimaAge [age] verified (unchecked method). Observe que este método não precisa de uma declaraçãothrows!Main.java: Reúna seu sistema de verificação! Você receberá uma entrada: uma idade (inteiro).Primeiro, imprima
=== Checked Exception Method ===e chameverifyAgecom a idade de entrada. Como ele lança uma exceção verificada, você deve envolvê-lo em um try-catch. CaptureInvalidAgeExceptione imprimaChecked exception caught: [message]. Capture tambémNegativeAgeExceptione imprimaUnchecked exception caught: [message].Em seguida, imprima uma linha em branco e
=== Unchecked Exception Method ===. ChameverifyAgeUncheckedOnlycom a mesma idade. Embora esse método possa lançar exceções, você não é obrigado a capturá-las. No entanto, envolva-o em um try-catch mesmo assim para tratar os erros de maneira adequada. CaptureNegativeAgeExceptione imprimaRuntime exception caught: [message]. CaptureIllegalArgumentExceptione imprimaIllegal argument caught: [message].
Você receberá uma entrada: um inteiro que representa a idade a ser verificada.
Observe a principal diferença: o método com a exceção verificada exige uma declaração throws e obriga os chamadores a tratá-la, enquanto o método não verificado é compilado normalmente sem nenhum tratamento de exceção. Essa é a distinção fundamental entre exceções verificadas e não verificadas em Java!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
// TODO: Test the checked exception method
// Print: "=== Checked Exception Method ==="
// Chame AgeVerifier.verifyAge(age) em um try-catch
// - Catch InvalidAgeException: print "Checked exception caught: [message]"
// - Catch NegativeAgeException: print "Unchecked exception caught: [message]"
// TODO: Print a blank line, then "=== Unchecked Exception Method ==="
// Chame AgeVerifier.verifyAgeUncheckedOnly(age) em um try-catch
// - Catch NegativeAgeException: print "Runtime exception caught: [message]"
// - Catch IllegalArgumentException: print "Illegal argument caught: [message]"
}
}
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 Personalizada10Tratamento de Exceções em POO
Hierarquia de Classes de ExceçãoExceções PersonalizadasErros Checked vs UncheckedPadrão Try With ResourcesRecapitulação - Usuário Validado2Modificadores 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 IteratorPratique por conta própria: Compilador de Java online