Login
Login

Capturando e tratando exceções em Java

Capturando e tratando exceções em Java
Hostman Team
Technical writer
Linguagem de programação Java
24.10.2025
Reading time: 13 min

A linguagem de programação Java, como muitas outras, possui ferramentas integradas para lidar com erros, ou seja, situações excepcionais (exceções) nas quais uma falha do programa é tratada por um código especial separado do algoritmo principal.

Graças às exceções, o desenvolvedor pode antecipar pontos fracos no código e evitar erros fatais durante a execução.

Portanto, o tratamento de exceções em Java é uma boa prática que melhora a confiabilidade geral do código.

O objetivo deste artigo é explorar os princípios de captura e tratamento de exceções, bem como revisar as estruturas sintáticas da linguagem destinadas a esse propósito.

Todos os exemplos deste guia foram executados no Ubuntu 22.04, instalado em um servidor em nuvem da Hostman.

Instalar o OpenJDK e executar uma aplicação

Os exemplos apresentados neste guia foram executados utilizando o OpenJDK. A instalação é simples.

Primeiro, atualize a lista de repositórios disponíveis:

sudo apt update

Em seguida, solicite a lista de versões do OpenJDK disponíveis para download:

sudo apt search openjdk | grep -E 'openjdk-.*-jdk/'

Você verá uma pequena lista no terminal:

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
openjdk-11-jdk/jammy-updates,jammy-security 11.0.25+9-1ubuntu1~22.04 amd64  
openjdk-17-jdk/jammy-updates,jammy-security 17.0.13+11-2ubuntu1~22.04 amd64  
openjdk-18-jdk/jammy-updates,jammy-security 18.0.2+9-2~22.04 amd64  
openjdk-19-jdk/jammy-updates,jammy-security 19.0.2+7-0ubuntu3~22.04 amd64  
openjdk-21-jdk/jammy-updates,jammy-security,now 21.0.5+11-1ubuntu1~22.04 amd64 [installed]  
openjdk-8-jdk/jammy-updates,jammy-security 8u432-ga~us1-0ubuntu2~22.04 amd64  

Usaremos a versão openjdk-21-jdk:

sudo apt install openjdk-21-jdk

Depois, você pode verificar se o Java foi instalado corretamente consultando sua versão:

java --version

A saída do terminal será semelhante a esta:

openjdk 21.0.5 2024-10-15  
OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu122.04)  
OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu122.04, mixed mode, sharing)

Como mostrado, a versão exata do OpenJDK é 21.0.5.

Todos os exemplos deste guia devem ser salvos em um arquivo separado com a extensão .java:

nano App.java

Em seguida, preencha o arquivo criado com um código de exemplo como este:

class App {
	public static void main(String[] args) {
		System.out.println("This text is printed to the console");
	}
}

Observe que o nome da classe deve coincidir com o nome do arquivo.

Depois, compile o arquivo:

javac App.java

E execute-o:

java App

O terminal exibirá o seguinte:

This text is printed to the console

Tipos de exceções em Java

Todas as exceções em Java têm um tipo específico associado ao motivo pelo qual a exceção ocorreu — o tipo particular de falha do programa.

Existem dois tipos fundamentais de exceções:

  • Checked Exceptions — ocorrem em tempo de compilação. Se não forem tratadas, o programa não será compilado.
  • Unchecked Exceptions — ocorrem em tempo de execução. Se não forem tratadas, o programa será encerrado.

O tipo Error é considerado uma exceção apenas condicionalmente — é um erro completo que inevitavelmente causa a falha do programa.

As exceções que podem ser tratadas por código personalizado e permitem que o programa continue a execução são Checked Exceptions e Unchecked Exceptions.

Assim, erros e exceções em Java são entidades diferentes. No entanto, tanto Errors quanto Exceptions (Checked e Unchecked) são tipos com subtipos adicionais que esclarecem o motivo da falha.

Checked Exceptions

Aqui está um exemplo de código que gera uma exceção em tempo de compilação:

import java.io.File;
import java.util.Scanner;

public class App {
	public static void main(String[] args) {
		File someFile = new File("someFile.txt"); // cria uma referência para o arquivo
        Scanner scanner = new Scanner(someFile);  // analisa o conteúdo do arquivo
    }
}

A compilação será interrompida e você verá o seguinte erro no terminal:

App.java:7: error: unreported exception FileNotFoundException; must be caught or declared to be thrown  
                Scanner scanner = new Scanner(someFile);  
                                  ^  
1 error

Se você capturar e tratar essa exceção, o código será compilado e executado corretamente.

Unchecked Exceptions

