Métodos de Programação II (Mestrado Integrado em Engenharia de Comunicações) 1º Ano, 2º Semestre Excepções e Streams em Java Métodos Programação II 1 Excepções • O Java introduz uma forma de fornecer robustez aos programas através de um mecanismo de tratamento de excepções. • O que é uma excepção ? – É uma sinal gerado pela máquina virtual java (em tempo de execução) que é comunicado ao programa indicando a ocorrência de uma erro recuperável. – Exemplos: tentativas de divisão por zero, indexação fora dos limites de um array, tentativas de leitura para além dos limites de um ficheiro, etc. – São quase sempre violações semânticas ao nível do ambiente de programação – No entanto (como vamos ver com exemplos), as excepções podem resultar de acções que não obedecem às restrições semânticas dos próprios problemas codificados. Métodos Programação II 2 Excepções (cont) • Uma excepção é lançada (thrown) no ponto do código onde ocorreu e diz-se apanhada (caugh) no ponto do código para o qual o controle foi transferido. • As excepções podem ser implícitas (originadas da máquina Java) ou explicitas (programadas e incluídas no código). • Excepções são representadas por instâncias da respectiva classe de excepção. • Podemos definir as nossas próprias excepções definindo classes que são subclasses de java.lang.throwable.Exception • Exemplo do posicionamento na hierarquia de classes: Object Throwable Exception RunTimeException Métodos Programação II ArrayIndexOutOfBoundsException 3 Excepções (exemplo) • Para o programa t.java: public static void main(String a[]) { double v[] = new double[10]; for(int i=0;i<11;i++) v[i] = i * i; } • A sua execução lança a excepção (e mensagem): • > java t Exception in thread "main“ java.lang.ArrayIndexOutOfBoundsException: 10 at t.main(t.java:4) Nome da classe que representa esta excepção Métodos Programação II 4 Definição de blocos de vigilância de excepções • Declaração de blocos de código onde são tratadas as excepções: • O Java usa cinco keywords para estas declarações try / catch / throw / throws / finally • try{ Definição do bloco do código a detectar a ocorrência da excepção } catch(Id_da_excepção var1) { Definir tratamento a dar a este caso. Vão existir tantos catch quantas as excepções a tratar. } finally { Código que é executado independentemente da ocorrência ou não da excepção. Exemplo: fechar ficheiro,etc. } Métodos Programação II 5 Exemplo try/catch try { …. …. } catch(ArrayIndexOutOfBoundsException e) { System.out.println(“ Limite máximo de elementos atingido”); } catch(NumberFormatException e) { System.out.println(“ Formato do valor numérico inválido”); } catch(NovaExcep e) { System.out.println(e.getMessage()); } …. …. Métodos Programação II 6 Lançamento de excepções e definição de métodos • Podemos ter métodos a não tratar localmente as excepções mas a delegar na entidade que envia a mensagem ao método. Nome da classe de excepção • Exemplo: public double area() throws NumberFormatException { ….. …. } Palavra chave que designa lançamento da excepção para ser tratada exteriormente ao método Métodos Programação II 7 Excepções representativas de violações semânticas • Por vezes, podemos usar as excepções como indicadores de situações anómalas que ocorrem durante a execução do nosso programa. • Estas situações de erro são representadas por excepções definidas pelo programador. Os erros são de definição própria dentro do contexto do programa e.g. o utilizador escolher uma opção não esperado num menu de escolha. • Exemplo: public class Stack Indicação que lança a excepção para o exterior { ...... public Object pop() throws emptyStackException { if(this.empty()) throw new emptyStackException(); else numElem -=1; Criação de uma instância da } excepção e seu lançamento } Métodos Programação II 8 Classes representativas de Excepção • Quando pretendemos definir uma excepção representativa de uma violação semântica do nosso ambiente definimos uma nova classe. class NovaExcep extends Exception { NovaExcep() { super(); } NovaExcep(String s) { super(s); } } • Existe um método getMessage() definido em Exception que contém a mensagem de erro correspondente à violação ou erro. Métodos Programação II 9 Streams • Resume em Java todas as considerações sobre I/O de dados. • Noção de Stream: • abstracção que representa fonte/destino de dados do tipo sequencial e independente dos dispositivos físicos. • Como abstracção que é tem de ser redefinida e concretizada! • Package = java.io • Duas grandes divisões (classes): – InputStream – OutputStream • Duas classes de streams: – Streams de texto; – Streams de bytes. Métodos Programação II 10 Classes Não Stream • Existem classes de tratamento de ficheiros que não são subclasses de InputStream ou OutputStream. Nomeadamente a classe File que trata de ficheiros de texto em disco. Public static void main(String a[]) { File f1 = new File("c:\jdk\mysource\exe1.java"); String nome = f1.getName(); String path = f1.getPath(); boolean test1 = f1.isFile(); boolean test2 = f1.isDirectory(); int comp = f1.length(); f1.delete(); } Métodos Programação II 11 Classes Stream • Tratar ficheiros de texto. Por exemplo imprimir as palavras contidas num ficheiros de texto. Usa-se BufferedReader que é a classe de leitura de streams de texto com buffer. FileReader permite ler sucessivas linhas de texto através do método readline(). A situação é análoga com a classe BufferedWriter. class Parse { Classe de identificação de public static void main(String arg[0]) tokens dentro de uma { string, usando um FileReader in = new FileReader(argv[0]); separador. Exemplo: “as;b;ff;hh;77;a” usando “;” BufferedReader fs = new BufferedReader(in); String s = fs.readLine(); String separador = " "; do { StringTokenizer st = new StringTokenizer(s,separador); while(st.hasMoreTokens()) System.out.println(st.nextToken()); } while((s = fs.readLine()) != null); } Próximo token } Métodos Programação II 12 Classe PrintWriter para ficheiros texto • Exemplo: public static void main(String a[]) { Circulo c = new Circulo(1,5,12); Circulo c2 = new Circulo(1,1,9); try{ PrintWriter p = new PrintWriter(“formas.txt”); p.println(c.toString()); p.println(c2.toString()); p.flush(); p.close(); } catch(IOException e) {….. }; } Métodos Programação II 13 ObjectStreams • Em Java é possível gravar objectos numa stream de uma forma transparente. Isto é, sem ter de nos preocupar com o que esse objecto é! Assim podemos ler/escrever para uma stream objectos, arrays e tipos de dados simples ex: int. • As classes ObjectInputStream e ObjectOutputStream implementam um algoritmo de serialização. Ou seja, implementam um algoritmo que garante que todas as referencias cruzadas existentes entre instâncias de diferentes classes são devidamente repostas aquando da leitura das tais instâncias. • Para garantir que isto aconteça basta que as classes das referidas instâncias que pretendemos gravar implementem a interface Serializable. • Uma classe é Serializable se todas as variáveis de instância por esta definidas pertencerem a classes Serializable. • A maioria das classes que temos vindo a usar são Serializable ex: String, arrays, etc. • Notar no entanto que as variáveis static não são serializáveis! Métodos Programação II 14 • Exemplo: Gravar um conjunto de figuras geométricas. Circulo e Elipse são subclasse da classe Forma apresentada em aulas anteriores. import java.io.*; public abstract class Forma implements Serializable { public abstract double area(); public abstract double perimetro(); } class test { public static void main(String a[]) { Forma f1 = new Circulo(); Forma f2 = new Elipse(); Forma f3 = new Circulo(); grava(f1,"figuras"); grava(f2,"figuras"); grava(f3,"figuras"); Formas f[] = new Formas[10]; ler("figuras",f); int i = 0; while(f[i] != null) System.out.println(f[i++].area()); } } Métodos Programação II 15 Método ler(String, Forma[]) public static void ler(String a, Forma ff[]) { try { FileInputStream f = new FileInputStream(a); ObjectInputStream in = new ObjectInputStream(f); int i = 0; while( (ff[i++] = (Forma)in.readObject()) != null); f.close(); } catch(ClassNotFoundException e) { System.out.println("Classe do objecto lido nao existe !!"); } catch(FileNotFoundException e) { System.out.println("Nome do fx nao esta correcto!! "); } catch(IOException e) { System.out.println("Problemas de I/O ..."); } Métodos Programação II 16 Método grava(Forma, String) public static void grava(Forma a, String nome) { try { FileOutputStream file = new FileOutputStream(nome); ObjectOutputStream out = new ObjectOutputStream(file); out.writeObject(a); out.flush(); out.close(); } catch(FileNotFoundException e) { System.out.println("Nome do fx nao esta correcto!! "); } catch(IOException e) { System.out.println("Problemas de I/O ..."); } } Métodos Programação II 17 Exercícios • Escrever um método que regista num ficheiro texto informação sobre as Estufas, nomeadamente código, área, temperaturas mínimas e máximas, e o nome do tipo de estufa. • Escrever métodos para escrita e leitura da informação do estado das estufas. Ou seja, que garante que a informação do programa GereEstufas se preserva. • Introduzir no código dos métodos das classes tratamento de excepções. Nomeadamente no código respeitante à escrita/leitura das Streams, inserção de novas estufas, validação do valor da temperatura no método emRisco(int), etc. Métodos Programação II 18