Controle Fluxo

Estrutura Excepcionais

Exceções

Ao executar o código Java, diferentes erros podem acontecer: erros de codificação feitos pelo programador, erros devido a entrada errada ou outros imprevistos.

Quando ocorre um erro, o Java normalmente para e gera uma mensagem de erro. O termo técnico para isso é: Java lançará uma exceção (jogará um erro).

De forma interpretativa em Java, um erro é algo irreparável, a aplicação trava ou é encerrada drasticamente. Já exceções é um fluxo inesperado da nossa aplicação, exemplo: Querer dividir um valor por zero, querer abrir um arquivo que não existe, abrir uma conexão de banco, com usuário ou senha inválida. Todos estes cenários e os demais, não são erros mas sim fluxos, não previstos pela aplicação.

É ai que entra mais uma responsabilidade do desenvolvedor, prever situações iguais a estas e realizar o que denominamos de Tratamento de Exceções.

Estruturas Excepcionais

Cenários conhecidos

AboutMe.java
import java.util.Locale;
import java.util.Scanner;

public class AboutMe {
    public static void main(String[] args) {
        //criando o objeto scanner
        Scanner scanner = new Scanner(System.in).useLocale(Locale.US);
        
        System.out.println("Digite seu nome");
        String nome = scanner.next();
        
        System.out.println("Digite seu sobrenome");
        String sobrenome = scanner.next();

        System.out.println("Digite sua idade");
        int idade = scanner.nextInt();
        
        System.out.println("Digite sua altura");
        double altura = scanner.nextDouble();

        
        //imprimindo os dados obtidos pelo usuario
        System.out.println("Olá, me chamo " + nome.toUpperCase() + " " + sobrenome.toUpperCase());
        System.out.println("Tenho " + idade + " anos ");
        System.out.println("Minha altura é " + altura + "cm ");
        scanner.close();   
    }
}

Aparentemente é um programa simples, mas vamos listar algumas possíveis exceções que podem acontecer.

  • Não informar o nome e sobrenome;
  • O valor da idade ter um caractere NÃO numérico;
  • O valor da altura ter uma vírgula ao invés de ser um ponto (conforme padrão americano);

Executando o nosso programa com os valores abaixo, vamos entender qual exceção acontecerá:

EntradaExceçãoCausa
Marcelo
Azevedo
quinze (15)java.util.InputMismatchExceptionO programa esperava o valor do tipo numérico inteiro.
1,65java.util.InputMismatchExceptionjava.util.InputMismatchException
ℹ️ Informação
A melhor forma de prever, que pode ocorrer uma exceção, é pensar que ela pode ocorrer. Lei de Murphy

Exceções mapeadas

A linguagem Java, dispõe de uma vasta lista de classes que representam exceções, abaixo iremos apresentar as mais comuns:

NomeCausa
java.lang.NullPointerExceptionQuando tentamos obter alguma informação de uma variável nula.
java.lang.ArithmeticExceptionQuando tentamos dividir um valor por zero.
java.sql.SQLExceptionQuando existe algum erro, relacionado a interação com banco de dados.
java.io.FileNotFoundExceptionQuando tentamos ler ou escrever, em um arquivo que não existe.

Tratando exceções

E quando inevitavelmente, ocorrer uma exceção? Como nós desenvolvedores podemos ajustar o nosso algoritmo para amenizar o ocorrido?

A instrução try, permite que você defina um bloco de código, para ser testado quanto a erros enquanto está sendo executado.

A instrução catch, permite definir um bloco de código a ser executado, caso ocorra um erro no bloco try.

A instrução finally, permite definir um bloco de código a ser executado, independente de ocorrer um erro ou não. As palavras-chave try e catch vem em pares:

Estrutura de um bloco com try e catch:

try {
  //  bloco de código conforme esperado
}
catch(Exception e) {// precisamos saber qual exceção
  // bloco de código que captura as exceções que podem acontecer
  // em caso de um fluxo não previsto
}
🔔 Atenção
O bloco try / catch pode conter um conjunto de catchs, correspondentes a cada exceção prevista em uma funcionalidade do programa.

Hora da verdade

Vamos explorar alguns outros cenários, com fluxo condicionais, repetições e excepcionais.

Case 1: Vamos imaginar que em um processo seletivo, existe o valor base salarial de R$ 2.000,00 e o salário pretendido pelo candidato. Vamos elaborar um controle de fluxo onde:

  • Se o valor salário base for maior que valor salário pretendido, imprima : LIGAR PARA O CANDIDATO;
  • Se não se o valor salário base for igual ao valor salário pretendido, imprima : LIGAR PARA O CANDIDATO, COM CONTRA PROPOSTA;
  • Se não imprima: AGUARDANDO RESULTADO DOS DEMAIS CANDIDATOS.

