Baixe o app para aproveitar ainda mais
Prévia do material em texto
Programação II CCT0695 Aula 4 Profª Otília Adaptado: Profº Henrique Tavares Ediberto Mariano Manipulação de Exceções Exceção Ação ou efeito de executar, de excluir. Ruptura de uma regra ou norma; desvio de um padrão estabelecido; rompimento do que se considera normal: não há regra sem exceção. Exceções Exception (java.lang.Exception) - É a raiz das classes originárias da classe Throwable, onde mostra as situações em que a aplicação pode querer capturar e realizar um tratamento para conseguir realizar o processamento. Trata seus erros Error (java.lang.Error) - Também é raiz das classes originárias da classe Throwable, indicando as situações em que a aplicação não deve tentar tratar, como ocorrências que não deveriam acontecer. “Erro” É algo que não pode mais ser tratado Por esse motivo é usado o try/catch e/ou propagação com throw/throwsHierarquia de herança da classe Throwable subclasses Exceções Quando algo imprevisto acontece Provenientes de erros de lógica ou acesso Recursos que talvez não estejam disponíveis. Exceções Motivos externos Abrir um arquivo que não existe; Fazer consulta a um banco de dados que não está disponível; Escrever algo em um arquivo sobre o qual não se tem permissão de escrita; Conectar em servidor inexistente. Exceções Erros de lógica externos Manipular um objeto que está com o valor nulo; Dividir um número por zero; Manipular um tipo de dado como se fosse outro; Utilizar um método ou classe não existentes. Exceções Tratamento Realizar o tratamento dos locais no código que podem vir a lançar possíveis exceções Campo de consulta a banco de dados Locais em que há divisões Consulta a arquivos de propriedades Exceções – Blocos try/catch CRUD no banco de dados; Índices fora do intervalo de array; Anulação de objetos; Cálculos matemáticos; I/O de dados; Erros de rede; Entre outros. Se dá em métodos que envolvem alguma manipulação de dados, bem como: Exceções – try{...} catch{...} try { // trecho de código que pode vir a lançar uma exceção } catch (tipo_excecao_1 e) { // ação a ser tomada } catch (tipo_excecao_2 e) { // ação a ser tomada } catch (tipo_excecao_n e) { // ação a ser tomada } try { ... } – linhas de código que podem vir a lançar uma exceção. catch (tipo_exceção e( { ... } – ação que ocorrerá quando a exceção for capturada. Exceções – NullPointerException public class AumentaFrase { public static void main(String[] args) { String frase = null; String novaFrase = null; novaFrase = frase.toUpperCase(); System.out.println("Frase antiga: "+frase); System.out.println("Frase nova: "+novaFrase); } } Exception in thread "main" java.lang.NullPointerException at br.estacio.lab.aula04.AumentaFrase.main(AumentaFrase.java:8) Exceções – NullPointerException public class AumentaFrase { public static void main(String[] args) { String frase = null; String novaFrase = null; System.out.println("Tratamento de Exceção - uso do try ... catch"); try { novaFrase = frase.toUpperCase(); } catch(NullPointerException e){// captura da possível exceção System.out.println("A frase inicial esta nula."); frase = "Frase vazia"; novaFrase = frase.toUpperCase(); } System.out.println("Frase antiga: "+frase); System.out.println("Frase nova: "+novaFrase); } } Tratamento de Exceção - uso do try ... catch A frase inicial esta nula. Frase antiga: Frase vazia Frase nova: FRASE VAZIA Exceções – Finally (palavra reservada) Exceção é lançada Após a sua captura Ação a ser tomada Exceções Finally (sintaxe) try { // trecho de código que pode vir a lançar uma exceção } catch (tipo_excecao_1 e) { // ação a ser tomada } catch (tipo_excecao_2 e) { // ação a ser tomada } catch (tipo_excecao_n e) { // ação a ser tomada } finally { // ação a ser tomada } Exceções – Finally (exemplo) public class AumentaFrase { public static void main(String[] args) { String frase = null; String novaFrase = null; System.out.println("Tratamento de Exceção - uso do finally"); try { novaFrase = frase.toUpperCase(); } catch(NullPointerException e){// captura da possível exceção System.out.println("A frase inicial esta nula."); frase = "Frase vazia"; } finally { novaFrase = frase.toUpperCase(); } System.out.println("Frase antiga: "+frase); System.out.println("Frase nova: "+novaFrase); } } Tratamento de Exceção - uso do finally A frase inicial esta nula. Frase antiga: Frase vazia Frase nova: FRASE VAZIA Exceções – try/catch/finally public class DivisaoPorZero { public static void main(String[] args) { try { System.out.println(3/0); System.out.println("me escreva"); }catch(ArithmeticException e){ // divisão por zero é uma ArithmeticException System.out.println(e); }finally { //código a ser executado antes do bloco try terminar System.out.println("passou pelo finally"); } System.out.println("após exceção"); } } java.lang.ArithmeticException: / by zero passou pelo finally após exceção Exceção - Cláusulas throw/throws As cláusulas throw e throws podem ser entendidas como ações que propagam exceções, ou seja, em alguns momentos existem exceções que não podem ser tratadas no mesmo método que gerou a exceção. throw • Ela é executada para indicar que uma exceção ocorreu. • Especifica um objeto a ser lançado. • O operando de um throw pode ser de qualquer classe derivada da classe Throwable • É usada para transferir o controle do bloco try para o bloco catch throws • Aparece depois da lista de parâmetros do método e antes do corpo do método. • É usada para manipulação de exceções sem o bloco try & catch. Ele especifica as exceções que um método pode lançar para o chamador e não lida com ele mesmo. //tratando ArithmeticExceptions e InputMismatchExceptions public class DivisaoPorZeroComExcecao { // demonstra o lançamento de uma exceção quando ocorre uma divisão por zero public static int quociente(int numerador, int denominador) throws ArithmeticException{ return numerador / denominador; // possível divisão por zero }// fim do método quociente public static void main(String[] args) { Scanner entrada = new Scanner(System.in); // scanner para entrada boolean continuaLoop = true; // determina se mais entradas são necessárias do { try { // le dois números e calcula o quociente System.out.println("Digite um valor inteiro para numerador:"); int numerador = entrada.nextInt(); System.out.println("Digite um valor inteiro para denominador:"); int denominador = entrada.nextInt(); int resultado = quociente(numerador, denominador); System.out.printf("\nResultado: %d / %d = %d\n", numerador, denominador, resultado); continuaLoop = false; // entrada bem-sucedida: fim do loop }catch(InputMismatchException a) { System.err.printf("\nExceção: %s\n", a); entrada.nextLine(); // descarta entrada para o usuário poder tentar de novo System.out.println("Você deve inserir números inteiros. Favor tente novamente.\n"); }catch(ArithmeticException b) { System.err.printf("\nExceção: %s\n", b); System.out.println("Zero é inválido para denominador. Favor tente novamente.\n"); } }while(continuaLoop); // fim do repita. } } Exceção – Calculadora - reformulada Exceção - Cláusulas throw - exemplo public class ExeThrow { static void exibir() { try { throw new NullPointerException("demonstração"); } catch(NullPointerException e){ System.out.println("Apanhado dentro do método exibir()."); throw e; // repetindo a exceção } } public static void main(String[] args) { try { exibir(); } catch(NullPointerException e){ System.out.println("Preso em principal"); } } } Apanhado dentro do método exibir(). Preso em principal Exceção - Cláusulas throws - exemplo public class SemThrows { public static void main(String[] args) { Thread.sleep(20000); System.out.println("Olá pessoal!"); } } Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unhandled exception type InterruptedException at br.estacio.lab.aula04.SemThrows.main(SemThrows.java:5)Exceção - Cláusulas throws - exemplo public class SemThrows { public static void main(String[] args) throws InterruptedException { Thread.sleep(20000); System.out.println("Olá pessoal!"); } } Olá pessoal! Exceções – Throwable (Métodos para captura de erros) oferece alguns métodos que podem verificar os erros reproduzidos, quando gerados para dentro das classes. Esse tipo de verificação é visualizado no rastro da pilha (stracktrace), que mostra em qual linha foi gerada a exceção. Podem ser tratados no bloco catch para visualizar em que momento foi gerado o erro. printStrackTrace – Imprime uma mensagem da pilha de erro encontrada em um exceção. getStrackTrace – Recupera informações do stracktrace que podem ser impressas através do método printStrackTrace. getMessage – Retorna uma mensagem contendo a lista de erros armazenadas em um exceção no formato String. Exceção - Throwable (Método printStrackTrace) public class ExePrintStrackTrace { public static void main(String[] args) { System.out.println("Uso do método printStrackTrace"); Scanner entrada = new Scanner(System.in); try { System.out.println("Obs.: Caso a entrada de dados for ilegal, causará uma exceção!!"); System.out.println("Informe sua idade: "); int idade = entrada.nextInt(); System.out.println(idade); } catch(InputMismatchException e){ e.printStackTrace(); } } } Exceção - Throwable (Método printStrackTrace) Uso do método printStrackTrace Obs.: Caso a entrada de dados for ilegal, causará uma exceção!! Informe sua idade: 51 51 Uso do método printStrackTrace Obs.: Caso a entrada de dados for ilegal, causará uma exceção!! Informe sua idade: Maria java.util.InputMismatchException at java.util.Scanner.throwFor(Unknown Source) at java.util.Scanner.next(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at br.estacio.lab.aula04.ExePrintStrackTrace.main(ExePrintStrackTrace.java:13) Exceção - Throwable (Método getStrackTrace) public class ExeGetStrackTrace { public static void main(String[] args) throws Exception { try { addNumeroPositivos(2, -1); } catch(Throwable e){ StackTraceElement[] stktrace = e.getStackTrace(); for(int i = 0; i < stktrace.length; i++) {// elemento de impressão do stktrace System.out.println("Os dois números não são positivos"); System.out.println("Index “ + i + " do stack trace “ + "array contem = “ + stktrace[i].toString()); } } } //método que adiciona dois números positivos public static void addNumeroPositivos(int a, int b) throws Exception{ // se os números forem positivos então adiciona ou uma exceção if(a < 0 || b < 0) { throw new Exception("Os dois números não são positivos"); } else { System.out.println(a + b); } } } Os dois números não são positivos Index 0 do stack trace array contem = br.estacio.lab.aula04.ExeGetStrackTrace.addPositiveNumbers(ExeGetStrackTrace.java:23) Os dois números não são positivos Index 1 do stack trace array contem = br.estacio.lab.aula04.ExeGetStrackTrace.main(ExeGetStrackTrace.java:9) Exceção - Throwable (Método getMessage) public class ExeGetMessage { public static void main(String[] args) { System.out.println("Uso do método getMessage"); try { int[] numero = new int[5]; for (int i = 0; i <= 10; i++) { numero[i] = i; System.out.println(i); } } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Array fora do indice: " + e.getMessage()); } } } Uso do método getMessage 0 1 2 3 4 Array fora do indice: 5 Serialização e desserialização Serialização permite que você crie o objeto ou uma variável de instância de uma classe e grave em um arquivo para futuramente, utiliza esse objeto/variável com seu estado que foi gravado. Exemplo - IMC A classe Pessoa, apresentada na Listagem 1, será empregada para estabelecer uma estrutura de registro para um arquivo utilizado para manter informações de um conjunto de pessoas adotado em um sistema para controle do Índice de Massa Corpórea (IMC). A estrutura da referida classe possui os seguintes atributos e métodos: String nome – atributo nome da pessoa; double pc – atributo peso corporal da pessoa (valor em quilogramas); double alt – atributo altura da pessoa (valor em metros); Pessoa(String nome, double pc, double alt) – método construtor da classe; double IMC() – método que retorna o cálculo do IMC que é definido pela relação entre peso corporal dividido pelo quadrado da altura da pessoa. O IMC é uma medida utilizada para medir a obesidade adotada pela Organização Mundial de Saúde. É o padrão internacional para avaliar o grau de obesidade de um indivíduo; String interpretaIMC() – método que retorna a interpretação do valor do IMC calculado através da classificação fornecida pelo Sistema de Vigilância Alimentar e Nutricional (SISVAN), levando em consideração indivíduos adultos. public class PessoaSerial implements Serializable { private String nome; private double pc; // peso corporal private double alt; // altura em metros public PessoaSerial(String nome, double pc, double alt) { this.nome = nome; this.pc = pc; this.alt = alt; } // getters e setters public double IMC() { return (getPC() / (getAlt() * getAlt())); } public String interpretaIMC() { double vlrIMC = IMC(); if (vlrIMC < 18.5) return ("baixo peso"); else if (vlrIMC < 25.0) return ("peso adequado"); else if (vlrIMC < 30.0) return ("sobrepeso"); else return ("obesidade"); } } Estruturar as informações do objeto em uma classe que implementa a interface Serializable public class EmpacotamentoSerial { // serialização: gravando o objetos no arquivo binário "nomeArq" public static void gravarArquivoBinario(ArrayList<Object> lista, String nomeArq) { File arq = new File(nomeArq); try { arq.delete(); arq.createNewFile(); ObjectOutputStream objOutput = new ObjectOutputStream(new FileOutputStream(arq)); objOutput.writeObject(lista); objOutput.close(); } catch (IOException erro) { System.out.printf("Erro: %s", erro.getMessage()); } } // desserialização: recuperando os objetos gravados no arquivo binário "nomeArq" public static ArrayList<Object> lerArquivoBinario(String nomeArq) { ArrayList<Object> lista = new ArrayList(); try { File arq = new File(nomeArq); if (arq.exists()) { ObjectInputStream objInput = new ObjectInputStream(new FileInputStream(arq)); lista = (ArrayList<Object>) objInput.readObject(); objInput.close(); } } catch (IOException erro1) { System.out.printf("Erro: %s", erro1.getMessage()); } catch (ClassNotFoundException erro2) { System.out.printf("Erro: %s", erro2.getMessage()); } return (lista); } } public class TesteSerial { public static void main(String[] args) throws IOException { Scanner ler = new Scanner(System.in); String nome; double pc; double alt; // 1) desserialização: recuperando os objetos gravados no arquivo binário "dados.dat" ArrayList<Object> pessoa = EmpacotamentoSerial.lerArquivoBinario("dados.dat"); while (true) {// 2) entrada de dados System.out.printf("Ficha nro: %d.\n", (pessoa.size() + 1)); System.out.printf("Informe o nome da pessoa, FIM para encerrar:\n"); nome = ler.nextLine(); if (nome.equalsIgnoreCase("FIM")) break; System.out.printf("\nInforme o peso corporal (em kg)...............: "); pc = ler.nextDouble(); System.out.printf("Informe a altura (em metros: 1,77 por exemplo): "); alt = ler.nextDouble(); pessoa.add(new PessoaSerial(nome, pc, alt)); // adiciona um novo objeto a lista ler.nextLine(); // esvazia o buffer do teclado System.out.printf("\n"); }// 3) serialização: gravando o objeto no arquivo binário "dados.dat" EmpacotamentoSerial.gravarArquivoBinario(pessoa, "dados.dat"); } } public class TesteSerial2 { public static void main(String[] args) { // desserialização: recuperando os objetos gravados no arquivo binário dados.dat ArrayList<Object> pessoa = EmpacotamentoSerial.lerArquivoBinario("dados.dat"); int i = 1; for (Object item : pessoa) { System.out.printf("Ficha nro....: %d.\n", i++); // ((Pessoa)item) - implementa o mecanismode downcast, ou seja, o objeto "item" declarado a partir da classe base "Object" é referenciado como um objeto "PessoaSerial" System.out.printf("Nome.........: %s\n", ((PessoaSerial) item).getNome()); System.out.printf("Peso Corporal: %.2f kgs\n", ((PessoaSerial) item).getPC()); System.out.printf("Altura.......: %.2f metros\n", ((PessoaSerial) item).getAlt()); System.out.printf("IMC..........: %.2f\n", ((PessoaSerial) item).IMC()); System.out.printf("Interpretacao: %s\n\n", ((PessoaSerial) item).interpretaIMC()); } } } Exportação de dados A exportação de dados persistidos corresponde à tarefa de compartilhar a mesma fonte de dados entre diversos aplicativos que podem, por exemplo, ser implementados em ambientes de desenvolvimento de naturezas diferentes. Uma aplicação para exportar dados deve criar um arquivo em um formato que outro aplicativo entende, permitindo assim que os dois programas possam compartilhar os mesmos dados. Em geral, dados exportados se apresentam no formato texto uma vez que arquivos que utilizam este formato podem ser facilmente lidos ou abertos por qualquer programa que lê texto e, por essa razão, são considerados universais. public class ExportarSerial { public static void main(String[] args) throws IOException { // desserialização: recuperando os objetos gravados no arquivo binário "dados.dat" ArrayList<Object> pessoa = EmpacotamentoSerial.lerArquivoBinario("dados.dat"); FileWriter arq = new FileWriter("export.txt"); PrintWriter gravarArq = new PrintWriter(arq); int i = 1; int n = pessoa.size(); for (Object item : pessoa) { System.out.printf("Exportando %do. registro de %d: %s\n", i++, n, ((PessoaSerial) item).getNome()); gravarArq.printf("Nome|%s;Peso Corporal|%.2f;Altura|%.2f;IMC|%.2f;Interpretação|%s%n", ((PessoaSerial) item).getNome(), ((PessoaSerial) item).getPC(), ((PessoaSerial) item).getAlt(), ((PessoaSerial) item).IMC(), ((PessoaSerial) item).interpretaIMC()); } gravarArq.close(); System.out.printf("\nExportação realizada com sucesso.\n"); } } Importar txt Para utilizar os dados produzidos, durante o processo de exportação por outro aplicativo, o programa de importação deve implementar a capacidade de recuperar e processar os dados importados. Uma aplicação para importar dados deve ser capaz de reconhecer o formato e a organização dos dados criados no arquivo texto de exportação. public class ImportaSerial { public static void main(String[] args) throws FileNotFoundException, IOException { FileReader arq = new FileReader("export.txt"); BufferedReader lerArq = new BufferedReader(arq); int i = 1, j, n; String linha = lerArq.readLine(); while (linha != null) { System.out.printf("Fichar nro: %d.\n", i); n = linha.length(); for (j = 0; j < n; j++) { if (linha.charAt(j) == '|’) System.out.printf(": "); else if (linha.charAt(j) == ';’) System.out.printf("\n"); else System.out.printf("%c", linha.charAt(j)); } System.out.printf("\n\n"); i++; linha = lerArq.readLine(); } lerArq.close(); } } Resumo - Serializable O mecanismo de serialização de objetos permite converter a representação interna de um objeto para uma sequência de bytes. Uma vez serializado, um objeto pode ser salvo em arquivo e recuperado a partir do arquivo e desserializado para recriar o objeto na memória. O processo de serialização de objetos com o propósito de persisti-los em arquivos de dados passa por três etapas: 1) estruturar as informações do objeto em uma classe que implementa a interface Serializable; 2) persistir os objetos serializados em um arquivo binário; e, 3) recuperar os objetos serializados do arquivo binário. Exercício prático - Cenário A forma correta de lidar com os casos em que um sistema orientado a objetos não segue o fluxo normal de execução, ou viola regras estabelecidas em termos de negócios, é com o uso de exceções e instruções de controle próprias para elas. Aqui deverá ser desenvolvida uma classe Pessoa, a qual deterá um ArrayList<Pessoa> como dependentes da mesma, e um repositório de objetos Pessoa com uso de HashMap. Para estas classes são definidas as seguintes regras: Uma pessoa que já tem responsável não pode ser dependente de outra. Não podem ser adicionadas duas pessoas ao repositório com o mesmo identificador. Não podem ser removidas pessoas com dependentes do repositório. Deverá ser utilizada uma especialização de Exception que informe a Pessoa relacionada com o erro ocorrido. Exercícios 1) O que uma exceção representa em um programa? 2) Qual a diferença entre as classes Exception (java.lang.Exception) e Error (java.lang.Error)? 3) Quais são as raízes originárias da classe Throwable? 4) Cite 4 motivos externos de uma exceção. 5) Cite 4 erros de lógica externos que pode existir em uma exceção. 6) Em que tratamento de exceção, onde o bloco finally deve aparecer, o código que fica dentro dele deve ser feito o que? Exercícios 7) Qual a diferença entre Cláusulas throw/throws? 8) Quais os métodos para captura de erros da classe Throwable? 9) O que é uma serialização?
Compartilhar