Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Curso de java parte 1, Notas de estudo de Informática

- - - - - - -

Tipologia: Notas de estudo

Antes de 2010

Compartilhado em 20/01/2009

ana-suzuki-10
ana-suzuki-10 🇧🇷

4 documentos

1 / 16

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Curso de Java – Módulo I
Exceções, Entrada e Saída
Programação Swing
Fábio Mengue – [email protected]
Centro de Computação - Unicamp
Exceções
O termo exception é uma abreviatura da frase exceptional event”. Sua definição formal é
um evento que ocorre durante a execução de um programa que quebra o fluxo normal dessa
execução.
Vários eventos podem causar exceções. Desde problemas sérios com hardware (como um
crash de disco) até um erro simples de programação, como acessar um elemento de um vetor
com um índice inválido. Quando um erro desses tipos ocorrem em um método Java, o método
cria um objeto do tipo Exception e o envia para o sistema. Esse objeto contém informação sobre
o erro, incluindo seu tipo e o estado em que o programa se encontrava quando o erro aconteceu.
O sistema fica responsável por encontrar alguma maneira de lidar corretamente com o erro. Na
linguagem usada pelos programadores Java, dizemos que o sistema gerou uma exceção (em
inglês, throwed an exception).
Depois que o método gerou uma exceção, o sistema tenta encontrar algum código que
possa ser utilizado para lidar com a exceção. Os candidatos mais prováveis são os que
“chamaram” o método onde o erro aconteceu. Se eles não tiverem condições de lidar com o
erro, o sistema continua a seguir a pilha de chamadas, até encontrar o código apropriado. Por sua
vez, o código é considerado apropriado para lidar com uma exceção quando o tipo da exceção
gerada é o mesmo tipo para o qual ele foi programado. Ao ser encontrado o código correto, o
sistema o executa (em inglês, catch the exception).
Caso o sistema não consiga identificar um código correto para gerenciar a exceção, o
sistema (normalmente representado pelo programa Java) se encerra. Claro que é desnecessário
dizer que isso não é exatamente o que gostaríamos que acontecesse na maioria das vezes.
Pelo fato de utilizar exceções para gerenciar erros, os programas em java possuem
vantagens sobre as linguagens tradicionais. A primeira grande vangatem é poder separar o
gerenciamento de erros do código comum. Outra vantagem é a propagação de erros, que permite
que se crie uma classe especializada apenas no gerenciamento destes eventos. E por fim, é
possível agrupar erros por tipo, tratando-os de uma vez. Veremos exemplos para cada uma das
vantagens a seguir.
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Pré-visualização parcial do texto

Baixe Curso de java parte 1 e outras Notas de estudo em PDF para Informática, somente na Docsity!

Curso de Java – Módulo I

Exceções, Entrada e Saída

Programação Swing

Fábio Mengue – [email protected] Centro de Computação - Unicamp

Exceções

O termo exception é uma abreviatura da frase “ exceptional event”. Sua definição formal é um evento que ocorre durante a execução de um programa que quebra o fluxo normal dessa execução.

Vários eventos podem causar exceções. Desde problemas sérios com hardware (como um crash de disco) até um erro simples de programação, como acessar um elemento de um vetor com um índice inválido. Quando um erro desses tipos ocorrem em um método Java, o método cria um objeto do tipo Exception e o envia para o sistema. Esse objeto contém informação sobre o erro, incluindo seu tipo e o estado em que o programa se encontrava quando o erro aconteceu. O sistema fica responsável por encontrar alguma maneira de lidar corretamente com o erro. Na linguagem usada pelos programadores Java, dizemos que o sistema gerou uma exceção (em inglês, throwed an exception).

Depois que o método gerou uma exceção, o sistema tenta encontrar algum código que possa ser utilizado para lidar com a exceção. Os candidatos mais prováveis são os que “chamaram” o método onde o erro aconteceu. Se eles não tiverem condições de lidar com o erro, o sistema continua a seguir a pilha de chamadas, até encontrar o código apropriado. Por sua vez, o código é considerado apropriado para lidar com uma exceção quando o tipo da exceção gerada é o mesmo tipo para o qual ele foi programado. Ao ser encontrado o código correto, o sistema o executa (em inglês, catch the exception ).