Case 2: Foi solicitado, que nosso sistema garanta que, diante das inúmeras candidaturas sejam selecionados apenas no máximo, 5 candidatos para entrevista, onde o salário pretendido seja menor ou igual ao salário base.

// Array com a lista de candidatos

String [] candidatos = {"FELIPE","MÁRCIA","JULIA","PAULO","AUGUSTO","MÔNICA","FABRÍCIO","MIRELA","DANIELA","JORGE"};
// Método que simula o valor pretendido

import java.util.concurrent.ThreadLocalRandom;
static double valorPretendido() {
   return ThreadLocalRandom.current().nextDouble(1800, 2200);
}

Case 3: Agora é hora de imprimir a lista dos candidatos selecionados, para disponibilizar para o RH entrar em contato.

Case 4: O RH deverá realizar uma ligação, com no máximo 03 tentativas para cada candidato selecionado e caso o candidato atenda, deve-se imprimir:

  • "CONSEGUIMOS CONTATO COM _[CANDIDATO] ``` APÓS **_**TENTATIVA`** TENTATIVA(S)" ;**
  • Do contrário imprima: "NÃO CONSEGUIMOS CONTATO COM O _[CANDIDATO]_".
public class ProcessoSeletivo {
  public static void main(String[] args) {
      //salario base maior que salario pretendido
      case1(2000.0, 1900.0);

      //salario base igual que salario pretendido
      case1(2000.0, 2000.0);

      //salario base igual que salario pretendido
      case1(1900.0, 2000.0);V
  }
  static void case1(double salarioBase, double salarioPretendido) {
      // ... DIGITE SUA SOLUÇÃO AQUI ...
  }
}
import java.util.concurrent.ThreadLocalRandom;

public class ProcessoSeletivo {
  public static void main(String[] args) {
    case2();
    
  }
  static void case2() {
    double salarioBase = 2000.0;
    String [] candidatos = {"FELIPE","MÁRCIA","JULIA","PAULO","AUGUSTO","MÔNICA","FABRÍCIO","MIRELA","DANIELA","JORGE"};
    int totalSelecionados = 0;
    int proximoCandidato = 0;
      
      // ... DIGITE SUA SOLUÇÃO AQUI ...
    
      System.out.println("Total de selecionados: " + totalSelecionados);
    System.out.println("Total de consultados: " + proximoCandidato);
  }
  static double valorPretendido() {
       return ThreadLocalRandom.current().nextDouble(1800, 2200);
  }
}
public class ProcessoSeletivo {
  public static void main(String[] args) {
    case3();
    
  }
  static void case3() {
      //assumindo que estes foram os candidatos selecionados
      String [] candidatosSelecionados = {"FELIPE","MÁRCIA","JULIA","PAULO","AUGUSTO"};
    
    //forma indexada
    //quando preciso do índice para complementar a lógica
    System.out.println("Imprimindo com a ordem de seleção pelo índice");
    
      // ... DIGITE SUA SOLUÇÃO AQUI ...
    
    //forma abreviada
    //interação total sem precisar da posição ou índice
    System.out.println("Imprimindo todos sem a necessidade de exibir o índice");

      // ... DIGITE SUA SOLUÇÃO AQUI ...
    
  }
import java.util.Random;

public class ProcessoSeletivo {
  public static void main(String[] args) {
      //assumindo que estes foram os candidatos selecionados
    String [] candidatosSelecionados = {"FELIPE","MÁRCIA","JULIA","PAULO","AUGUSTO"};
    //primeiro um for para selecionar os candidatos
      // ... DIGITE SUA SOLUÇÃO AQUI ...
    
  }
  static void case4(String candidato) {
    
    int tentativasRealizadas = 1;
    boolean atendeu=false;
      
      // ... DIGITE SUA SOLUÇÃO AQUI ...
    
    if(atendeu)
        System.out.println("CONSEGUIMOS CONTATO COM " + candidato +" NA " + tentativasRealizadas + " TENTATIVA");
    else
        System.out.println("NÃO CONSEGUIMOS CONTATO COM " + candidato +", NÚMERO MÁXIMO TENTATIVAS " + tentativasRealizadas + " REALIZADA");
  }
  
  //método auxiliar
  static boolean atender() {
    return new Random().nextInt(3)==1;
  }
}

Referências