O objetivo desse laboratório é exercitar o uso de exceções em Java. Use o material sobre exceções que está em nosso site para te ajudar. Não se esqueça de criar um projeto Eclipse para esse laboratório.
O uso e tratamento de exceções é ortogonal à
orientação a objetos (tirando o fato de que Java usa a posição da
exceção na hierarquia de exceções para determinar se ela está coberta
por uma cláusula catch
ou throws
), portanto
as questões abaixo não aplicam conceitos OO.
A primeira tarefa é escrever um programa que lê dois números
do teclado e mostra a divisão entre eles. Crie uma classe
Divide
com uma função public static void
main(String[] args)
. Essa função será chamada quando o programa
for executado.
1. A leitura de uma linha é feita através do
método readLine()
, da classe
java.io.BufferedReader
. O código para ler uma linha do
console é o seguinte:
BufferedReader ent = new BufferedReader(new InputStreamReader(System.in)); String linha = ent.readLine();
Para converter uma string em um número inteiro use a
função. Integer.parseInt
. Agora você pode implementar a
função main
de Divide
.
Repare que o
compilador vai reclamar do não tratamento de
IOException
. Essa é uma exceção checada,
então lembre que ela deve ser sempre tratada ou sinalizada com uma
cláusula throws
na assinatura. Conserte o código usando a
cláusula throws
. Execute o programa e teste algumas entradas.
2. O que acontece quando você passa um denominador de 0? Conserte o
seu programa para tratar a ArithmeticException
que
acontece nesse caso, imprimindo uma mensagem de erro para o usuário
ao invés do stack trace.
3. Faça um tratamento diferente da ArithmeticException
no programa acima; agora o programa deve reclamar e pedir outro
denominador. Esse segundo denominador também pode ser zero,
capture e trate essa segunda ArithmeticException
do jeito
que você fez no exercício 2.
4. O que acontece quando o usuário entra alguma coisa que não
é um número para no numerador ou o denominador? Trate
também este erro com outra cláusula catch
.
5. Fatore a leitura de um número do teclado para uma função
static int leNumero()
. Repare o que acontece com a
IOException
.
A principal utilidade de uma exceção é para sinalização e tratamento de erros, mas também podemos usar exceções para controle de fluxo que seria trabalhoso de maneira convencional. Vamos voltar ao nosso exemplo de formas geométricas em um programa de desenho. Baixe novamente o projeto Eclipse da quarta semana de aula e faça os exercícios abaixo:
1. Adicione um método boolean primitiva()
à interface Forma
que retorna false
se
essa é uma composição e true
se não for uma
composição.
2. Adicione um método Forma clicada(Coord
pos)
. A ideia desse método é retornar qual a
forma primitiva de uma composicao contém a coordenada
passada. Para as formas simples o método vai apenas retornar a
própria forma se ela contém a coordenada ou null
se não contém. Para uma composição ela deve retornar a forma
simples que contém aquela coordenada, ou null
se
nenhuma das formas da composição tem aquela coordenada. Implemente o
método usando os conceitos que você já sabe. Pense com
cuidado!
3. Agora vamos resolver o problema anterior de um modo diferente. A
assinatura de clicada
vai ser void clicada(Coord
pos)
. Para as formas simples ele não vai fazer nada se a forma
não contém pos
, mas se ela contém vai
sinalizar com uma exceção FormaEncontrada
, derivada de
RuntimeException
, contendo a própria forma. Implemente a
classe FormaEncontrada
, e a nova versão de
clicada
. Teste-a assim:
try { // c é uma composição complicada c.clicada(pos); // se chegou aqui é porque a busca falhou fail("forma não encontrada"); } catch(FormaEncontrada fe) { // f é a forma dentro de c que a gente está procurando Assert.assertEquals(f, fe.forma); }