Caso o sistema não consiga identificar um código correto para gerenciar a exceção, o sistema (normalmente representado pelo programa Java) se encerra. Claro que é desnecessário dizer que isso não é exatamente o que gostaríamos que acontecesse na maioria das vezes.

Pelo fato de utilizar exceções para gerenciar erros, os programas em java possuem vantagens sobre as linguagens tradicionais. A primeira grande vangatem é poder separar o gerenciamento de erros do código comum. Outra vantagem é a propagação de erros, que permite que se crie uma classe especializada apenas no gerenciamento destes eventos. E por fim, é possível agrupar erros por tipo, tratando-os de uma vez. Veremos exemplos para cada uma das vantagens a seguir.

Nas linguagens de programação tradicionais, a detecção de erros e seu tratamento normalmente causa uma certa confusão no código, pois tudo está misturado. Por exemplo, imagine que você tenha uma função que leia um arquivo do disco para a memória. Imagine que esse programa se parece com isso:

lerArquivo{ abrir o arquivo; determinar seu tamanho; alocar memória; ler o arquivo para a memória; fechar o arquivo; }

Parece muito simples. Mas o que acontece se:

O arquivo não puder ser aberto? For impossível determinar o tamanho do arquivo? Não for possível alocar a quantidade total de memória? A leitura falhar? O arquivo não puder ser fechado?

Então, criamos código a mais para detectar e lidar com esses possíveis erros. Assim, nosso programa agora ficaria assim:

lerArquivo { codigoErro=0; abrir arquivo; if (arquivoAberto) { determinar tamanho; if (tamanhoDeterminado) { alocar memória; if (memoriaAlocada) { ler o arquivo para a memória; if (leituraFalhou) { codigoErro=-1; } else { codigoErro=-2; } } else { codigoErro=-3; } fechar arquivo; if (arquivoNaoFechado) && codigoErro=0) { codigoErro=-4; }

implementados em sua classe. O metodo1 chama o metodo2, que chama metodo3, que finalmente chama lerArquivo.

metodo1 { call method2; } metodo2 { call method3; } metodo3 { call lerArquivo; }

Suponha que o código em metodo1 seja o único interessado nos erros que podem acontecer em lerArquivo. Se isso fosse ser implementado usando a notificação tradicional, metodo3 e metodo2 deveriam ter maneiras de propagar códigos de erro eventualmente retornados por lerArquivo para os métodos que os invocaram, até chegar a metodo1.

metodo1 { errorCodeType error; error = call metodo2; if (error) doErrorProcessing; else proceed; } errorCodeType metodo2 { errorCodeType error; error = call metodo3; if (error) return error; else proceed; } errorCodeType metodo3 { errorCodeType error; error = call lerArquivo; if (error) return error; else proceed; }

Como já visto, o sistema Java irá procurar automaticamente um código adequado para o gerenciamento de erros. Usamos então uma palavra que indica que qualquer exceção ocorrida (e não tratada) deve ter propagada para a classe que “chamou” a classe corrente. Veja o exemplo:

metodo1 { try { call metodo2; } catch (Exception) { doErrorProcessing; } } metodo2 throws Exception { call metodo3; } metodo3 throws Exception { call lerArquivo; }

Entretanto, como pode ser visto no código, o envio das exceções exige um certo esforço dos métodos intermediários, que também necessitam repassar a exceção com throws até o método correto. Mesmo assim, essa técnica obviamente é mais vantajosa que a tradicional, no sentido que evita confusão no código.

A última mas não menos importante vantagem é que as exceções são agrupadas. Por exemplo, imagine um grupo de exceções. Todas elas dizem respeito a erros que podem ocorrer quando se manipula um vetor. Exceção para estouro do vetor, para inclusão de tipo inválido, ou mesmo para quando o elemento procurado não faz parte do vetor. Cada uma dessas exceções pode ser tratada de maneira independente, ou você pode ter um método que trate todas as exceções deste grupo, tornando a coisa mais simples.

Pelo fato das exceções serem classes Java como qualquer outra, a hierarquia presente em todas as classes Java também está presente aqui. Todas elas são instâncias ou descendentes da classe Throwable. Cada “folha” da árvore que se inicia em Throwable representa uma exceção específica, e cada “tronco” representa um grupo relacionado de exceções.

Por exemplo, ArrayException é uma subclasse de Exception (por sua vez, uma subclasse de Throwable ), e possui 3 subclasses: InvalidIndexException, ElementTypeException, NoSuchElementException. Cada uma delas representa um erro específico, que pode ocorrer na manipulação de um vetor. Uma maneira de lidar com as exceções é uma a uma:

catch (InvalidIndexException e) {

... } Outra maneira seria tratando a exceção de acordo com o grupo ao qual ela pertence. Isso pode ser feito por vários motivos, o mais forte deles é manter a simpliciadade. No nosso exemplo, temos ArrayException , que representa qualquer erro que pode acontecer com a

do { c = in.read(); if (Character.isWhitespace((char)c)) return buf.toString(); else buf.append((char)c); } while (c != -1);

return buf.toString(); } }