Aqui está outro exemplo de código que gera uma exceção apenas em tempo de execução:

class App {
	public static void main(String[] args) {
		int[] someArray = {1, 2, 3, 4, 5}; // cria um array com 5 elementos
        System.out.println(someArray[10]); // tenta acessar um elemento inexistente
    }
}

Nenhuma exceção ocorrerá durante a compilação, mas após executar o código compilado, você verá este erro no terminal:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5  
	at app.main(app.java:4)

Isso significa que essa exceção pode ser tratada por código definido pelo usuário, permitindo que o programa continue a execução.

Error

Por fim, aqui está um exemplo de código que causa um erro em tempo de execução:

public class App {
	static int i = 0;

	public static int showSomething(int x) {
		i = i + 2;
		return i + showSomething(i + 2);
	}

	public static void main(String[] args) {
		App.showSomething(i); // gera um erro de stack overflow
    }
}

A compilação será bem-sucedida, mas durante a execução o terminal exibirá um StackOverflowError:

Exception in thread "main" java.lang.StackOverflowError  
	at java.base/java.io.BufferedOutputStream.implWrite(BufferedOutputStream.java:220)  
	at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:200)  
	at java.base/java.io.PrintStream.implWrite(PrintStream.java:643)

Nesse caso, o erro não pode ser tratado; ele só pode ser corrigido no código.

Classes de exceção em Java

Internamente, todas as exceções (e erros) em Java são representadas como um conjunto de classes, algumas das quais herdam de outras.

A classe base para todos os erros e exceções é Throwable. Duas outras classes herdam dela — Error e Exception, que servem como classes base para uma ampla gama de subclasses associadas a tipos específicos de exceção.

A classe Error descreve erros do tipo sistema, conforme mencionado anteriormente, enquanto a classe Exception descreve exceções verificadas.

Além disso, a classe RuntimeException herda de Exception e descreve exceções não verificadas.

Uma hierarquia simplificada de classes de exceção em Java pode ser representada da seguinte forma:

  • Throwable

    • Error

    • Exception

      • CloneNotSupportedException

      • InterruptedException

      • ReflectiveOperationException

        • ClassNotFoundException

        • IllegalAccessException

        • InstantiationException

        • NoSuchFieldException

        • NoSuchMethodException

      • RuntimeException

        • NullPointerException

        • ArithmeticException

        • IllegalArgumentException

        • IndexOutOfBoundException

        • NumberFormatException

Cada classe de exceção inclui métodos para obter informações adicionais sobre a falha.

Você pode encontrar a classificação completa das exceções Java, incluindo as provenientes de pacotes adicionais, em um guia de referência dedicado.

Sintaxe para tratamento de exceções em Java

try e catch

Todas as exceções são tratadas usando blocos especiais try e catch, que são padrão na maioria das linguagens de programação, incluindo Java.

Dentro do bloco try, você escreve o código que pode conter um erro capaz de gerar uma exceção.

Dentro do bloco catch, você escreve o código que trata a exceção que ocorreu no bloco try previamente definido.

Por exemplo, uma estrutura try-catch pode ter a seguinte aparência:

public class App {
	public static void main(String[] args) {
		try {
			// code that might throw an exception
			int someVariable = 5 / 0;
			System.out.println("Who said you can’t divide by zero?");
		} catch (ArithmeticException someException) {
			// code that handles the exception
			System.out.println("Actually, you can't divide by zero...");
		}
	}
}

A saída desse código no console será:

Actually, you can't divide by zero...

Este exemplo é baseado em uma divisão ilegal por zero, envolvida em um bloco try que lança uma ArithmeticException.

No bloco catch, essa exceção é tratada imprimindo uma mensagem de erro no console.

Graças a essa estrutura, o programa pode continuar sendo executado mesmo após o erro de divisão por zero.

finally

Diferentemente de muitas outras linguagens de programação, o Java inclui um bloco especial finally como parte do mecanismo de tratamento de exceções. Ele é sempre executado — independentemente de uma exceção ocorrer ou não.

Podemos estender a estrutura mostrada anteriormente:

public class App {
	public static void main(String[] args) {
		try {
			// code that might throw an exception
			int someVariable = 5 / 0;
		} catch (ArithmeticException someException) {
			// code that handles the exception
			System.out.println("Actually, you can't divide by zero...");
		} finally {
			// code that always executes
			System.out.println("Who cares if you can divide by zero or not? This message will appear anyway!");
		}
	}
}

Após executar esse código, o console exibirá:

Actually, you can't divide by zero...
Who cares if you can divide by zero or not? This message will appear anyway!

Para entender a necessidade prática do bloco finally, considere o exemplo a seguir:

try {
	parseJson(response.json);
} catch (JSONException someException) {
	System.out.println("Looks like there’s something wrong with the JSON...");
}

// a function that hides the loading indicator
hideLoaderUI();

Em um programa com essa estrutura, a função hideLoaderUI() nunca será executada se ocorrer uma exceção.

Você poderia tentar chamar hideLoaderUI() dentro do tratamento de exceção e também fora dele:

try {
	parseJson(response.json);
} catch (JSONException someException) {
	hideLoaderUI(); // duplicado
    System.out.println("Looks like there’s something wrong with the JSON...");
}

hideLoaderUI(); // duplicado

No entanto, isso resultaria em duplicação desnecessária da chamada da função. Além disso, duplicar código é considerado uma má prática.

Portanto, para garantir que hideLoaderUI() seja executado em qualquer caso sem duplicação, você pode usar um bloco finally:

try {
	parseJson(response.json);
} catch (JSONException someException) {
	System.out.println("Looks like there’s something wrong with the JSON...");
} finally {
	// the loading indicator will be hidden in any case
	hideLoaderUI();
}

throw

O Java permite criar (lançar) exceções manualmente usando o operador especial throw:

public class App {
	public static void main(String[] args) {
		throw new Exception("Something strange seems to have happened...");
	}
}

Você também pode criar uma variável para a exceção antecipadamente e depois lançá-la:

public class App {
	public static void main(String[] args) {
		var someException = new Exception("Something strange seems to have happened...");
		throw someException;
	}
}

throws

Outra palavra-chave importante, throws (observe o “s” no final), permite declarar explicitamente os tipos de exceções (na forma de nomes de classes) que um método pode lançar.

Se esse método lançar uma exceção, ela será propagada para o código chamador, que deverá tratá-la:

public class App {
	public static void someMethod() throws ArithmeticException, NullPointerException, InterruptedException {
		int someVariable = 5 / 0;
	}

	public static void main(String[] args) {
		try {
			App.someMethod();
		} catch (Exception someException) {
			System.out.println("Dividing by zero again? Do you even know what insanity is?");
		}
	}
}

A saída no console será:

Dividing by zero again? Do you even know what insanity is?

Criando exceções personalizadas

A estrutura hierárquica das exceções naturalmente permite a criação de classes de exceções personalizadas que herdam das classes base.

Graças às exceções personalizadas, o Java permite implementar caminhos de tratamento de erro específicos para a aplicação.

Assim, além das exceções padrão do Java, você pode adicionar as suas próprias.

Cada exceção personalizada, como qualquer exceção predefinida, pode ser tratada usando os blocos padrão try-catch-finally:

class MyOwnException extends Exception {
	public MyOwnException(String message) {
		super(message); // chama o construtor da classe pai
        System.out.println("Warning! An exception is about to be thrown!");
	}
}

public class App {
	public static void main(String[] args) {
		try {
			throw new MyOwnException("Just an exception. No explanation. Anyone got a problem?");
		} catch (MyOwnException someException) {
			System.out.println(someException.getMessage());
		}
	}
}

Saída no console:

Warning! An exception is about to be thrown!
Just an exception. No explanation. Anyone got a problem?

Conclusão

Este tutorial demonstrou, por meio de exemplos, por que as exceções são necessárias em Java, como elas ocorrem (incluindo como lançar uma manualmente) e como tratá-las usando as ferramentas correspondentes da linguagem.

As exceções que podem ser capturadas e tratadas são de dois tipos:

  • Checked Exceptions: tratadas em tempo de compilação.

  • Unchecked Exceptions: tratadas em tempo de execução.

Além dessas, existem erros fatais que só podem ser resolvidos reescrevendo o código:

  • Errors: não podem ser tratados.

Existem várias estruturas sintáticas (blocos) usadas para tratar exceções:

  • try: código que pode lançar uma exceção.

  • catch: código que trata a possível exceção.

  • finally: código que é sempre executado, independentemente de uma exceção ter ocorrido.

Além disso, existem palavras-chave para controlar o processo de lançamento de exceções:

  • throw: lança manualmente uma exceção.

  • throws: lista as exceções possíveis em um método declarado.

Você pode encontrar a lista completa de métodos na classe pai Exception na documentação oficial da Oracle.

Linguagem de programação Java
24.10.2025
Reading time: 13 min

Semelhante

Tem perguntas,
comentários ou preocupações?

Nossos profissionais estão disponíveis para ajudá-lo a qualquer momento,
seja para assistência ou apenas se você não souber por onde começar.
Envie-nos um e-mail
Hostman's Support