Nessa aula, vamos aprender sobre os tipos de erro que podem acontecer na criação e execução de um programa.
Ao fim da aula, saberemos como prever e lidar com certas condições excepcionais que podem interromper o funcionamento esperado do nosso código.
Existem duas maneiras pelas quais um programa que criamos pode dar errado...
Vejam o código abaixo:
Há algum problema com o programa? De que tipo?
Sim. O literal atribuído à variável num é do tipo double, e não float.
Como o rebaixamento de tipo não é permitido em Java, ocorrerá um erro de compilação.
public class RaizQuadrada {
public static void main(String[] args) {
float num = 2.0;
System.out.printf("A raíz quadrada de %f é %f\n", num, Math.sqrt(num));
}
}
public class RaizQuadrada {
public static void main(String[] args) {
float num = 2.0;
System.out.printf("A raíz quadrada de %f é %f\n", num, Math.sqrt(num));
}
}
RaizQuadrada.java:3: error: incompatible types: possible lossy conversion
from double to float
float num = 2.0;
^
1 error
E quanto ao código abaixo:
Há algum problema com o programa? De que tipo?
Sim. Um array de 100 elementos tem posições válidas de 0 até 99.
Na linha 4 tenta-se atribuir um valor em uma posição fora dos limites do array.
Entretanto, o compilador Java não verifica os limites de arrays, portanto o código vai compilar sem erros.
O programa portanto causará um erro de execução.
public class ManipulacaoDeArray {
public static void main(String[] args) {
int[] v = new int[100];
v[100] = 2;
}
}
public class ManipulacaoDeArray {
public static void main(String[] args) {
int[] v = new int[100];
v[100] = 2;
}
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 100 out of bounds for length 100 at ManipulacaoDeArray.main(ManipulacaoDeArray.java:4)
Nosso foco aqui será nos erros de execução, que não podem ser detectados pelo compilador e possuem o potencial de causar danos ao sistema e aos usuários, caso não tratados.
Podemos antecipar e detectar certos erros de execução, criando um fluxo de código alternativo à ocorrência do erro e salvando nosso programa de uma "morte" repentina.
A esse processo se dá o nome de tratamento de exceção.
Chamamos os erros encontrados dessa maneira de exceções.
Isso é feito em três etapas:
Vejam o programa abaixo:
Compilamos o programa e não ocorreram erros.
Podemos prever algum erro de execução?
Pause os slides e pense um pouco...
O programa espera receber uma idade (digitada pelo usuário) e imprime a idade recebida em binário.
E se o valor que o usuário digitar não puder ser convertido em um número inteiro?
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade;
Scanner scanner = new Scanner(System.in);
System.out.println("Digite sua idade e aperte <ENTER>: ");
String linha = scanner.nextLine();
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
}
Agora que identificamos uma exceção, aplicamos o mecanismo para detectar quando ela ocorre.
No Java, esse mecanismo é o bloco try ... catch.
Colocamos dentro de um bloco try o código que pode causar a exceção.
O bloco try é sempre seguido de um bloco catch, onde colocamos o caminho alternativo que o código deve seguir se a exceção ocorrer.
O bloco catch captura apenas exceções do tipo que foi especificado em sua cláusula. Nesse caso NumberFormatException.
Nesse caso informamos ao usuário que a idade digitada é inválida.
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade;
Scanner scanner = new Scanner(System.in);
System.out.println("Digite sua idade e aperte : ");
String linha = scanner.nextLine();
try { // Bloco try: a exceção pode ocorrer aqui
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
catch (NumberFormatException e) {
System.out.println("Idade inválida.");
}
}
}
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade;
Scanner scanner = new Scanner(System.in);
System.out.println("Digite sua idade e aperte : ");
String linha = scanner.nextLine();
try { // Bloco try: a exceção pode ocorrer aqui
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
catch (NumberFormatException e) {
System.out.println("Idade inválida.");
}
}
}
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade;
Scanner scanner = new Scanner(System.in);
System.out.println("Digite sua idade e aperte : ");
String linha = scanner.nextLine();
try { // Bloco try: a exceção pode ocorrer aqui
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
catch (NumberFormatException e) {
System.out.println("Idade inválida.");
}
}
}
Entretanto, isso não resolveu o problema do nosso programa ser abortado quando a exceção ocorre.
Precisamos então melhorar o nosso caminho alternativo, retornando ao fluxo planejado do programa.
Podemos fazer isso repetindo o trecho que lê e imprime a idade até uma idade válida ser digitada.
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade = 0;
Scanner scanner = new Scanner(System.in);
while (idade == 0) {
try {
System.out.println("Digite sua idade e aperte : ");
String linha = scanner.nextLine();
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
catch (NumberFormatException e) {
System.out.println("Idade inválida.");
}
}
}
}
import java.util.Scanner;
public class IntroExcecoes {
public static void main(String[] args) {
int idade = 0;
Scanner scanner = new Scanner(System.in);
while (idade == 0) {
try {
System.out.println("Digite sua idade e aperte : ");
String linha = scanner.nextLine();
idade = Integer.parseInt(linha);
System.out.println("Sua idade em binário é: " +
Integer.toBinaryString(idade));
}
catch (NumberFormatException e) {
System.out.println("Idade inválida.");
}
}
}
}
Agora podemos evitar que nossos programas sejam interrompidos por exceções.
Exercitem diversos cenários possíveis onde as coisas podem dar errado. Ficarão surpresos com a quantidade de exceções diferentes que podem encontrar em programas simples.
Abordaremos mais detalhes sobre exceções adiante no curso.
Perguntas:
Até a próxima aula!