O compilador apresenta o erro na linha 8 (in = new FileReader(filename);). Essa instrução cria um objeto FileReader, usado para abrir um arquivo cujo nome é passado como parâmetro.

O que acontece se o arquivo não existir no disco? Os profissionais que desenharam a classe FileReader não tinham a menor idéia do que o programador gostaria que acontecesse caso o arquivo não existisse. O programa deve terminar? Um nome de arquivo diferente deve ser testado? O arquivo deve ser criado? Não existe jeito de saber o que o programador que está utilizando o FileReader gostaria que acontecesse nessa situação. Assim, eles geram uma exceção (do tipo java.io.FileNotFoundException). Assim, o método que chamou a instrução decide a maneira apropriada de tratar do assunto.

No nosso exemplo, pode se ver que o programa ignora o fato de que FileReader pode gerar uma exceção. Mas o compilador Java não deixa que o fato passe em branco, se recusando a compilar o programa e gerando uma mensagem de erro que alerta o programador a respeito.

Além da mensagem vista acima, outra mensagem deve ser gerada:

InputFile.java:15: Warning: Exception java.io.IOException must be caught, or it must be declared in throws clause of this method. while ((c = in.read()) != -1) { ^ Agora, o problema está no objeto in, que da classe FileReader. O método read() também pode gerar uma exceção, desta vez caso algum problema aconteça na leitura. Por exemplo, se as permissões do arquivo não estejam configuradas de modo que esse programa possa ler seus dados. A exceção gerada pode esse método é java.io.IOException.

Nesse ponto, você tem duas opções. Ou pode criar o código para capturar as exceções dentro do programa InputFile ou propaga-las para outros métodos mais acima na pilha de execução. De qualquer maneira, o programa InputFile deve fazer alguma coisa. E para fazer isso existe uma maneira correta.

O Bloco try

O primeiro passo para construir um programa capaz de gerenciar exceções é colocar os comandos que podem gerar exceções dentro de um mesmo contexto, usando a palavra reservada try :

try { Comandos... }

Você pode colocar cada um dos comandos em um contexto próprio, ou pode colocar todos os comandos que podem gerar exceção em apenas um contexto e depois programar (separadamente) o código que irá lidar com cada uma das exceções.

Por exemplo:

PrintWriter out = null; try { out = new PrintWriter( new FileWriter("OutFile.txt"));

for (int i = 0; i < size; i++) out.println("Value at: " + i + " = " + victor.elementAt(i)); }

O bloco try neste programa delimita o escopo sobre o qual o código de tratamento de erros irá atuar. Nesse pedaço de código existem duas instruções que podem gerar exceções; você consegue identifica-las?

Uma instrução try deve ser acompanha de pelo menos um bloco catch.

O Bloco catch

A instrução catch define qual o código que irá ser executado, dependendo da exceção gerada. Você os associa aos blocos definidos pelo try colocando-os logo após o bloco:

try {

... } catch (... ) { ... } catch (... ) { ... }...

Não se deve ter nenhuma outra instrução entre o final do contexto do try e o início do catch.

Assim, podemos reescrever nosso exemplo de modo que apenas um bloco catch pode lidar com todas as exceções:

try {

... } catch (Exception e) { System.err.println("Exception caught: " + e.getMessage()); }

A classe Exception é a mais alta na hierarquia Throwable. Assim, qualquer exceção que ocorrer será tratada por esse bloco. A idéia em si é que ele basta para tratar de erros gerais, mas é um tanto inútil para um tratamento adequado, perdendo um pouco da vantagem de tratamento que o Java fornece.

Finalmente, temos o bloco finally.

O Bloco finally

Todo try deve ter pelo menos um catch. Existe mais um bloco de código que pode ser definido, mas ele não é obrigatório. Ele existe para que se possa realizar certas atividades que devem ser feitas independentemente do curso de execução ter gerado exceções ou não. Um exemplo é fechar um arquivo ou conexão com o banco de dados.

Lembremos novamente de nosso exemplo da página 8. Três casos ocorrer.

  1. O FileWriter falha e lança uma IOException.
  2. O victor.elementAt(i) falha e lança uma ArrayIndexOutOfBoundsException.
  3. Tudo dá certo, e nenhuma exceção é gerada.

Certas instruções devem ser executadas para qualquer um dos casos. O bloco finally serve justamente para isso. Suas instruções serão executadas sempre, com exceções ou sem elas. Sua definição permite que eliminemos código duplicado e facilita o encerramento de uma rotina.

Exercícios:

  1. O código abaixo é válido?

try { ... } finally { ... }

2.Quais as exceções que serão capturadas pelo bloco abaixo?

catch (Exception e) { ... }

Cite uma desvantagem de usar esse tipo de classe de exceção.

3.Quais as exceções que serão capturadas pelo bloco abaixo?

} catch (Exception e) { ... } catch (ArithmeticException a) { ... }

Há alguma coisa errada com esses blocos? O código compila?

Os streams para leitura de bytes lidam com palavras de 8 bits, e são subclasses de java.io.InputStream e java.io.OutputStream.

Os streams mais fáceis de entender são os relacionados a arquivos. Segue um exemplo de programa que copia um arquivo de um stream para outro.

import java.io.*;

public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("entrada.txt");

File outputFile = new File("saida.txt");

FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c;

while ((c = in.read()) != -1) out.write(c);

in.close(); out.close(); } }

Como podemos ver, o programa é muito simples. Ele abre um FileReader no arquivo entrada.txt e abre um FileWriter no arquivo saida.txt. O programa lê caracteres enquanto houver no stream de entrada e os escreve no stream de saída. Quando terminar, ele fecha ambos os streams.

O assunto é um tanto extenso, e esse curso se propõe a passar apenas a idéia básica sobre o assunto. Temos capacidade de gerar ou ler streams com arquivos zipados, serializar objetos (artifício utilizado para comunicação remota) e mesmo acessar arquivos de maneira não sequencial.

Introducao ao Swing

O pacote Swing é parte da JavaTM Foundation Classes (JFC) na plataforma Java. Existe na linguagem como pacote de extensão desde a versão 1.1, e serve basicamente para auxiliar as pessoas a construirem GUI's (Guided User Interface). O Swing fornece todos os componentes básicos, de botões a tabelas.

Seu primeiro Swing

A maneira mais fácil de ensinar a utilizar o Swing mostrando código. Vamos a um programa bem simples, que exibe “Alo Mundo”.

import javax.swing.*;

public class HelloWorldSwing { public static void main(String[] args) { JFrame frame = new JFrame("HelloWorldSwing"); final JLabel label = new JLabel("Hello World"); frame.getContentPane().add(label);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack();

Notas sobre o Swing:

Para aparecer na tela, todos os componentes devem ser adicionados e estarem presentes em alguma parte de hierarquia, que se inicia na raiz ( JFrame, JDialog ou JApplet).

Todos os componentes raiz possuem um content pane , que contém a parte visível do que estamos montando, como mostrado na figura abaixo:

Opcionalmente, você pode adicionar um menu a um componente raiz. O menu é posicionado diretamente na raiz, fora do content pane.

Bibliografia

The Java Tutorial – http://www.sun.com/docs Core Java – Horstmann, Cay S., Cornell, Gary. Makron Books

Proibida a alteração, reprodução e cópia de parte deste material para qualquer finalidade sem a permissão do Centro de Computação da Unicamp.

A utilização deste material é permitida desde que conste a autoria do mesmo.

 2002 Centro de Computação da Unicamp.