Você está na página 1de 233

J AVA

francisco calaça
otávio calaça

Guia para iniciantes


2013 – Versão 1.1
LICENÇA

Esta apostila é disponibilizada sob os termos da licença Creative Commons - Attribution-


NonCommercial-NoDerivs 3.0 Unported.
Isto quer dizer que VOCÊ PODE:

• Copiar este material de forma não comercial;

• Redistribuir este material de forma não comercial;

• Imprimir este material de forma não comercial;

Esta licença também quer dizer que você VOCÊ NÃO PODE:

• Vender este material a terceiros;

• Alterar este material;

Qualquer uso indevido deste material, venda ou alteração estarão sugeitos às penas pre-
vistas na Lei Federal No 9.610, de 19 de fevereiro 1998.
Mais detalhes sobre esta licença bem como seu conteúdo original pode ser acessado em:
http://creativecommons.org/licenses/by-nc-nd/3.0/legalcode

Bons estudos. . .

iii
C O L A B O R E C O M E S TA A P O S T I L A

Precisamos de colaboradores para melhorar esta apostila. Se você deseja entrar para nosso
time, mande um email para chicocx@gmail.com com o título:

DESEJO COLABORAR COM A APOSTILA DE JAVA.

Responderemos a você com informações sobre o que ainda é necessário fazer.


Nas próximas versões, você verá seu nome adicionado na lista de colaboradores e poderá
se gabar, mostrando isto ao seus amigos. Colabore !

Colaboradores
• Francisco Calaça Xavier

• Otávio Calaça Xavier

• Edicarlos Pimenta Gonçalves

v
CONTEÚDO
1 introdução 1
1.1 Algoritmos 1
1.2 Lógica binária 1
1.3 Nascimento da ciência da computação 2
1.4 Java 2
2 preparação do ambiente de estudos 5
2.1 Padronização do ambiente de trabalho 5
2.2 Primeiros testes no ambiente de trabalho 6
2.3 Exercícios 7
3 lógica de programação em java 9
3.1 Fluxograma 9
3.2 Para entender os programas criados a partir de agora 10
3.2.1 Informações iniciais 10
3.3 Strings 11
3.4 Saída Formatada 12
3.5 Conceito de Variável 13
3.6 Palavras reservadas e identificadores 14
3.7 Tipos Primitivos 15
3.7.1 Tipos primitivos inteiros 15
3.7.2 Tipos primitivos de ponto flutuante 15
3.7.3 Tipo primitivo char 16
3.7.4 Tipo primitivo boolean 16
3.7.5 Conversões de variáveis 17
3.8 Operadores 17
3.8.1 Aritméticos 17
3.8.2 Atribuição 18
3.8.3 Incremento/Decremento 19
3.8.4 Relacionais 20
3.8.5 Lógicos 20
3.9 Estruturas de seleção 21
3.9.1 if . . . else 22
3.9.2 Operador condicional ou ternário 23
3.9.3 switch 24
3.10 Estruturas de Repetição 26
3.10.1 for 26
3.10.2 while 27
3.10.3 do . . . while 27
3.11 Exercícios 28
4 introdução à orientação a objetos 29
4.1 O conceitos Classe e Objeto 29
4.2 Elementos de uma classe 30

vii
4.2.1 Atributos 30 Versão 1.1 conteúdo
4.2.2 Métodos 31
4.2.3 Métodos construtores 32
4.2.4 Padrões de nomenclatura 33
4.3 Atributos e métodos static 34
4.3.1 Import static 35
4.4 Tipos Wrapper 36
4.4.1 Auto-boxing e Auto-unboxing 36
4.5 Regras de escopo 37
4.6 Sobrecarga de métodos 38
4.7 Exercícios 39
5 arrays 41
5.1 O que são arrays 41
5.2 Declaração e inicialização de arrays 42
5.3 Método main 44
5.4 Laço for aprimorado 46
5.5 Passagem de parâmetros no Java 46
5.6 Arrays multidimensionais 49
5.7 Lista de parâmetros com comprimento variável 49
5.8 Exercícios 50
6 um pouco mais de orientação a objetos 51
6.1 Coletor de lixo 51
6.2 A palavra-chave this 52
6.3 Variáveis do tipo final 54
6.4 Encapsulamento 54
6.5 Enumerações 57
6.6 Pacotes 57
6.6.1 Como usar tipos dentro de outros pacotes 59
6.7 Herança 60
6.7.1 Um exemplo de Herança 60
6.7.2 Sobrescrita de métodos 62
6.7.3 A palavra-chave super 62
6.8 Alguns Modificadores de acesso 62
6.8.1 private 62
6.8.2 pacote 62
6.8.3 protected 63
6.8.4 public 63
6.9 Classe object 63
6.9.1 método equals() 63
6.9.2 método toString() 64
6.10 Polimorfismo 65
6.10.1 Abstração 65
6.10.2 Exemplo de Polimorfismo 66
6.11 Conversão e casting 69
6.11.1 A palavra-chave instanceof 70
6.12 Métodos e classe do tipo final 70

viii http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 conteúdo

6.13 Interfaces 71
6.13.1 Interfaces em Java 71
6.14 Exercícios 73
7 tratamento de exceções 75
7.1 O que são exceções 75
7.2 Como tratar exceções 75
7.2.1 O bloco try 75
7.2.2 O bloco catch 76
7.3 Exceções checadas e exceções não checadas 78
7.4 Como declarar novos tipos de exceções 78
7.5 Como lançar exceções 79
7.6 Hierarquia das exceções 80
7.7 Exercícios 81
8 fluxo de dados 83
8.1 A classe File 83
8.2 Como escrever em arquivos 83
8.3 Como ler arquivos 84
8.4 Um editor de texto simples 85
8.5 Serialização de objetos 87
8.6 Um trocador de mensagens simples 88
8.7 Exercícios 91
9 genéricos e coleções 93
9.1 o que são genéricos 93
9.2 Introdução a coleções 95
9.3 Listas 95
9.4 Conjuntos 97
9.5 Mapas 97
9.5.1 Properties 99
9.6 Pilhas 101
9.7 Filas 102
9.8 Ordenação de Listas 102
9.9 Exercícios 104
10 uml: unified modeling language 107
10.1 Diagrama de Classe 107
10.1.1 Classe 107
10.1.2 Associações de Classe 108
10.2 Diagrama de Caso de Uso 110
10.2.1 Caso de Uso 110
10.2.2 Ator 111
10.2.3 Descrição do Caso de Uso 111
10.3 Demais diagramas 111
11 threads 113
11.1 Processos e Threads 113
11.1.1 Processos 113
11.1.2 Threads 113
11.2 Criação de Threads 114

http://solutioin.com ix
Francisco Calaça, Otávio Calaça
Versão 1.1 conteúdo

11.3 A classe Executors 115


11.4 Métodos sleep e yield 116
11.5 Sincronização 116
11.6 O verificador de primos 119
11.7 Exercícios 121
12 strings e datas 123
12.1 As classes Date e Calendar 123
12.2 Formatação de Datas 124
12.3 A classe String 125
12.4 A classe StringBuffer 125
12.5 Saída formatada 126
12.5.1 Caracteres de conversão 126
12.6 Exercícios 128
13 jdbc 131
13.1 Conexão com banco de dados 131
13.2 A linguagem SQL 133
13.2.1 SELECT 133
13.2.2 Cláusula WHERE 133
13.2.3 O Operador LIKE 133
13.2.4 INSERT 134
13.2.5 UPDATE 134
13.2.6 DELETE 134
13.3 Como executar instruções SQL e obter registros 134
13.3.1 PreparedStatement 136
13.4 Execução em Lote 136
13.5 Tabela de Clientes 138
13.6 Exercícios 141
14 java persistence api com hibernate 143
14.1 Mapeamento objeto relacional 143
14.2 Configurações iniciais 143
14.3 A criação do primeiro exemplo 144
14.4 O arquivo persistence.xml 146
14.5 O EntityManager 148
14.6 A inclusão de clientes com JPA 149
14.6.1 Persistindo entidades 149
14.6.2 Localizando entidades 150
14.6.3 Removendo entidades 150
14.6.4 Mesclando entidades 150
14.7 Relacionamento entre classes 150
14.8 Formas de obtenção de id’s 153
14.9 JPQL - A linguagem consulta da Jpa 154
14.9.1 Passagem de parâmetros 154
14.10Exercícios 155
15 aplicativos web 157
15.1 XML 157
15.2 HTML 158

x http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 conteúdo

15.2.1 A estrutura básica de um documento HTML 158


15.2.2 Outras tags HTML 159
15.3 JavaScript 160
15.4 CSS 161
15.5 Aplicativos Web com Java 163
15.5.1 Instalação do Tomcat 163
15.6 Exercícios 164
16 servlets 165
16.1 Estrutura de uma aplicação web Java 165
16.2 Construindo o primeiro Servlet 165
16.3 Como fazer no eclipse 167
16.4 Atendendo requisições com o método get 168
16.5 Atendendo requisições com o método post 174
16.6 Redirect 175
16.7 Forward 177
16.8 Escopo de objetos web 178
16.8.1 Request 178
16.8.2 Session 179
16.8.3 Application 179
16.9 Como distribuir uma aplicação web 179
16.10Exercícios 180
17 java server pages 181
17.1 Elementos do Jsp 181
17.1.1 Scriptlet 181
17.1.2 Expressões 182
17.1.3 Declarações 183
17.2 Diretivas 183
17.2.1 Diretiva include 183
17.2.2 Diretiva Page 184
17.3 Ações do JSP 186
17.4 Biblioteca de tags JSTL 186
17.4.1 EL - Expressão de Linguagem 187
17.5 MVC - Model View Control 188
17.5.1 O cadastro de clientes 188
17.6 Exercícios 190
18 introdução ao javaserver faces 191
18.1 Fazendo JavaServer Faces funcionar 191
18.2 Managed bean 191
18.3 Tags básicas 195
18.3.1 Tags JSF para renderização de HTML 195
18.3.2 Tags Core do JSF 195
18.3.3 Exemplo de uso das Tags 195
18.4 Expressões de Ligação - EL 197
18.4.1 Ligações com atributos 198
18.4.2 Ligações com métodos 198
18.5 Configurar o Primefaces 199

http://solutioin.com xi
Francisco Calaça, Otávio Calaça
Versão 1.1 conteúdo

18.6 Cadastro de Clientes 200


18.7 Cadastro de Produtos (com JPA) 203
18.8 Conversores 210
18.8.1 Conversores personalizados 210
18.9 Exercícios 213
19 padrões de projeto 215
19.1 Padrões GoF 215
19.2 Abstract Factory 216
19.2.1 Utilização 217
19.3 Factory Method 217
19.3.1 Utilização 217
19.3.2 Command 218
19.3.3 Problema 218
19.3.4 Aplicação 219
19.4 Data Access Object (DAO) 219
19.4.1 Vantagens 219
19.5 MVC 220
19.5.1 Componentes 220
19.5.2 Justificativa 220
a montagem do ambiente de trabalho 221
a.1 Obtenção e instalação do JDK 221
a.2 O que é a Máquina virtual Java 221
a.3 Obtenção e instalação do eclipse 221

xii http://solutioin.com
Francisco Calaça, Otávio Calaça
INTRODUÇÃO
1
A computação pode ser definida como a busca de uma solução para um problema, a partir
de entradas (inputs), e através de um algoritmo. É com isto que lida a teoria da computação,
subcampo da ciência da computação e da matemática. Durante milhares de anos, a com-
putação foi executada com caneta e papel, ou com giz e ardósia, ou mentalmente, por vezes
com o auxílio de tabelas, ou utensílios artesanais.
A primeira ferramenta conhecida para a computação foi o ábaco, inventado na Mesopotâmia
em torno de 2400 a.C. Sua versão original era consistia em desenhar linhas na areia com
rochas. Os ábaco ainda são usadas como instrumento de cálculo hoje.

1.1. Algoritmos
O matemático indiano Brahmagupta explicou pela primeira vez no século VII, o sistema
de numeração hindu-arábico. Nesta época aparecem os relatos de uso do 0. Por volta de
820, o matemático persa Al-Khwarizmi escreveu o livro Calculando com Numerais Hindus.
Este matemático foi responsável pela difusão do sistema de numeração hindu-arábico no
Oriente Médio, e posteriormente na Europa. No século XII começaram traduzir este livro
para o latim: Algoritmi de numero Indorum. Tais livros apresentaram novos conceitos
para definir sequências de passos para completar tarefas (definição de algorítimos), como
aplicações de aritmética e álgebra. Por derivação do nome, atualmente usa-se o termo
algorítmo.

1.2. Lógica binária


O matemático indiano Pingala inventou o sistema de numeração binário por volta do século
III a.C. Este sistema de numeração ainda é utilizado atualmente no processamento de to-
dos computadores, o sistema estabelece que sequências de uns e zeros podem representar
qualquer número. Fisicamente estas sequências são substituidas pelos estados ligado e
desligado.
George Boole, em 1854 publicou a álgebra booleana com um sistema completo que per-
mitia a construção de modelos matemáticos para o processamento computacional. Em 1801
apareceu o tear controlado por cartão perfurado, invenção de Joseph Marie Jacquard. Neste
tear os buracos indicavam os uns, e áreas não furadas indicavam os zeros. O sistema ainda
não pode ser considerado um computador, mas demonstrou que as máquinas poderiam
ser controladas pelo sistema binário.

1
Versão 1.1 introdução

1.3. Nascimento da ciência da computação


Antes da década de 1920, computador era um termo associado a pessoas que realizavam
cálculos, geralmente físicos e matemáticos. Milhares de computadores, em sua maioria mul-
heres, eram empregados em projetos no comércio, governo e pesquisa. Após a década de
1920, a expressão máquina computacional começou a ser usada para referir-se a qualquer
máquina que realize o trabalho de um profissional computador.
No final da década de 1940 o termo máquina computacional perdeu espaço para o termo
computador. As máquinas digitais estavam cada vez mais difundidas. Alan Turing, um dos
pioneiros da Ciência da Computação, inventou a Máquina de Turing, que posteriormente
evoluiu para o computador moderno.
Em 1930 os engenheiros eletricistas já podiam construir circuitos eletrônicos para resolver
problemas lógicos e matemáticos, mas a maioria o fazia sem qualquer processo, de forma
particular, sem rigor teórico, ou qualquer estudo ou padronização. Isso mudou com a tese
de mestrado de Claude E. Shannon de 1937, A Symbolic Analysis of Relay and Switching
Circuits. Enquanto tomava aulas de Filosofia, Shannon foi exposto ao trabalho de George
Boole, e percebeu que tal conceito poderia ser aplicado em conjuntos eletro-mecânicos para
resolver problemas de lógica. Tal idéia, que utiliza propriedades de circuitos eletrônicos
para a lógica, é o conceito básico de todos os computadores digitais. Shannon desenvolveu
a teoria da informação no artigo de 1948 A Mathematical Theory of Communication, cujo
conteúdo serve como fundamento para áreas de estudo como compressão de dados e crip-
tografia.

1.4. Java
A linguagem de programação orientada a objetos Java foi criada em 1991 pelo engenheiro
James Gosling, da Sun, e anunciada em 1995. O projeto da sua criação surgiu num contexto
de um outro projeto, em que certos problemas da linguagem C++, como, por exemplo, a
falta de funcionalidades do ’garbage collection’, levaram a optar pela criação de uma nova
linguagem, então denominada Oak (palavra inglesa para as árvores da família Quercus,
como o carvalho) em "homenagem" à árvore que se encontrava plantada do lado de fora
do escritório de James Gosling.
Em 1994 esta linguagem foi renomeada para Java porque, após uma pesquisa de marcas,
foi descoberta que já existia uma linguagem de computador denominada Oak. Desta forma,
em 1996 o Java 1.0 foi finalmente apresentado à comunidade.
Em 2009, a Oracle adquire a Sun Microsystems e tornou-se a detentora dos direitos e da
marca Java.
As especificações da linguagem Java são mantidas uniformes através de um processo
comunitário gerido pela Sun Microsystems, o JCP (Java Community Process). Fazem parte
do JCP várias empresas como a Oracle, Google, IBM, Nokia dentre outras. Para mais infor-
mações sobre o JCP acesse o site http://jcp.org.
As características principais da linguagem Java são:

• é orientada a objetos;

2 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução

• é independente de plataforma;

• integra mecanismos e bibliotecas de funções para programação distribuída;

• foi projetada para executar código remotamente sem perda de segurança.

http://solutioin.com 3
Francisco Calaça, Otávio Calaça
P R E PA R A Ç Ã O D O A M B I E N T E D E
2
ESTUDOS

Neste capítulo você montrará seu ambiente de estudos Java. A sua principal ferramenta é
o JDK (Java Development Kit). Esta sigla significa: “Kit de Desenvolvimento Java”. O JDK
contém uma vasta quantidade de aplicativos necessários para resolver problemas do dia a
dia do desenvolvimento Java.
Outra ferramenta importante é a IDE (Integrated Development Environment). Esta sigla
significa: “Ambiente de desenvolvimento integrado”. Trata-se de uma ferramenta que con-
tém vários recursos, necessários para a construção eficiente de um software.
Hoje é possível encontrar diversas IDE’s para desenvolvimento em Java. Dentre elas
estão o Eclipse1 e o NetBeans2 , que são ide’s Open Source e que contam com colabração de
grandes comunidades e empresas ao redor do mundo. Os exemplos deste livro serão feitos
utilizando o Eclipse. Apesar disto, nada impede você de instalar o netbeans e também testar
estes exemplos nele.

2.1. Padronização do ambiente de trabalho


É muito importante ter um ambiente de trabalho organizado e padronizado para prossegui-
mento dos estudos. Esta padronização te ajudará a encontrar dependências, aplicativos e
exemplos e está ilustrada na Figura 2.1.
Onde em:

• Aplicativos: contém os aplicativos utilizados no desenvolvimento de software. Exem-


plo: JDK, eclipse, etc.

• Material: contém bibliotecas, tutoriais, etc

• Projetos: contém os seus projetos criados no decorrer da sua aprendizagem.

1 http://www.eclipse.org
2 http://www.netbeans.org

Figura 2.1: Padronização do ambiente de trabalho utilizada

5
Versão 1.1 preparação do ambiente de estudos

Se você quiser, pode baixar um arquivo compactado contendo esta estrutura já montada.
Este arquivo pode ser obtido no site http://solutioin.com/java. Após ter realizado o download
no seu computador, descompacte o arquivo em algum lugar de sua preferência e pronto!
Você já está apto para começar os estudos em Java. Bons estudos!

Dica:
Se você ficou curioso em como este ambiente foi montado, acesse o
Apêncie A que saberá como.

2.2. Primeiros testes no ambiente de trabalho


Primeiro, inicialize o eclipse. Isto pode ser feito executando o programa eclipse (Linux) ou
eclipse.exe (Windows) da pasta eclipse, dentro da pasta Aplicativos da estrutura baixada.
Com o eclipse inicializado, crie um novo projeto Java. Depois crie uma classe. Será a
primeira classe criada neste curso. O objetivo é que você entenda como funciona um pro-
grama bem simples em Java. O código deste exemplo inicial está apresentado na Listagem
2.1. Esta classe, após executada, gera a saída no console:

Veja como é fácil

Listagem 2.1: Exemplo do primeiro Programa


1 public class PrimeiroPrograma {
2 public static void main(String[] args) {
3 System.out.println("Veja como é fácil");
4 }
5 }

No momento, não se preocupe com as instruções desta classe. O que você deve entender
agora é que o comando da linha 3 imprime no console o texto que se encontra entre aspas.
Outra forma de apresentar texto para o usuário está ilustrada no código da Listagem
2.2. Observe, que após executar este código, a mensagem é apresentada em uma janela,
conforme ilustrado na Figura 2.2.

Listagem 2.2: Exemplo de apresentação de mensagem


1 import javax.swing.JOptionPane;
2

3 public class SegundoPrograma {


4 public static void main(String[] args) {
5 JOptionPane.showMessageDialog(null, "Olá , como vai ?");
6 }
7 }

Para um terceiro exemplo, será apresentado um código que faz a leitura de informações
teclado. Isto será bastante útil nesta primeira fase do curso, onde estamos estudando os
elementos iniciais da programação. A Listagem 2.3 exemplifica uma das formas de se obter
informações do usuário.

6 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 preparação do ambiente de estudos

Figura 2.2: Saída apresentada pelo segundo programa

Listagem 2.3: Exemplo de apresentação de mensagem


1 import javax.swing.JOptionPane;
2

3 public class TerceiroPrograma {


4 public static void main(String[] args) {
5 String texto = JOptionPane.showInputDialog("Digite um texto:");
6 System.out.println("Texto digitado: " + texto);
7 }
8 }

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

2.3. Exercícios
1. Crie uma classe que apresente no console a seguinte mensagem: “Meu primeiro
código Java”.

2. Crie uma classe que apresente em uma janela a mensagem: “Estou ficando bom
nisto”.

3. Crie uma classe que solicite ao usuário as seguintes informações: nome, endereço e
telefone. Após o usuário ter digitado estas informações, apresente em uma janela.

http://solutioin.com 7
Francisco Calaça, Otávio Calaça
L Ó G I C A D E P R O G R A M A Ç Ã O E M J AVA
3
Todo programa é constituído por uma sequência lógica de passos que executará tarefas
necessárias para a solução do problema a que o programa se propõem.
Neste capítulo, serão apresentados os passos necessários para construção de um pro-
grama simples em Java.

3.1. Fluxograma
Fluxograma é uma representação esquemática do processo. Ilustra graficamente a transição
de informações ao longo da execução deste processo.
É útil para compreensão de controle de fluxo quando o algoritmo é complexo ou extenso.
A Figura 3.1 ilustra um fluxograma. Observe que cada ação é representada por um retân-
gulo. O losango representa uma tomada de decisão. As elípses representam o início e o fim
do processo.

Figura 3.1: Exemplo de fluxograma

9
Versão 1.1 lógica de programação em java

3.2. Para entender os programas criados a par-


tir de agora
3.2.1 Informações iniciais
Para que haja um completo entendimento inicial nos programas que faremos neste capítulo,
é importante apresentar alguns conceitos.

3.2.1.1 Pacote java.lang


Não é necessário importar o pacote java.lang, ou seja, todas as classes deste pacote estão
acessíveis sem a necessidade de que seja feito qualquer import. Algumas destas classes são:
System, String, Integer, Double, Character, etc.

3.2.1.2 Nomeclatura dos métodos e das classes


Java utiliza um padrão de escrita chamado CamelCase1 .

• nomes de classes iniciam com letras maiúsculas e o restante das letras são minúsculas.
Exemplo: PrimeiraClasse, PessoaFisica, etc.

• nomes de métodos iniciam com letras minúsculas. Uma nova palavra no nome inicia
com letra maiúscula (sem o caracter sublinhado _). Exemplo: realizarAcao(), fazer-
Algo(), etc.

3.2.1.3 Método main


Todo aplicativo Java inicia sua execução pelo método main. A única forma de escrever esta
assinatura é:

public static void main(String [] args)

O significado de cada uma destas palavras será descrito posteriormente. É necessário que
o leitor apenas utilize esta assinatura como está.

3.2.1.4 Case sensitive


Em Java existe diferença entre letras maiúsculas e minúsculas. Assim, os identificadores
teste, Teste e TesTe são todos diferentes.

1 CamelCase é a denominação em inglês para a prática de escrever palavras compostas ou frases, onde cada
palavra é iniciada com Maiúsculas e unidas sem espaços. É um padrão largamente utilizado em diversas
linguagens de programação, como Java, Ruby, PHP e Python, principalmente nas definições de Classes e Ob-
jetos. Exemplo: iPod, GameCube, OpenOffice.org, CamelCase, dataNascimento, enderecoEntregaMercadoria,
ItemPedido.

10 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

3.2.1.5 Nome da classe é o nome do arquivo


Todo código Java deve ser escrito dentro de classes. O nome da classe deve ser o mesmo
nome do arquivo. Isto não é uma regra, mas evitará alguns problemas. Posteriormente será
apresentado mais detalhes sobre este assunto.

3.2.1.6 Outras observações


Após cada instrução deve ser colocado um ponto-vírgula (;).
Em Java as funções são chamadas de métodos. As variáveis declaradas fora dos métodos
são chamadas de atributos ou variáveis de classe.

3.2.1.7 Comentários
Existem três tipos de comentários em Java, conforme apresentado na Listagem 3.1.

Listagem 3.1: Exemplo de comentários


1 //Comentário de linha
2

4 /*
5 * Comentário
6 * de
7 * bloco
8 */
9

10

11 /**
12 * Exemplo de comentário
13 * de Javadoc.
14 *
15 */

3.3. Strings
Strings são cadeias de caracteres. Em java são representadas pela classe String e são expres-
sas entre aspas. Strings literais como “abcdef” também são instâncias desta classe.
É possível utilizar o operador + para concatenação de Strings:
‘‘Primeira String ’’ + ‘‘Segunda String’’

resulta em:
‘‘Primeira String Segunda String’’

Existem alguns caracteres que necessitam de alguns truques para serem expressos em
Strings. Eles estão descritos na tablela da figura 3.2.
A listagem 3.2 apresenta mais exemplos de sequências de escape. A saída deste exemplo
é:

http://solutioin.com 11
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Figura 3.2: Caracteres especiais e sua forma de representação em Strings

Como colocar "aspas" na String.


Exemplo
de
tabulação
c:\diretorio\arquivo

Observe que, para imprimir apenas uma barra, utiliza-se duas.

Listagem 3.2: Exemplos de sequência de escape


1

2 public class ExemploSequenciaEscape {


3

4 public static void main(String[] args) {


5 System.out.println("Como colocar \"aspas\" na String.");
6 System.out.println("Exemplo\n\tde\n\t\ttabulação");
7 System.out.println("c:\\ diretorio \\ arquivo");
8 }
9

10 }

3.4. Saída Formatada


O Java possui o recurso de saída formatada. Com este recurso é possível definir uma String
de formatação e após isto, passar parâmetros para a mesma. Isto evita concatenação ex-
cessiva de String e aumenta a legibilidade do código. A utilização destes caracteres está
descrita na Tabela 12.1. Para cada caractere de conversão existe um parâmetro que será
colocado no seu lugar:

("O aluno %s foi %s", "Marcos", "aprovado")

Neste caso palavra “Marcos” será colocada no lugar do primeiro %s e a palavra “aprovado”
será colocada no lugar do segundo %s resultando no seguinte:

"O aluno Marcos foi aprovado"

A listagem 12.4 apresenta exemplos de saída formatada.

12 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Caracter Aplicado em
%s String
%d Inteiro
%f Ponto flutuante

Tabela 3.1: Caracteres de conversão utilizados na saída formatada

Listagem 3.3: Saída formatada


1 import javax.swing.JOptionPane;
2

4 public class ExemploSaidaFormatada {


5

6 public static void main(String[] args) {


7 String nome = JOptionPane.showInputDialog("Nome:");
8 String resultado = JOptionPane.showInputDialog("Resultado:");
9 System.out.printf("O aluno %s foi %s\n", nome, resultado);
10 System.out.printf("\nFormatação numérica :%.2f", 12.356);
11 }
12

13 }

3.5. Conceito de Variável


Para resolver problemas em programas de computador é necessário manipular vários da-
dos, sejam eles números ou caracteres. Se você precisa calcular o resultado de uma única
conta, provavelmente o melhor seria utilizar uma calculadora. A utilidade de se escrever
um programa aparece quando usamos várias variáveis. Estas possuem a capacidade de con-
ter valores. Desta forma, é possível então calcular o resultado de várias contas. As variáveis
são declaradas com um identificador e seu nome. Exemplo:

String nome;
int idade;
String endereco;

Também é possível passar valores para variáveis no momento de sua declaração:

String nome = "José Maria";


int idade = 5;
String endereco = "Rua 2 nr 3 Centro";

http://solutioin.com 13
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

3.6. Palavras reservadas e identificadores


Palavras reservadas, são as palavras que não podem ser usadas como identificadores, ou
seja, não podem ser usadas como nome de variáveis, nome de classes, etc. Estas palavras
são assim definidas ou porque já têm uso na sintaxe da linguagem ou porque serão usadas
em algums momento, seja para manter compatibilidade com versões anteriores ou mesmo
com outras linguagens. No caso do Java, as palavras reservadas estão descritas na Tabela
3.2.

abstract continue for new switch


assert default goto package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while

Tabela 3.2: As palavras reservadas do Java

De acordo com a Java Language Specification2 , null, true e false são tecnicamente chama-
dos de valores literais, e não keywords. Se você tentar criar algum identificador com estes
valores, você também terá um erro de compilação.
Utilizamos, em Java, as seguintes regras para criação do identificador:

• não pode ser uma palavra reservada (Tabela 3.2);

• não pode ser true nem false - literais que representam os tipos lógicos (booleanos);

• não pode ser null - literal que represanta o tipo nulo;

• não pode conter espaços em brancos ou outros caracteres de formatação;

• deve ser a combinação de uma ou mais letras e dígitos (letras maíusculas, minúsculas,
números, sublinha (_) e cifrão ($)).

Os identificadores não podem começar com números. As letras maiúsculas e minúsculas


diferenciam os identificadores, ou seja, x é um identificador diferente de X, nome é diferente
de Nome, etc.
Exemplos:

2 http://docs.oracle.com/javase/specs/

14 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Y_1
nome
Pessoa
j3
_teste

3.7. Tipos Primitivos


Tipos primitivos são tipos que não necessitam instanciação, ou seja, sua declaração já cria
a variável na memória não sendo necessário construtores.
Existem oito tipos primitivos em Java que são divididos em quatro grupos:
• inteiros

• ponto flutuante

• caractere

• booleano.

3.7.1 Tipos primitivos inteiros


Os quatro tipos primitivos inteiros são utilizados para armazenamento de números inteiros,
sem casas decimais. Eles estão descritos na Tabela 3.3.

Tipo Tamanho Intervalo


byte 1 byte −128 até +127
short 2 bytes −32.768 até +32, 767
int 4 bytes −2.147.483.648 até 2.147.483.647
long 8 bytes −9.223.372.036.854.775.808 até 9.223.372.036.854.775.807

Tabela 3.3: Tipos primitivos inteiros do Java

Por padrão, os tipos primitivos inteiros são do tipo int, ou seja, se apenas for escrito
o número 5, este será do tipo int. Para explicitar o tipo long deve-se acrescentar, após o
número, a letra L (maiúscula ou minúscula):

long numero = 45L;

3.7.2 Tipos primitivos de ponto flutuante


Existem dois tipos de ponto flutuante, conforme descrito na tabela da figura 3.4. Estes tipos
são utilizados para armazenamento de números com casas decimais. Utiliza-se o símbolo
ponto (.) para separação decimal:

http://solutioin.com 15
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

1234.566
4343.1212

Tipo Tamanho Intervalo


float 4 byte +/ − 3.4E − 38 até +/ − 3.4E + 38
double 8 bytes +/ − 1.7E − 308 até +/ − 1.7E + 308

Tabela 3.4: Tipos primitivos de ponto flutuante do Java

Por padrão, os tipos primitivos com casas decimais são do tipo double, ou seja, se ape-
nas for escrito o número 3.5, este será do tipo double. Para explicitar o tipo float deve-se
acrescentar, após o número, a letra F (maiúscula ou minúscula):

float numero = 3.5F;

3.7.3 Tipo primitivo char


O tipo primitivo char é utilizado para representar caracteres. Ocupa dois bytes para ar-
mazenamento e o intervalo vai de 0 até 65535. Note que o tipo char não abrange números
negativos e possui dois bytes de armazenamento pois o Java suporta caracteres Unicode.

Dica:
O Unicode possui o objetivo explícito de transcender as limitações
de codificações de carácter tradicionais, como as definidas pelo
padrão ISO 8859, que possuem grande uso em vários países mas
que permanecem em sua maioria incompatíveis umas com as outras.
Várias codificações de carácter tradicionais compartilham um prob-
lema comum, ao permitirem processamento bilíngue (geralmente us-
ando caracteres romanos e a língua local), mas não processamento
multilíngue (processamento de línguas arbitrárias misturadas umas
com as outras).

3.7.4 Tipo primitivo boolean


O tipo primitivo boolean é utilizado para representar dois estados, verdadeiro ou falso.
Exemplo:

boolean ativo = true;


boolean cancelado = false;

16 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

3.7.5 Conversões de variáveis


É possível realizar automáticamente conversões entre variáveis primitivas do Java seguindo
a figura 3.3. Segundo esta figura não é possível converter automaticamente tipos maiores
como long para tipos menores como byte. Neste caso é necessário realizar a operação cast:

long maior = 56L;


byte menor = (byte)maior;

Observe que para realizar a operação de cast basta colocar o tipo que se deseja converter
entre parêntesis na frente da variável a ser convertida.
O código da listagem 3.4 apresenta um exemplo do que acontece quando é feito um cast
de uma variável maior para uma menor. Existe o risco de truncamento do número. A saída
deste exemplo é:

Numero:300
Após truncamento:44

Isto ocorre porque 300 escrito em binário é: 100101100. Contando os primeiros oito bits
da direita para esquerda, temos: 00101100. Este valor em decimal vale 44. O restante do
número em binário fui truncado, ou seja, descartado.

Listagem 3.4: Exemplo de truncamento de números


1 public class ExemploTruncamento {
2

3 public static void main(String[] args) {


4 int numero = 300;
5 byte menor = (byte) numero;
6 System.out.printf("\nNumero:%d \nApós truncamento :%d", numero, menor);
7 }
8

9 }

3.8. Operadores
Quando o computador foi concebido ele era puramente uma máquina de cálculos. Apesar
de atualmente o computador estar associado a diversas atividades da vida cotidiana, o
mesmo ainda não passa de uma super máquina de fazer cálculos. Desta forma, a linguagem
Java possui diverosos operadores cujo objetivo é realizar este cálculos. Nesta seção serão
apresentados os operadores que irão nos auxiliar em operações matemáticas e lógicas.

3.8.1 Aritméticos
A aritmética do Java é realizada por meio dos cinco operadores. Eles são divididos em dois
grupos, os de maior prioridade, listados na Tabela 3.5 e os de menor prioridade, listados

http://solutioin.com 17
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Figura 3.3: Conversões automáticas de tipos primitivos

na Tabela 3.6. Os operadores de maior prioridade são executados antes dos operadores
de menor prioridade, ou seja, se em uma expressão matemática existirem os dois tipos
inicialmente realiza-se as operações de maior prioridade e somente após são executados os
operadores de menor prioridade. A expressão:
5 + 3 * 5

Resultará em 20. A operação 3 ∗ 5 será executada primeiro.


A ordem de execução do Java dá-se da esquerda para a direita, ou seja, o nosso sentido
de leitura. Existindo, na mesma expressão matemática, dois ou mais operadores de maior
prioridade será executado o que vier primeiro: 8/2 ∗ 3 resultará em 12 porque a divisão 8/2
veio primeiro.
É possível alterar a órdem de execução com parêntesis. Após a execução de:

x = (5 + 3) * 2

o valor da variável x será 16 pois a soma será feita primeiro devido aos parêntesis.

3.8.2 Atribuição
Em Java é utilizado o operador = para realizar a atribuição. Sua ordem de execução é da
direita para a esquerda, ou seja, os valores mais à direita são atribuídos às variáveis mais a
esquerda: x = 4 equivale a dizer que o valor 4 será atribuído à variável x e, após a execução
desta instrução a variável x passará a conter o valor 4.

18 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Operador Operação realizada


* Multiplicação
/ Divisão
% Resto da divisão inteira

Tabela 3.5: Operadores com maior prioridade

Operador Operação realizada


+ Adição
- Subtração

Tabela 3.6: Operadores com menor prioridade

Em Java é possível combinar o operador de atribuição (=) com os operadores de arit-


mética criando mais operadores de atribuição conforme listados na Tabela 3.7. Veja que é
possível combinar alguns operadores e realizar uma operação aritmética e uma atribuição
utilizando uma destas combinações.
Uma dica para entender estes operadores é colocar o operador de aritmética antes do
operador de atribuição, sendo assim, se for necessário realizar as operações de soma e
atribuição primeiro escreva o operador de soma e depois o de atribuição: + =,

x += 3;

Após a execução desta instrução o valor da variável x será acrescido de 3.

Operador Exemplo Equivalente a


+= s += 7 s=s+7
-= s -= 7 s=s-7
*= m *= 7 m=s*7
/= d /= 7 d=s/7
%= r %= 7 r=s%7

Tabela 3.7: Exemplos de operadores de atribuição

3.8.3 Incremento/Decremento
Os operadores de incremento e decremento são utilizados quando existe a necessidade de
somar ou subtrair em apenas uma unidade os valores contidos em uma variável utilizando
dois sinais de soma, para incremento e dois sinais de subtração para decremento: Assim,
x + + incrementará o valor de x e x − − decrementará o valor de x. Estes operadores se
dividem em dois grupos:

http://solutioin.com 19
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

1. Pré-incremento/Pré-decremento: primeiro é incrementado/decrementado e somente


depois o valor é utilizado. O operador é colocado antes da variável:

x = 4;
y = ++x + 5;

O resultado de y após esta execução é 10. Inicialmente o valor de x é incrementado


passando a valer 5. Só após o incremento o valor da variável é utilizado na operação
de soma.

2. Pós-incremento/Pós-decremento: primeiro utiliza-se o valor e somente depois a var-


iável é incrementada/decrementada. O operador é colocado após a variável.

x = 4;
y = x++ + 5;

O resultado de y após esta execução é 9. Inicialmente o valor de x é somado, assim 4


+ 5 vale 9. O valor só é incrementado após as operações aritméticas.

3.8.4 Relacionais
São utilizados para comparar duas variáveis. O resultado da comparação é um valor
booleano. A relação de comparadores do Java pode ser vista na Tabela 3.8.

Operador Operação
== Igualdade
!= Diferença
> Maior que
>= Maior ou igual que
< Menor que
<= Menor ou igual que

Tabela 3.8: Operadores de comparação do Java

3.8.5 Lógicos
Existem quatro operações lógicas:

1. E, o resultado de uma operação lógica E só é verdadeiro se os dois operandos também


forem verdadeiros;

20 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

2. OU, o resultado de uma operação lógica OU só é falso se os dois operandos também


forem verdadeiros;

3. NAO, o resultado é a negação do operando, assim o que é verdadeiro se torna falso


e o que é falso se torna verdadeiro após esta operação;

4. OU EXCLUSIVO, o resultado de uma operação lógica OU EXCLUISIVO só é ver-


dadeiro se os dois operandos forem diferentes.

A tabela verdade do Operador E pode ser vista na figura 3.10. A tablea verdade do
Operador OU pode ser vista na figura 3.9. A tabela verdade do Operador OU EXCLUSIVO
pode ser vista na figura 3.11.
Os operadores lógicos do Java podem ser vistos na tabela da figura 3.12. Observe que
existem dois tipos de operadores OU (| e ||) e dois tipos de operadores E (& e &&).
Basicamente o que diferem estes dois tipos de operadores são o seguinte:

1. OU e E curto-circuito (|| e &&) são utilizados apenas para operações condicionais.


Em uma operação condicional, já sendo possível a obtenção do resultado, analisando
apenas o primeiro operando, não é analisado o segundo operando.

2. OU e E lógico (| e &) são utilizados em operações lógicas bit a bit.

Entrada 1 Entrada 2 Saída


V V V
V F V
F V V
F F F

Tabela 3.9: Tabela verdade da operação OU

Entrada 1 Entrada 2 Saída


V V V
V F F
F V F
F F F

Tabela 3.10: Tabela verdade da operação E

3.9. Estruturas de seleção


Estrutura de seleção (expressão condicional ou ainda construção condicional) é uma es-
trutura de desvio do fluxo de controle que executa diferentes instruções dependendo se a

http://solutioin.com 21
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Entrada 1 Entrada 2 Saída


V V F
V F V
F V V
F F F

Tabela 3.11: Tabela verdade da operação OU EXCLUSIVO

Operador Operação
|| OU curto-circuito
&& E curto-circuito
| OU lógico
& E lógico
ˆ OU exclusivo
! Não lógico

Tabela 3.12: Tabela de operadores lógicos

seleção (ou condição) é verdadeira ou falsa, em que a expressão é processada e transfor-


mada em um valor booleano.

3.9.1 if . . . else
A instrução if . . . else se comporta da seguinte maneira. Quando o teste do “if” for ver-
dadeiro, é executado o código que se encontra logo em seguida do if. No caso do teste ser
falso, é executado o código que se encontra logo em seguida do else. O bloco else não é
obrigatório. A figura 3.4 ilustra o fluxo da instrução if . . . else. Na listagem 3.5 pode ser
visto um exemplo de uso.
Sua sintaxe é:

if(teste){
//executa somente se o teste for verdadeiro
}else{
//executa somente se o teste for falso
}

Listagem 3.5: Exemplo de uso do if . . . else


1 import javax.swing.JOptionPane;
2

3 public class ExemploIf {


4 public static void main(String[] args) {
5 //Obtenção dos dados do usuário

22 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Figura 3.4: Fluxo de execução do if

6 String notaString = JOptionPane.showInputDialog("Digite a nota:");


7 //Conversão em int
8 int nota = Integer.parseInt(notaString);
9

10 if (nota >= 5) {
11 JOptionPane.showMessageDialog(null, "Aprovado");
12 } else {
13 JOptionPane.showMessageDialog(null, "Reprovado");
14 }
15 }
16 }

Dica:
Para converter String em int, utilize o código:

int nota = Integer.parseInt(notaString);

e para converter String em double:

double nota = Double.parseDouble(notaString);

3.9.2 Operador condicional ou ternário


O operador condicional pode ser utilizado como um if ... else. Este operador é conhecido
também como operador ternário porque ele possui três operandos:

(teste ? "quando teste verdadeiro" : "quando teste falso" ));

http://solutioin.com 23
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

Um exemplo de uso deste operador está na Listagem 3.6.


Na listagem 3.7 pode ser visto outro exemplo de aplicação do operador condicional na
listagem 3.7;

Listagem 3.6: Exemplo de uso do operador condicional.


1 import javax.swing.JOptionPane;
2

3 public class ExemploCondicional {


4 public static void main(String[] args) {
5 String notaString = JOptionPane.showInputDialog("Digite a nota:");
6 int nota = Integer.parseInt(notaString);
7 String resultado = nota >= 5 ? "aprovado" : "reprovado";
8 String msg = "O aluno foi " + resultado;
9 JOptionPane.showMessageDialog(null, msg);
10 }
11 }

Listagem 3.7: Outro exemplo de uso do operador condicional.


1 import javax.swing.JOptionPane;
2

3 public class ImprimeMaior {


4 public static void main(String[] args) {
5 String primeiroNumero = JOptionPane.showInputDialog("Digite um número:");
6 String segundoNumero = JOptionPane.showInputDialog("Digite um número:");
7

8 int n1 = Integer.parseInt(primeiroNumero);
9 int n2 = Integer.parseInt(segundoNumero);
10

11 int maior = n1 > n2 ? n1 : n2;


12

13 JOptionPane.showMessageDialog(null, "O maior numero é: " + maior);


14 }
15 }

3.9.3 switch
Diferente das instruções if e if . . . else, a instrução switch permite um maior número de pos-
sibilidades de caminhos de execução. A palavra chave switch pode ser utilizada somente
com o tipo primitivo int (byte, short, char por conversão automática e seus tipos Wrappers),
o tipo Enum e, a partir da versão 7 do Java, String. Na listagem 3.8 está o código exemplo
da instrução switch.
Sua sintaxe é:

switch(tipo){
case a:
//instrucao;
case b:
//instrucao;

24 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

default:
//instrucao;
}

É comum utilizar a instrução switch juntamente com o break para que apenas uma opção
seja executada.

Listagem 3.8: Exemplo de utilização do switch


1 import javax.swing.JOptionPane;
2

3 public class ExemploSwitch {


4 public static void main(String[] args) {
5 String numeroString =
6 JOptionPane.showInputDialog("Digite o número de um mês (1 a 12):");
7 int num = new Integer(numeroString);
8 String msg;
9 switch (num) {
10 case 1:
11 msg = "Janeiro";
12 break;
13 case 2:
14 msg = "Fevereiro";
15 break;
16 case 3:
17 msg = "Março";
18 break;
19 case 4:
20 msg = "Abril";
21 break;
22 case 5:
23 msg = "Maio";
24 break;
25 case 6:
26 msg = "Junho";
27 break;
28 case 7:
29 msg = "Julho";
30 break;
31 case 8:
32 msg = "Agosto";
33 break;
34 case 9:
35 msg = "Setembro";
36 break;
37 case 10:
38 msg = "Outubro";
39 break;
40 case 11:
41 msg = "Novembro";
42 break;
43 case 12:
44 msg = "Dezembro";

http://solutioin.com 25
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

45 break;
46 default:
47 msg = "Número incorreto";
48 }
49 JOptionPane.showMessageDialog(null, msg);
50 }
51 }

3.10. Estruturas de Repetição


Estrutura de repetição é uma estrutura de desvio do fluxo de controle que realiza e repete
diferentes ações, dependendo se uma condição é verdadeira ou falsa, em que a expressão
é processada e transformada em um valor booleano. Estão associados a uma estrutura
de repetição uma condição (também chamada "expressão de controle" ou "condição de
parada") e um bloco de código: verifica-se a condição, e caso seja verdadeira, o bloco é
executado. Após o final da execução do bloco, a condição é verificada novamente, e caso
ela ainda seja verdadeira, o código é executado novamente.

3.10.1 for
A instrução for provê um caminho rápido para percorer uma faixa de valores. Com esta
instrução é possível repetir determinadas instruções enquanto a condição for verdadeira. A
sintaxe do for é a seguinte:
for (inicialização; condição; incremento) {
instruções(s)
}

É bom lembrar que:


• A inicialização é executada apenas quando o loop inicia;
• Quando a condição for false o loop terminará;
• O incremento é invocado depois de cada iteração, local adequado para incrementos e
decrementos de variáveis;
Veja na listagem 3.9 um exemplo de uso do laço for. Neste exemplo são impressas quinze
linhas no console.
Listagem 3.9: Exemplo de uso do laço for
1 public class ExemploFor {
2 public static void main(String[] args) {
3 for (int i = 0; i < 15; i++) {
4 System.out.printf("\nlinha: %d", i);
5 }
6 }
7 }

26 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

3.10.2 while
A instrução while executa um bloco de instruções enquanto uma condição particular for
verdadeira (true). Sua sintaxe é:

while (teste) {
statement(s)
}

A expressão while avalia o teste, que deve retornar um tipo booleano. Se a espressão
avaliada for verdadeira (true), o bloco while executa as instruções dentro do bloco. A ex-
pressão while continua testando o teste até que este seja falso (false). O código da listagem
3.10 calcula a soma de inteiros enquanto a opção de saída não é informada.

Listagem 3.10: Exemplo de utilização do laço while


1 import javax.swing.JOptionPane;
2

3 public class ExemploWhile {


4 public static void main(String[] args) {
5 int status = 0;
6

7 int qtd = 0;
8 double soma = 0;
9

10 while (status != 1) {
11 String numStr1 = JOptionPane.showInputDialog("Digite um inteiro");
12 int n1 = Integer.parseInt(numStr1);
13

14 soma += n1;
15 qtd++;
16

17 String msg = "Digite 1 para sair ou qualquer outro número para continuar";
18 String statusStr = JOptionPane.showInputDialog(msg);
19

20 status = Integer.parseInt(statusStr);
21

22 }
23

24 double media = soma / qtd;


25 JOptionPane.showMessageDialog(null, "Média: " + media);
26

27 }
28 }

3.10.3 do . . . while
A linguagem Java provê a instrução do . . . while que pode ser vista abaixo:

http://solutioin.com 27
Francisco Calaça, Otávio Calaça
Versão 1.1 lógica de programação em java

do {
statement(s)
} while (teste);

A principal diferença entre do . . . while e while é que while primeiro avalia o teste e somente
após executa o loop, enquanto do . . . while primeiro executa a instrução e somente após isto
é avaliado o teste. Em resumo, do . . . while garante pelo menos uma execução das instruções
do bloco.

3.11. Exercícios
1. Crie um código que executa a seguinte ação: solicita ao usuário uma idade. Se esta for
maior ou igual a 16, imprime: “Pode votar”. Se não for, imprime: “Não pode votar”.

2. Melhore o código do exercício anterior para imprimir também “Vodo obrigatório”


quando a idade estiver entre 18 e 70 anos.

3. Crie um código que imprima o seguinte:

************
************
************
************

4. Crie um código que solicita ao usuário um número entre 1 e 7. Após isto, o sistema
imprime: Domingo se o número for 1, Segunda se o número for 2, Terça se o número
for 3, etc. . .

5. Altere o código da listagem 3.10 para utilizar do. . . while no lugar de while.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

28 http://solutioin.com
Francisco Calaça, Otávio Calaça
I N T R O D U Ç Ã O À O R I E N TA Ç Ã O A
4
OBJETOS

O Objetivo da orientação a objetos é facilitar o reuso de software. Hoje ao ir a uma loja


para comprar uma lâmpada, a única coisa que é necessário saber é a potência desta. O
fabricante da lâmpada, sem ter medido nada na sua sala, consegue fabricar uma lâmpada
que servirá para você. Hoje é fácil reutilizar lâmpadas por conta que estas seguem alguns
padrões que facilitam sua utilização. Não é necessário rever toda a fiação da sua residência
quando uma lâmpada queima, nem substituir nada. Basta tirar a lâmpada defeituosa e
colocar outra nova no seu lugar.
Desta forma, a orientação a objetos traz para o mundo do software as facilidades encon-
tradas no mundo real.
Neste capítulo você verá os conceitos inicias da orientação a objetos, tais como classes e
seus elementos.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

4.1. O conceitos Classe e Objeto


Os conceitos iniciais de Orientação a Objetos são:

• Classe, significa grupo ou conjunto. Representa um tipo de dados que pode conter
atributos e métodos, como por exemplo, Carro. A classe Carro define todo o conjunto
de carros. A este conjunto é possível associar atributos como potência, número de
passageiros, etc. Mas lembre-se, trata-se de apenas um conjunto, este ainda pode
estar vazio.

• Objeto, representa um elemento do conjunto Carro, ou seja, o carro construído. Sabendo


o que é um carro (seus atributos) é possível construir quantos objetos do tipo carros
forem necessários.

Em resumo: Objeto é a instância de uma classe. Mas o que significa instância ?


Instância siginifica a concretização de algo, ou seja, a materizalização de um objeto.
Assim a frase: “Objeto é a instância de uma classe” pode ser traduzida como: “Objeto é
a concretização de uma classe”.

29
Versão 1.1 introdução à orientação a objetos

Assim uma classe é o arquivo, o código digitado, enquanto o objeto será construído pelo
programa, a partir da classe, e executado pelo computador.
Para declarar classes utiliza-se a palavra chave class:

class Carro {
//campos, construtores, e declaração de métodos
}

Para instanciar, ou criar, objetos a partir de uma classe utiliza-se o operador: new.

Carro seuCarro = new Carro();

Note que uma classe é também um tipo. Você acabou de criar um novo tipo de variáveis
no Java! O tipo Carro.
Antes de serem instanciadas, as variáveis objeto valem null. A palavra chave null é
utilizada para expressar a não existencia de uma instância de um objeto em determinada
variável, ou seja, representa o nulo. Esta forma, uma variável não instanciada possui o valor
null.

4.2. Elementos de uma classe


Uma classe possui atributos e métodos. Existe também um tipo especial de método: o método
construtor. Nesta seção serão apresentados estes elementos.

4.2.1 Atributos
Atributos de uma classe são as propriedades da mesma. No exemplo do Carro, atributos
poderiam ser: cor, dataDeFabricacao, potência, etc. Observe que atributos são substantivos que
descrevem a Classe e que são exclusivos de cada objeto, ou seja, apesar de todos os Carros
possuirem o atributo cor, cada Carro pode ter uma cor diferente. Na classe da listagem 4.1
existem os atributos cor e velocidade. Após a execução da classe da Listagem 4.2, você verá
a seguinte saída:

Cor: Branco - Velocidade:80.0

Listagem 4.1: Carro com seus atributos


1 public class Carro {
2 double velocidade;
3 String cor;
4 }

Listagem 4.2: Classe que cria um objeto do tipo Carro


1 public class CarroTeste {
2 public static void main(String[] args) {
3 Carro obj = new Carro();

30 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

4 obj.cor = "Branco";
5 obj.velocidade = 80;
6

7 System.out.printf("Cor: %s - Velocidade :%s\n", obj.cor, obj.velocidade);


8 }
9 }

4.2.2 Métodos
Métodos são como funções. Possuem instruções que são executadas quando o método é
invocado. Em Orientação a Objetos os métodos descrevem ações realizadas pelos objetos.
Em Java os métodos devem possuir tipo de retorno:
int realizaAlgo(){
//instruções
return 5;
}

Neste caso é obrigatório explicitar o que o método retorna com a palavra chave return.
Se o método não retornar algo, o tipo de retorno utilizado é void (note que sempre deve
ser informado o tipo de retorno. Mesmo quando o método não retorna nada!):
void realizaAlgo(){
//instruções
}

Os métodos também podem receber parâmetros:


void realizaAlgo(int parametro){
//instruções
}

Havendo a necessidade de múltiplos parâmetros em um método utiliza-se vírgula para


separá-los:
void realizaAlgo(int parametro, double outroParametro){
//instruções
}

A Listagem 4.3 inclui métodos na classe Carro. Estes métodos são responsáveis por al-
terar a velocidade e parar o carro. A Listagem 4.4 apresenta um exemplo de execução destes
métodos. Após sua execução, você verá a seguinte saída:
Mudando a velocidade para 80,000000 Km/h
Velocidade atual: 80,000000 Km/h
Parando veículo. Velocidade 0 Km/h. Cor: Branco

Mudando a velocidade para 60,000000 Km/h


Velocidade atual: 60,000000 Km/h
Parando veículo. Velocidade 0 Km/h. Cor: Vermelho

http://solutioin.com 31
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

Listagem 4.3: Carro com atributos e métodos


1 public class Carro {
2

3 double velocidade;
4 String cor;
5

6 void mudarVelocidade(double v) {
7 velocidade = v;
8 System.out.printf("\n\nMudando a velocidade para %f Km/h", velocidade)
;
9 }
10

11 void pararCarro() {
12 System.out.printf("\nVelocidade atual: %f Km/h", velocidade);
13 System.out.printf("\nParando veículo. Velocidade 0 Km/h. Cor: %s", cor
);
14 }
15 }

Listagem 4.4: Classe que cria um objeto do tipo Carro


1 public class CarroTesteMetodo {
2 public static void main(String[] args) {
3 Carro meuCarro = new Carro();
4 meuCarro.cor = "Branco";
5 meuCarro.mudarVelocidade(80);
6 meuCarro.pararCarro();
7

8 Carro carroDaEsposa = new Carro();


9 carroDaEsposa.cor = "Vermelho";
10 carroDaEsposa.mudarVelocidade(60);
11 carroDaEsposa.pararCarro();
12 }
13 }

4.2.3 Métodos construtores


Métodos construtores são um tipo especial de métodos. Eles são invocados quando objetos
são criados. A declaração de um construtor é similar a declaração de um método, exceto
o tipo de retorno: Construtores não possuem tipo de retorno. Nem void. Toda classe Java
possui um construtor. Se não for implementado um construtor o compilador criará um
automaticamente. Este construtor criado, é chamado de construtor padrão por não receber
parâmetros.

Dica:
Construtor padrão é aquele que não recebe parâmetros.

32 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

É possível passar parâmetros para construtores conforme apresentado na listagem 4.5. É


uma forma de criar objetos e ao mesmo tempo ajustar os atributos iniciais. O código da
listagem 4.6 possui a seguinte saída:

Fabricando uma Motocicleta.


Cor: Azul, Potência: 125,000000 cilindradas

Fabricando uma Motocicleta.


Cor: Vermelho, Potência: 250,000000 cilindradas

Fabricando uma Motocicleta.


Cor: Prata, Potência: 400,000000 cilindradas

Listagem 4.5: Exemplo de construtor que recebe atributos


1 public class Motocicleta {
2 String cor;
3 double potencia;
4

5 public Motocicleta(String c, double p) {


6 cor = c;
7 potencia = p;
8 System.out.printf("\n\nFabricando uma Motocicleta."
9 + "\nCor: %s, Potência: %f cilindradas", cor, potencia);
10 }
11 }

Listagem 4.6: Criação de motocicletas


1 public class MotocicletaTeste {
2 public static void main(String[] args) {
3 Motocicleta moto1 = new Motocicleta("Azul", 125);
4 Motocicleta moto2 = new Motocicleta("Vermelho", 250);
5 Motocicleta moto3 = new Motocicleta("Prata", 400);
6 }
7 }

4.2.4 Padrões de nomenclatura


Os padrões de nomenclatura utilizados pelos programadores Java são:

• Os nomes das classes começam com letras maiúsculas;

• Os nomes dos métodos e variáveis começam com letras minúsculas;

• Não é utilizado o caracter _ para mudança de palavra e sim a colocacação da primeira


letra da palavra em maiúsculo.

• Variáveis constantes são escritas em maiúsculo.

http://solutioin.com 33
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

Dica:
Esta padronização, dentre outras da linguagem Java, estão descritas
no documento chamado: Code Conventions for the Java Program-
ming Language. Este documento pode ser acessado através do site:
http://www.oracle.com/technetwork/java/codeconv-138413.html

4.3. Atributos e métodos static


Até agora todos os atributos e métodos de uma classe só estavam acessíveis atravéz de suas
instâncias. Se você observar o campo out da classe System verá que é possível acessa-lo
diretamente da classe, sem qualquer instância.
Os campos podem ser da classe ou do objeto. Até agora todos os campos criados foram
de objetos, pois só são acessíveis a partir de objetos. Para que determinados atributos
possam ser compartilhados por todos os objetos de determinada classe, estes atributos
devem possuir o modificador static.
Na listagem 4.7 é apresentada uma classe com um atributo static. Observe que este
atributo é incrementado a cada nova instância desta classe. A classe da listagem 4.8 cria
três objetos do tipo ObjetoTeste e no final acessa a variável quantidadeInstancias para saber
este número. Note que é possível acessar elementos statics sem a necessidade de instanciar
a classe.

Listagem 4.7: Objeto para testes da palavra chave static


1

2 public class ObjetoTeste {


3

4 static int quantidadeInstancias;


5

6 public ObjetoTeste() {
7 quantidadeInstancias ++;
8 }
9

10 }

Listagem 4.8: Demonstração da palavra chave static


1

2 public class ExemploStatic {


3

4 public static void main(String[] args) {


5 ObjetoTeste obj1 = new ObjetoTeste();
6 ObjetoTeste obj2 = new ObjetoTeste();
7 ObjetoTeste obj3 = new ObjetoTeste();
8

9 System.out.printf("\nQuantidade de instâncias do Objeto" +


10 "Teste:%d" , ObjetoTeste.quantidadeInstancias);
11 }
12

34 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

13 }

4.3.1 Import static


Permite importar métodos e campos static de determinadas classes. Exemplo:

import static javax.swing.JOptionPane.*;


import static java.lang.Math.*;

Observe no código da listagem 4.9 a utilização de vários métodos do tipo static das
classes JOptionPane e Math. A cada utilização de um método destas classes como:

JOptionPane.showMessageDialog(...);

Um exemplo equivalente está no código da listagem 4.10. Nesta classe foi utilizado o
import static o que tornou desnecessário a referência das classes JOptionPane e Math:

showMessageDialog(...);

Listagem 4.9: Código sem import static


1 import javax.swing.JOptionPane;
2

3 public class ExemploSemImportStatic {


4 public static void main(String[] args) {
5 String numeroTexto = JOptionPane.showInputDialog("Digite um número:");
6 int numero = new Integer(numeroTexto);
7 double raizQuadrada = Math.sqrt(numero);
8 double cubo = Math.pow(numero, 3);
9 double seno = Math.sin(numero);
10

11 JOptionPane.showMessageDialog(null, "Numero:" + numero);


12 JOptionPane.showMessageDialog(null, "Raiz Quadrada:" + raizQuadrada);
13 JOptionPane.showMessageDialog(null, "Cubo:" + cubo);
14 JOptionPane.showMessageDialog(null, "Seno:" + seno);
15 }
16 }

Listagem 4.10: Código com import static


1

2 import static javax.swing.JOptionPane.*;


3 import static java.lang.Math.*;
4

5 public class ExemploImportStatic {


6 public static void main(String[] args) {
7 String numeroTexto = showInputDialog("Digite um número:");
8 int numero = new Integer(numeroTexto);
9 double raizQuadrada = sqrt(numero);
10 double cubo = pow(numero, 3);
11 double seno = sin(numero);

http://solutioin.com 35
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

12

13 showMessageDialog(null, "Numero:" + numero);


14 showMessageDialog(null, "Raiz Quadrada:" + raizQuadrada);
15 showMessageDialog(null, "Cubo:" + cubo);
16 showMessageDialog(null, "Seno:" + seno);
17 }
18

19 }

4.4. Tipos Wrapper


As classes wrappers tem o papel de encapsular os tipos primitivos para a possibilidade de
operações como: conversões, mudança de bases decimais, e algumas operação que somente
a objetos é permitido, como por exemplo, trabalhar com conjuntos.
Java possui oito tipos wrapper, que adicionam funcionalidades aos tipos primitivos:

1. Byte - byte

2. Short - short

3. Integer - int

4. Long - long

5. Float - float

6. Double - double

7. Character - char

8. Boolean - boolean

Basicamente os tipos wrapper possuem os mesmos nomes dos tipos primitivos, com a
primeira letra maiúscula, exceto para os tipos int que é Integer e char que é Character.
Algumas destas funcionalidades são: a conversão de tipo primitivo para objeto, conver-
são para String, conversão à partir de String, etc.

4.4.1 Auto-boxing e Auto-unboxing


Este conceito permite converter automaticamente tipos primitivos em equivalentes objetos
utilizando a classe Wrapper respectiva. Isto economiza código e facilita o entendimento do
programa.

• Auto-boxing, conversão automática de um tipo primitivo para seu respectivo tipo


Wrapper;

• Auto-unboxing, conversão automática de um tipo Wrapper para seu respectivo tipo


primitivo;

36 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

Veja na listagem 4.11 um exemplo de boxing e unboxing.

Listagem 4.11: Exemplo de auto boxing


1 public class ExemploAutoBoxing {
2 public static void main(String[] args) {
3 /*
4 * Exemplo de auto boxing. Observe o número 16, tipo int e primitivo, foi
5 * automaticamente convertido para o tipo Wrapper Integer.
6 */
7 Integer idade = 16;
8

9 /*
10 * Exemplo de auto unboxing. Observe a utilização da classe Integer para
11 * conversão da String 56 em tipo int.
12 */
13 int quantidade = new Integer("56");
14

15 }
16 }

4.5. Regras de escopo


Entenda por escopo área de atuação. Os escopos do Java são definidos por chaves. As var-
iáveis declaradas dentro de um escopo somente podem ser acessadas dentro deste mesmo
escopo.
Observe que os blocos if, while, for, métodos, etc. definem escopos. Seus códigos são
escritos entre chaves. Todas as variáveis declaradas dentro de um bloco if somente podem
ser acessadas dentro de um bloco if. Cada método define um novo escopo, por isto as
variáveis declaradas dentro de um método não podem ser acessadas por outro método, ou
seja, outro escopo.
Observe o código da listagem 4.12. Neste código existe um bloco for no método main.
Dentro do bloco for foi declarada as variáveis numero e i. Estas variáveis não podem ser
acessadas fora do bloco for.

Listagem 4.12: Exemplo de regras de escopo


1 public class ExemploEscopo {
2 public static void main(String[] args) {
3 for (int i = 0; i < 10; i++) {
4 int numero = i;
5 System.out.println("linha " + i);
6 }
7 }
8 }

http://solutioin.com 37
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

4.6. Sobrecarga de métodos


Java trabalha com o conceito da assinatura de métodos. A assinatura de um método consiste
no nome do mesmo juntamente com seus atributos de entrada. Assim o método:

void acao(String texto)

possui a assinatura acao(String), pois o método se chama acao e recebe uma String como
parâmetro de entrada.
Não entra no conceito de assinatura de um método o seu tipo de retorno, ou seja, dois
métodos:

void acao(String texto)


int acao(String texto)

possuem a mesma assinatura: acao(String) pois o tipo de retorno não é considerado na


definição da assinatura.
O código da listagem 4.13 apresenta um exemplo de sobrecarga de métodos. Neste
código todos os métodos se chamam metodoQualquer e diferem apenas na quantidade
e tipo de parâmetros. Observe que suas assinaturas são diferentes. O método main invoca
cada um destes métodos passando parâmetros diferentes. A JVM consegue descobrir o
método correto a ser executado em função da quantidade e tipo dos parâmetros informa-
dos.

Listagem 4.13: Exemplo de sobrecarga de métodos


1 public class ExemploSobrecarga {
2 static void metodoQualquer(int i){
3 System.out.printf("\nEste método recebe um INT: %d", i);
4 }
5 static void metodoQualquer(double d){
6 System.out.printf("\nEste método recebe um DOUBLE: %f", d);
7 }
8 static void metodoQualquer(String texto){
9 System.out.printf("\nEste método recebe um BYTE: %s", texto);
10 }
11 static void metodoQualquer(){
12 System.out.printf("\nEste método não recebe parâmetros");
13 }
14

15 public static void main(String[] args) {


16 metodoQualquer(1);
17 metodoQualquer(1.0);
18 metodoQualquer("teste");
19 metodoQualquer();
20 }
21 }

38 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução à orientação a objetos

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

4.7. Exercícios
1. Qual a diferença entre classe e objeto?

2. Quais são os elementos de uma classe?

3. O que são métodos construtores?

4. Para que serve a palavra chave static?

5. O que faz o import static?

6. O que é um escopo?

7. O que é sobrecarga de métodos?

8. O que são tipos wrappers ? Quais são eles ?

9. Crie uma classe java com atributos e métodos (à sua escolha). Crie outra classe que
instancia a primeira, seta seus atributos e invoca seus métodos.

10. Adicione um construtor na classe do exercício anterior.

http://solutioin.com 39
Francisco Calaça, Otávio Calaça
A R R AY S
5
Arrays são estruturas de dados que permitem o armazenamento de objetos o que fa-
cilita a manipulação e transporte destes. No mundo real são utilizadas caixas quando é
necessário agrupar ou transportar objetos. No mundo do Java uma das estruturas utilizadas
são Arrays. Para trabalhar adequadamente com Arrays é necessário que você saiba como
inicializa-los. O próprio método main recebe um array de strings quando é feito String []
args.
O Java 5 trouxe uma nova estrutura for, mais adequada para percorrer valores de arrays.
Esta estrutura é mais rápida e mais simples de implementar. Trata-se do for aprimorado.

5.1. O que são arrays


Um array é um objeto continer utilizado para armazenar outros objetos. Possui um tamanho
fixo. O tamanho de um array é estabelecido quando este é criado. Após sua criação não é
mais possível alterar este tamanho. Em capítulos posteriores será apresentado as coleções
que podem ter seus tamanhos alterados.
Cada item em um array é chamado de elemento e cada elemento pode ser acessado por
um índice numérico. Este índice é um inteiro e sempre se inicia com 0, ou seja, um array
com 10 elementos terá os índices de 0 até 9.
Um bom exemplo para ilustrar um array é a caixa de ovos. Pense em uma caixa de ovos
com 9 unidades. A caixa de ovos é um array com 9 elementos. Todos do tipo ovo. A figura
5.1 ilustra isto. Note que quando se cria um array este é uma caixa de ovos vazia mas com
um espaço pré-determinado, no caso 9. Este espaço é o tamanho do array. Somente após a
criação do array é possível “colocar” elementos nele.
Para acessar determinado elemento de um array é necessário utilizar colchetes:

int n = numeros[4];

Este exemplo acessa o quinto elemento do array (a numeração dos índices de um array
inicia com 0, por isto o indice 4 representa o quinto elemento).
Se ocorrer uma tentativa de acesso a um elemento não existente em um array ocorrerá
um erro. Por exemplo, ao tentar acessar o sexto elemento de um array com 3 elementos
será visto um erro:

int [] numeros = new int[3];


int n = numeros[5];

Ocasionará o erro: java.lang.ArrayIndexOutOfBoundsException


No capítulo sobre exceções será apresentado como tratar estes tipos de erros.

41
Versão 1.1 arrays

Figura 5.1: Um array pode ser comparado a um porta ovos, cada elemento do array pode ser com-
parado a um ovo

5.2. Declaração e inicialização de arrays


É possível declarar arrays da seguinte forma:

int [] primeiroArray;

Como nas declarações de variáveis de qualquer tipo no Java, a declaração possui duas
partes: o tipo e o nome da variável. Note que o tipo do array é escrito como tipo[], onde
tipo é o tipo de dados que será colocado no array.
Também é possível, ao declarar arrays, colocar os colchetes após a variável:

int primeiroArray [];

Mas esta forma é menos usual no Java.


Um array é inicializado utilizando o operador new porque este é um objeto:

primeiroArray = new int[10];

Este exemplo cria um array com capacidade de armazenamento de 10 elementos.


Esta operação apenas inicializa o array, mas não os elementos internos a este. Os elemen-
tos devem ser inicalizados um a um:

primeiroArray[0] = 2;
primeiroArray[1] = 3;
. . .
primeiroArray[8] = 4;
primeiroArray[9] = 5;

Outra forma de se inicializar um array e, ao mesmo tempo, inicializar os elementos de


um array é:

int [] primeiroArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};

Observe neste exemplo que é, na mesma linha, declarado um array, inicializado com 10
elementos e, cada elemento, é inicializado com um determinado valor.
Uma observação importante, que costuma cair nas provas de certificação, é que quando o
array é de tipos primitivos todos os elementos deste são inicializados com 0 ou false, se for

42 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

de tipo boolean. Em array de Objetos, os elementos não são inicializados, todos continuarão
valendo null.
Array possui um atributo chamado length. Este atributo possui a quantidade de elemen-
tos do array.
O código da listagem 5.1 apresenta um exemplo de declaração e inicialização de arrays.
Observe neste exemplo que foi declarado dois tipos de arrays: um array de int e um array
de String. Os elementos destes arrays não foram inicializados mas após a iteração entre
seus elementos é possível notar que os elementos do array de int valem 0 e os elementos
dos array de tipo String valem null.
A saída deste exemplo é a seguinte:

Array de tipo int


Posição [0] = 0
Posição [1] = 0
Posição [2] = 0
Posição [3] = 0
Posição [4] = 0
Posição [5] = 0
Posição [6] = 0
Posição [7] = 0
Posição [8] = 0
Posição [9] = 0

Array de tipo String


Posição [0] = null
Posição [1] = null
Posição [2] = null
Posição [3] = null
Posição [4] = null
Posição [5] = null
Posição [6] = null
Posição [7] = null
Posição [8] = null
Posição [9] = null

Listagem 5.1: Exemplo de declaração de arrays


1 public class DeclaracaoArray {
2 public static void main(String[] args) {
3 //Criando um array de tipo int
4 int [] numeros = new int[10];
5 //Criando um array de String
6 String [] textos = new String[10];
7

8 System.out.println("\nArray de tipo int");


9 for (int i = 0; i < numeros.length; i++) {

http://solutioin.com 43
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

10 System.out.printf("Posição [%d] = %d\n", i, numeros[i]);


11 }
12

13 System.out.println("\nArray de tipo String");


14 for (int i = 0; i < textos.length; i++) {
15 System.out.printf("Posição [%d] = %s\n", i, textos[i]);
16 }
17

18 }
19 }

5.3. Método main


Agora é possível explicar toda a assinatura do método main:

public static void main(String [] args){


. . .
}

Sempre deverá ser assim! Este método deve:

• Ser public pois deve ser acessado externamente;

• Ser static pois, como é o primeiro método a ser acessado em um programa Java, ainda
não é possível existir uma instância de um objeto, logo, é necessário um método static,
que pode ser acessado fora de qualquer instância de um objeto;

• Deve, sempre, receber um array de String como parâmetro. São os parâmetros para o
programa.

O código da listagem 5.2 ilustra como obter os parâmetros informados pela linha de
comando a um programa Java. Neste exemplo observe a utilização do atributo length no
laço for.
Para configurar o eclipse basta clicar no botão descrito na figura 5.2. Após isto crie
um novo Java Application, conforme ilustrado na figura 5.3. Clique na aba Arguments
e coloque os parâmetros no campo Program Arguments.
Para executar via linha de comandos basta acrescentar, após a classe, os parâmetros para
a aplicação, conforme ilustrado na figura 5.4.

Listagem 5.2: Obtenção dos parâmetros informados ao programa


1 public class ParametrosPrograma {
2 public static void main(String[] args) {
3 System.out.println("Os parâmetros digitados foram:");
4 for (int i = 0; i < args.length; i++) {
5 System.out.println(args[i]);
6 }
7 }
8 }

44 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

Figura 5.2: Início das configurações de execução

Figura 5.3: Configuração do eclipse para passagem de parâmetros para a aplicação

Figura 5.4: Passagem de parâmetros para uma aplicação Java via linha de comando

http://solutioin.com 45
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

5.4. Laço for aprimorado


O Java 5 trouxe uma nova funcionalidade para iteração de arrays: o for aprimorado. Esta
nova forma de utilização do for permite iterações de coleções e arrays de forma compacta
e mais fácil de ser lida. Para demonstrar um exemplo, considere o exemplo da listagem 5.3.
Neste exemplo é utilizada a seguinte estrutura for:

for (String meioTransporte : transportes) {


. . .
}

Observe que este for necessita apenas de dois parâmetros: A variável que receberá cada
item do array e o array. Este for percorrerá todo o array transportes e coloca, cada elemento
deste, na variável meioTransporte.

Listagem 5.3: Exemplo de uso do for aprimorado


1 public class ForAprimorado {
2 public static void main(String[] args) {
3 String [] transportes = {"Terrestre", "Aquático", "Aéreo"};
4

5 for (String meioTransporte : transportes) {


6 System.out.printf("\nTransporte: %s", meioTransporte);
7 }
8 }
9 }

5.5. Passagem de parâmetros no Java


Em Java todos os parâmetros são passados por valor. Isto significa que o valor da variável
passado sempre será copiado para o valor da variável que está recebendo o parâmetro. Mas
isto provoca dois tipos de comportamentos diferentes:

• Quando a variável passada é primitiva (byte, short, int long, float, double, char e
boolean), o valor é copiado para a variável que está recebendo, ou seja, esta pode
sofer alterações que não serão replicadas no valor da variável passada.

• Quando é passado uma variável Objeto, o valor desta também é copiado. A diferença
é que o valor de uma variável Objeto é apenas a referência a este Objeto, por isto,
tem-se a impressão que ocorreu uma passagem por referência, mas ainda é por valor,
pois este foi copiado. Lembre-se o valor de uma variável Objeto é a referência a este
objeto. Se, neste caso, for alterada a variável passada, esta também sofre alterações na
origem.

Para poder entender melhor isto, veja o código da listagem 5.5. Esta classe utiliza a classe
Pessoa descrita na listagem 6.4.

46 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

Observe, na classe da listagem 5.5, a existência de dois métodos chamados metodoQual-


quer. O primeiro método recebe um int, que é um tipo primitivo, e o segundo método
recebe uma Pessoa, que é um objeto.
Quando invocado o metodoQualquer pela primeira vez no método main, foi passado
como parâmetro a variável valor que é um tipo primitivo. Note que o valor desta variável
não mudou, antes e depois da execução do metodoQualquer continuou tendo 4 como valor.
Quando é invocado o metodoQualquer passando um objeto do tipo Pessoa, este teve
sua referência copiada. Assim quando alterado em metodoQualquer, esta alteração será
percebida no método main. Observe que, apesar de se ter a impressão que ocorreu uma
passagem por referência, não foi isto que ocorreu no Java. O que ocorreu foi uma passagem
por valor. Lembre-se que em Java as varáveis Objeto armazenam apenas a referência a um
objeto. Na passagem de parâmetros por valor, o valor (no caso a referência ao objeto do
tipo Pessoa) foi copiado para o método metodoQualquer.
A figura 5.5 ilustra a cópia de uma referência. Observe que, apesar de serem variáveis e
referência diferentes, o Objeto é o mesmo. Assim, uma alteração realizada pela referência
referencia 01 - variável 01 também será percebida pela referência referencia 02 - variável
02.
Um outro exemplo está no código da listagem 5.6. Lembre-se que array é um objeto,
logo terá sua referência copiada. O método alteraArray recebe um array de int. Este array
(que é um objeto) é criado no método main e passado como parâmetro para o método
passagemArray. Gerando a seguinte saída:

Antes:
1 2 3 4 5 6 7 8 9

Depois:
11 12 13 14 15 16 17 18 19

Figura 5.5: Comportamento das referências do Java

Listagem 5.4: Classe Pessoa utilizada no exemplo de passagem de parâmetros


1

2 public class Pessoa {


3 String nome;

http://solutioin.com 47
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

4 public Pessoa(String n) {
5 nome = n;
6 }
7 }

Listagem 5.5: Exemplo de passagem de parâmetros no Java


1 public class PassagemParametros {
2 static void metodoQualquer(int a) {
3 a++;
4 }
5

6 static void metodoQualquer(Pessoa p) {


7 p.nome = p.nome + "[NOME ALTERADO]";
8 }
9

10 public static void main(String[] args) {


11 System.out.println("Passagem tipo primitivo:");
12 int valor = 4;
13 System.out.printf("\nValor antes: %d", valor);
14 metodoQualquer(4);
15 System.out.printf("\nValor depois: %d", valor);
16

17 Pessoa pessoa = new Pessoa("Maria");


18 System.out.printf("\n\nValor antes: %s", pessoa.nome);
19 metodoQualquer(pessoa);
20 System.out.printf("\nValor depois: %s", pessoa.nome);
21 }
22 }

Listagem 5.6: Passagem de um array como parâmetro


1 public class PassagemArray {
2 static void alteraArray(int[] array) {
3 for (int i = 0; i < array.length; i++) {
4 array[i] += 10;
5 }
6 }
7

8 public static void main(String[] args) {


9 int[] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
10 System.out.println("\n\nAntes:");
11 for (int n : numeros) {
12 System.out.printf(" %d ", n);
13 }
14 alteraArray(numeros);
15 System.out.println("\n\nDepois:");
16 for (int n : numeros) {
17 System.out.printf(" %d ", n);
18 }
19 }
20 }

48 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

5.6. Arrays multidimensionais


É possível, mas não aconselhado, utilizar arrays multidimensionais no Java. Basta acrescen-
tar o par abre e fecha colchetes para cada dimensão. Note que os arrays criados até agora
possuem dimensão unitária. Um exemplo de array bi-dimenssional é:

int [][] matriz = new int [3][4];

Neste exemplo foi declarado um array bi-dimensional e inicializado com 3 x 4 posições


de armazenamento, podendo ser utilizado para representação de uma matriz com 3 linhas
e 4 colunas.

5.7. Lista de parâmetros com comprimento var-


iável
Mais uma funcionalidade acrescentada no Java 5 foi a Lista de parâmetros com compri-
mento variável: vararg. A declaração é feita utilizando o tipo, reticências e nome da var-
iável:

metodoQualquer(double ... variável){


}

Este exemplo cria o metodoQualquer que pode receber qualquer quantidade de valores
do tipo double:

metodoQualquer(1, 2, 3);
metodoQualquer(3.5, 6.4);
metodoQualquer();

São todas as chamadas válidas para metodoQualquer.


Um outro exemplo de vararg é o método printf. Note que este método pode receber uma
quantidade qualquer de parâmetros.
Para utilização de vararg deve-se seguir as seguintes regras:

1. Um método pode receber no máximo uma lista de parâmetros variáveis;

2. A lista de parâmetros variáveis deve ser o último argumento;

3. Entenda que a lista de parametros variáveis será convertida, pelo compilador, em um


array;

4. É possível passar de 0 a muitos parâmetros para um vararg;

O código da listagem 5.7 apresenta um exemplo de utilização de vararg. Esta classe


possui um método chamado calcularMedia(double . . . variável) que recebe uma quantidade
qualquer de parâmetros.

http://solutioin.com 49
Francisco Calaça, Otávio Calaça
Versão 1.1 arrays

Listagem 5.7: Exemplo de utilização de vararg


1 public class ExemploVararg {
2 public static double calcularMedia(double... notas) {
3 double soma = 0;
4 for(double n : notas){
5 soma += n;
6 }
7 return soma / notas.length;
8 }
9

10 public static void main(String[] args) {


11 double media = calcularMedia(5, 6, 5, 8);
12 System.out.printf("\nA média é: %f", media);
13 }
14 }

Também é possível utilizar vararg no método main, apesar de pouco usual:

public static void main(String ... args) {


}

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

5.8. Exercícios
1. O que são arrays?

2. Quais as formas de se declarar um array?

3. Explique o for aprimorado.

4. Como passar parâmetros para o método main?

5. Explique a passagem de parâmetros no Java.

6. O que são lista de parâmetros com comprimento variável?

7. Crie uma classe chamada Calculadora. Esta classe deverá possuir os métodos somar
e multiplicar que recebam uma quantidade variável de parâmetros do tipo double.
O método somar retorna a soma de todos eles e o método multiplicar o valor do
produto entre eles.

50 http://solutioin.com
Francisco Calaça, Otávio Calaça
U M P O U C O M A I S D E O R I E N TA Ç Ã O A
6
OBJETOS

No capítulo 4 foi realizada uma introdução à orientação a objetos. Neste capítulo será
apresentado mais detalhes deste novo paradigma: Encapsulamento, Herança, Abstração e
Polimorfismo. Estes elementos promovem o melhor reuso de software o que torna possível
a concepção de sistemas mais complexos e menos propensos a erros.
Outro assunto abordado neste capítulo é o coletor de lixo. Algumas tecnologias deman-
dam uma preocupação do desenvolvedor em desalocar recursos. Em Java não é necessário
preocupar-se com isto. Os objetos criados uma vez não mais referenciados são coletados
pelo Garbage Collector (Coletor de lixo).

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

6.1. Coletor de lixo


É chamado de heap space o espaço onde ficam armazenados os objetos Java instanciados.
Os objetos são criados pelo operador new e alocados no heap space em tempo de execução.
A coleta do lixo é o processo automático que remove os objetos que não estão sendo mais
referenciados liberando espaço neste heap space.
O coletor de lixo ou gc (garbage collector em inglês) é um processo executado paralelamente
à aplicação e é responsável pela liberação de memória.
Nas listagens 6.1 e 6.2 é apresentado uma demonstração de funcionamento do coletor de
lixo. Todas as instâncias de ObjetoColetado, ao serem instanciadas, escrevem a linha:

++ Construindo o objeto: 0

e toda as vezes que estas instâncias são finalizadas pelo gc, é executado o método
void finalize(). Desta forma, é impressa a linha:

-- Finalizando o objeto: 0

Assim a saída do programa é:

++ Construindo o objeto: 0
++ Construindo o objeto: 1

51
Versão 1.1 um pouco mais de orientação a objetos

++ Construindo o objeto: 2
++ Construindo o objeto: 3
-- Finalizando o objeto: 3
-- Finalizando o objeto: 2
. . .
++ Construindo o objeto: 1200
++ Construindo o objeto: 1201

Quando você executar na sua máquina o comportamento será ligeiramente diferente. Os


objetos coletados bem como a ordem que isto é realizado serão diferentes. Isto ocorre por
não ser possível prever o momento em que determinado objeto será coletado.
É possível solicitar à máquina virtual a invocação do coletor de lixo. Para isto, deve ser
executado o método System.gc(). Isto não é aconselhado uma vez que existe um algoritmo,
bastante otimozado, para realizar esta tarefa.
Listagem 6.1: Objeto a ser coletado na demonstração do coletor de lixo
1 public class ObjetoColetado {
2

3 int numero;
4

5 public ObjetoColetado(int n) {
6 numero = n;
7 System.out.printf("\n++ Construindo o objeto: %d", numero);
8 }
9

10 protected void finalize() throws Throwable {


11 System.out.printf("\n-- Finalizando o objeto: %d", numero);
12 }
13

14 }

Listagem 6.2: Demonstração do coletor de lixo


1

2 public class ExemploColetorLixo {


3

4 public static void main(String[] args) {


5 for (int i = 0; i < 5000; i++) {
6 new ObjetoColetado(i);
7 }
8 }
9

10 }

6.2. A palavra-chave this


A palavra chave this pode ser utilizada de duas formas:

• como método

52 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

• como referência

Quando utilizada como método, este acessa o construtor da própria classe. Observe que
um dos construtores do código abaixo:

public class Ponto {


public int x = 0;
public int y = 0;

//construtor
public Ponto(int a, int b) {
x = a;
y = b;
}

public Ponto() {
this(0, 0);
}
}

invoca um outro construtor com a chamada this(0, 0) passando os parâmetros para outro
construtor.
Quando utilizada como referência esta referencia o objeto da própria classe. Com this é
possível acessar os elementos da instância do objeto a partir da classe. Note que a palavra
chave this não pode ser utilizada dentro de contextos static porque nestes contextos não
são acessados a partir de instâncias da classe e sim diretamente. Lembre-se this acessa
membros do objeto criado a partir da classe em que é utilizado.
Por exemplo a classe Ponto pode ser escrita assim:

public class Ponto {


public int x = 0;
public int y = 0;

//construtor
public Ponto(int a, int b) {
x = a;
y = b;
}
}

Mas também pode ser escrito assim:

public class Ponto {


public int x = 0;
public int y = 0;

//construtor
public Ponto(int x, int y) {

http://solutioin.com 53
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

this.x = x;
this.y = y;
}
}

Cada argumento do segundo exemplo se possui o mesmo nome dos atributos da classe:
x e y. Para diferencia-los é utilizado this. A referência this indica que this.x e this.y são as
variáveis x e y da classe e não do construtor. Assim:

this.x = x;

Significa que o valor declarado de x será atribuido a um elemento da classe chamado x.

6.3. Variáveis do tipo final


Variáveis do tipo final são constantes no Java. Isto significa que:

• É obrigatória a inicialização;

• Após ser inicializada seu valor não pode mais ser alterado;

É um padrão utilizar letras maiúsculas nos identificadores de variáveis do tipo final:

final int CONSTANTE = 7;

6.4. Encapsulamento
Encapsulamento significa, na íntegra, colocar dentro de uma cápsula. Imagine o seguinte
cenário:
Um parque municipal, sem grades, muros, etc. Todos os visitantes podem entrar no
parque por qualquer lugar. O parque é muito extenso. Um dia o administrador do parque
deseja entregar um aviso dizendo que no dia seguinte não será aberto. Como entregar
os avisos? Dificil! O que fazer para facilitar a entrega de informações aos visistantes do
parque?
Solução: Criar grades ao redor do parque e colocar uma portaria! Assim qualquer aviso
a ser dado aos visitantes do parque pode ser dado por meio de uma determinada portaria.
Fica muito mais fácil avisar a todos uma vez que é obrigatória a passagem dos visitantes
pela portaria.
Encapsulamento é justamente isto. Significa fechar todas as entradas a um atributo e
construir uma portaria onde é possível entrar e sair valores para melhorar o controle sobre
os valores deste atributo.
Encapsulamento é um dos pilares da Orientação a Objetos e no java é feito da seguinte
forma:

• Para fechar todos os acessos utiliza-se o modificador de acesso private no atributo.


Este modificador impede que o atributo da classe possa ser acessado de outra classe.

54 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

• Para construir a “portaria” devem ser criados os métodos acessores: getAtributo()


para ler o resultado e setAtributo para gravar no atributo.

Suponha o seguinte atributo:

String nome;

Para ecapsulá-lo é necessário:


Proibir o acesso ao nome a partir de outra classe:

private String nome;

Construir os métodos acessores get. . . e set. . . :

public String getNome(){


}
public void setNome(String nome){
}

Apesar dos termos get e set estarem em inglês é obrigatório que estes sejam usados desta
forma. Mais adiante este padrão será necessário para correto funcionamento de determi-
nadas API’s.
Não se preocupe com isto. Hoje a maior parte das IDE’s fazem este trabalho.
No eclipse basta criar a classe, escrever os atributos nela (com o modificador private),
conforme a figura 6.1. Após isto clique com o botão direito na tela e selecione a opção
source - Generate getters and setters, conforme a figura 6.2. Clique nos parâmetros que
deseja criar os métodos getters e setters conforme a figura 6.3. A figura 6.4 apresenta os
métodos criados.

Figura 6.1: Exemplo do encapsulamento no eclipse: Criando o atributo

http://solutioin.com 55
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

Figura 6.2: Exemplo do encapsulamento no eclipse: Invocando o assistente para criação do encap-
sulamento

Figura 6.3: Exemplo do encapsulamento no eclipse: Escolha dos campos que serão encapsulados

56 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

Figura 6.4: Exemplo do encapsulamento no eclipse: Resultado final

6.5. Enumerações
As enumerações (ou enums) são tipos especiais de Java que permite lista limitada dos
valores. Estes valores podem ser passados às indicações de controle (switch(), if() ex.)
Em liberações prévias, a maneira padrão representar um tipo enumerated era o teste
padrão interno de Enum: teste padrão interno de Enum - tem problemas severos!

final static public int INVERNO = 0;


final static public int PRIMAVERA = 1;
final static public int VERAO = 2;
final static public int OUTONO = 3;

Este teste padrão tem muitos problemas, como:

• Como os tipos são int é possível passar o número 10, por exemplo, que não corre-
sponde a nenhuma estação do ano.

• É provável que ocorram conflitos entre constantes, por exemplo, pode existir uma
constante MASCULINO = 1 que conflitará com PRIMAVERA, ou seja, neste caso
PRIMAVERA = MASCULINO!.

6.6. Pacotes
Para facilitar a localização, melhorar a organização e os conflitos de nomes entre classes é
utilizado pacotes que agrupam tipos relacionados.
Definição: Um pacote é um agrupamento de tipos relacionados que facilitam o gerencia-
mento de algumas classes.

http://solutioin.com 57
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

Os tipos (classes, enumerações, interfaces) que fazem parte da plataforma java sao mem-
bros de vários pacotes como:

• Pacote java.lang, classes fundamentais do java

• Pacote java.io, classes para leitura e escrita em dispositivos

É possível colocar as suas classes dentro de pacotes também, utilizando a palavra chave
package:

package livro.capitulo08;

Não é permitida a existência de mais que uma declaração package. Isto se dá pelo fato
de que um tipo (classe, enum ou interface) pode estar em apenas um pacote.
A declaração package deve ser a primeira declaração do arquivo. Antes dos import’s,
antes de tudo.
Suponha que você escreveu um grupo de classes que representa objetos gráficos, como
círculos, retângulos, linhas e pontos.

public class Circulo {


. . .
}

public class Retangulo{


. . .
}

public class Ponto{


. . .
}

public class Linha{


. . .
}

Você deve colocar estas classes em um pacote por várias rasões, incluindo:

• Você ou outros programadores podem facilmente determinar que estes tipos estão
relacionados entre si.

• Você e outros programadores sabem onde encontrar os tipos que fornecem funcional-
idades gráficas.

• Os nomes dos seus tipos não conflitarão com os nomes de tipos com outros pacotes

• Você pode permitir tipos que serão acessados apenas por elementos de dentro do
mesmo pacote ou tipos que serão acessados externamente

58 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.6.1 Como usar tipos dentro de outros pacotes


É possível utilizar tipos (classes, enums ou interfaces) dentro de outros pacotes de três
formas:

• Referencie o tipo com o seu nome qualificado. Ex.: java.util.Date

• Importe o tipo: import java.util.Date

• Importe todos os tipos dentro do pacote: import java.util.*

A listagem 6.3 apresenta esses três exemplos. Nesta listagem é possível ver a declaração
de:

• import java.io.* - que importa todos os tipos do pacote java.io

• import java.util.Date - que importa apenas o tipo Date do pacote java.util

• java.util.List - que referencia diretamente o tipo dentro do pacote sem a necessi-


dade do import.

Listagem 6.3: Exemplo de uso de pacotes


1 import java.io.*;
2 import java.util.Date;
3

4 public class ExemploPacote {


5

6 public static void main(String[] args) {


7 /*
8 * A classe Date foi importada através da declaração:
9 * import java.util.Date;
10 * contida no cabeçalho da classe
11 */
12 Date hoje = new Date();
13 System.out.println(hoje);
14

15 /*
16 * Note a referência direta à List, sem a necessidade
17 * de realizar um import.
18 */
19 java.util.List lista = new java.util.ArrayList();
20

21 /*
22 * Esta classe foi importada do pacote java.io, através
23 * da declaração:
24 * import java.io.*;
25 */
26 File arquivo = new File("c:\\ arquivo.txt");
27 }
28 }

http://solutioin.com 59
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.7. Herança
Na Orientação a Objetos uma classe pode derivar de outras classes atributos e métodos.
Uma classe que deriva, ou herda de outra classe é chamada de subclasse (também
classe derivada, classe extendida, ou classe filha). A classe é herdada por uma subclasse é
chamada de superclasse (também classe ancestral, classe pai).
A Herança define uma especialização. Desta forma uma subclasse, pode ser entendida
como uma especialização de determinada classe. Por exemplo, seja a classe Medico. Uma
especialização é Pediatra. Desta forma, um Pediatra possui todos os métodos e atributos
de Medico, afinal um Pediatra ainda é Medico. Mas, além destes, possui também atributos
e métodos específicos de Pediatra.
Exceto a classe Object, que não possui superclasses, todas as classes tem uma, e somente
uma superclasse direta (herança simples). Se uma classe não tiver herdando de outra ex-
plicitamente, então esta herda da classe Object de forma implícita.
Heraça somente é aplicado a atributos e métodos de classes. Construtores não são herda-
dos por herança.

6.7.1 Um exemplo de Herança


O código da listagem 6.4 apresenta a classe Pessoa que será ancestral das demais classes
em nosso exemplo. Observe a existencia dos atributos nome e telefone nesta classe.
A classe Aluno, apresentada na listagem 9.14, herda de pessoa. Esta herança faz comv
que Aluno também possua os atributos e métodos de Pessoa, como nome e telefone.
A listagem 6.6 apresenta o uso das classes Aluno e Pessoa. Note que o método imprim-
irDados é utilizado para imprimir os dados referentes à classe.

Listagem 6.4: Classe Pessoa


1

2 public class PessoaFisica {


3

4 private String nome;


5 private String telefone;
6

9 public PessoaFisica(String nome, String telefone) {


10 this.nome = nome;
11 this.telefone = telefone;
12 }
13

14 public void imprimirDados(){


15 System.out.printf("\nNome: %s - Telefone :%s", nome, telefone);
16 }
17

18 public String getNome() {


19 return nome;
20 }

60 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

21 public void setNome(String nome) {


22 this.nome = nome;
23 }
24 public String getTelefone() {
25 return telefone;
26 }
27 public void setTelefone(String telefone) {
28 this.telefone = telefone;
29 }
30 }

Listagem 6.5: Classe Aluno - filha de Pessoa


1

2 public class Aluno extends PessoaFisica{


3

4 private double nota;


5

6 public Aluno(String nome, String telefone, double nota) {


7 super(nome, telefone);
8 this.nota = nota;
9 }
10

11 public void imprimirDados() {


12 super.imprimirDados();
13 System.out.printf(" Nota: %.2f", nota);
14 }
15

16 public double getNota() {


17 return nota;
18 }
19

20 public void setNota(double nota) {


21 this.nota = nota;
22 }
23 }

Listagem 6.6: Exemplo da utilização da herança com as classes Pessoa e Aluno


1

2 public class ExemploHeranca {


3

4 public static void main(String[] args) {


5 PessoaFisica pessoa = new PessoaFisica("Maria", "3231 -2323");
6 Aluno aluno = new Aluno("Claudia", "3132 -5656", 8.5);
7

8 pessoa.imprimirDados();
9 aluno.imprimirDados();
10 }
11

12 }

http://solutioin.com 61
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.7.2 Sobrescrita de métodos


Note que a classe Aluno possui um método com mesmo nome e assinatura de sua ancestral,
Pessoa. A isto da-se o nome de sobrescrita de métodos. Mais adiante será apresentado o
Polimorfismo e a Sobrescrita de métodos possui papel fundamental no Polimorfismo.

6.7.3 A palavra-chave super


A palavra chave super pode ser utilzada de duas formas:

• como método

• como referência.

Quando utilizada como método, este acessa o método construtor da classe Pai. Note
no construtor da classe da listagem 9.14 que foi utilizado super(nome, telefone); para
referenciar o construtor da super-classe.
Quando utilizada como referência, este acessa métodos ou membros da classe Pai. Note
no método imprimirDados() o uso de super.imprimirDados(); para também imprimir os
dados de pessoa.

6.8. Alguns Modificadores de acesso


Veja agora o uso de quatro modificadores de acesso:

6.8.1 private
A palavra private restringe o acesso do método ou do atributo somente à classe que o
definiu, ou seja, um método ou atributo privado só poderá ser acesso dentro da classe que
o definiu.! A listagem 6.4 descreve uma classe que possui um atributo com esse modificador.
Veja que não é possível acessar o atributo nome de fora desta classe.

6.8.2 pacote
É utilizado quando não existe nenhum modificador de acesso antes da variável. Restringe
o acesso somente a classes definidas dentro do mesmo pacote, ou seja, quando não é infor-
mado nenhum modificador de acesso, o elemento pode apenas ser acessado de uma classe
que esta no mesmo pacote.

62 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.8.3 protected
Ele é um pouco mais liberal que o modificador padrão ou pacote, pois ele permite que um
método de uma classe definida em um pacote possa ser acessado por uma classe definida
em outro pacote desde que esta classe seja filha da anterior.

6.8.4 public
Um método público pode ser acessado por qualquer classe em qualquer pacote. Utilizado
para estabelecer uma interface entre os componentes do programa.
É boa prática definir todos os membros de uma classe private e ir aumentando a acessi-
bilidade quando for necessário. Evite criar tudo do tipo public.

6.9. Classe object


A classe Object é uma classe que serve de superclasse para todas as classes existentes em
Java. Isso significa que ao criar uma classe, se não for especificada nenhuma superclasse
após a palavra extends, então a classe Object será assumida automaticamente como su-
perclasse. Portanto toda classe é subclasse de Object, e com isso herda alguns métodos
automaticamente.

6.9.1 método equals()


Um método muito interessante presente na classe Object é o equals. Suponha que haja duas
instâncias de uma mesma classe e é necessário testar se elas contém a mesma informação.
O operador:
==

retorna apenas o valor true apenas se seus operandos forem precisamente o mesmo objeto.
Porém, o operador equals retorna quando os objetos contém o mesmo estado, através da
comparação campo-a-campo.
Por exemplo, eu e você podemos ter carro do mesmo modelo. Nesse caso:
meuCarro == seuCarro

seria false pois embora nossos carros sejam do mesmo modelo, são carros diferentes. En-
tretanto,
meuCarro.equals(seuCarro);

poderia ser true se os atributos de ambos os carros fossem idênticos, por exemplo, mesmo
ano, mesma cor, etc.
A listagem 6.7 apresenta um exemplo de comparação de objetos. Note que apesar das
Strings possuirem o mesmo valor: texto, ao compará-las com == não é visto o resultado
esperado. Apenas com equals.

http://solutioin.com 63
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

A saída deste exemplo é:

s1 = texto
s2 = texto
s1 diferente de s2 com ==
s1 igual a s2 com equals

Listagem 6.7: Exemplo de comparação entre objetos com equals


1 public class ExemploEquals {
2

3 public static void main(String[] args) {


4 String s1 = new String("texto");
5 String s2 = new String("texto");
6

7 System.out.printf("s1 = %s\n", s1);


8 System.out.printf("s2 = %s\n", s2);
9

10 if (s1 == s2) {
11 System.out.println("s1 igual a s2 com ==");
12 } else {
13 System.out.println("s1 diferente de s2 com ==");
14 }
15

16 if (s1.equals(s2)) {
17 System.out.println("s1 igual a s2 com equals");
18 } else {
19 System.out.println("s1 diferente de s2 com equals");
20 }
21

22 }
23

24 }

6.9.2 método toString()


Outro método bastante utilizado da classe Object é o método toString. Este método é
invocado pela máquina virtual toda vez que se deseja converter determinado objeto em
String.
O código da listagem 6.8 apresenta um exemplo de utilização do toString. Observe no
método main o código:

System.out.println(exemplo);

Este código imprime o objeto e, ao ser convertido em String para a impressão, a máquina
virtual executará o método toString para descobrir como fazer isto.

Listagem 6.8: Exemplo de utilização do método toString


1

64 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

2 public class ExemploToString {


3

4 public String toString() {


5 return "Exemplo da implementação do toString";
6 }
7

8 public static void main(String[] args) {


9 ExemploToString exemplo = new ExemploToString();
10 System.out.println(exemplo);
11 }
12 }

6.10. Polimorfismo
Uma característica importante das classes reside no fato de que as subclasses de uma dada
classe são consideradas do mesmo tipo de seu parente.
Assim no exemplo anterior de Pessoa e Aluno, pode-se dizer que Aluno é do tipo Pessoa,
ou seja, Aluno é uma Pessoa. Note que a herança define, desta forma, o relacionamento É
UM. Nestes casos também é possível que exista a sobrescrita de métodos. Isto permite a
realização de uma mesma operação sobre diferentes tipos de classes, desde que mantenham
algo em comum. Este efeito se chama Polimorfismo.

6.10.1 Abstração
Para que você entenda melhor a abstração veja um exemplo com o mundo real. Tome
inicialmente algumas verdades:

1. Todo animal locomove;

2. Todo Peixe é um animal;

3. Todo Sapo é um animal;

4. Todo Tigre é um animal;

Pergunta: Como o Animal Locomove? A resposta é complicada pois Peixes, Sapos e


Tigres se locomovem de forma diferente. Na verdade a resposta é: depende.
Mas, para cumprir a verdade 1, que todo animal se locomove, é necessário definir um
método locomover em animal. Mesmo não sabendo ainda como este o faz: nadando, pu-
lando ou correndo.
É neste cenário que entra o conceito de abstração: Existe, mas não é possível saber como
é, como é feito.
Desta forma, o método locomover deve ser abstrato utilzando a palavra chave abstract.
Para isto deve-se cumprir algumas regras:

• Todo método abstrato não possui corpo, ou seja, no lugar dos é colocado ponto-
vírgula: ;.

http://solutioin.com 65
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

• Quando uma classe possui pelo menos um método abstrato, esta também deve ser
declarada como abstrata

• As classes abstratas não podem ser instanciadas.

• As classes filhas de uma classe abstrata devem, obrigatoriamente ou implementar os


métodos abstratos da classe pai, ou também ser abstrata.

6.10.2 Exemplo de Polimorfismo


Para explicar melhor o Polimorfismo veja o exemplo da folha de pagamento de uma em-
presa.
O código da listagem 6.9 apresenta a classe Empregado. Observe que esta classe é ab-
strata (pelo modificador abstract na sua declaração). O método calcularSalario também
é abstrato, pois apesar de todos os empregados possuirem salário, esta característica só
poderá ser descrita se for possível saber o tipo de empregado: Assalariado, Comissionado
ou Horista.
A classe Empregado herda de Pessoa os atributos nome e telefone, não sendo mais
necessários sua implementação. Essa classe também sobrescreve o método toString que
define um comportamento personalizado quando for necessário a converssão de objetos
do tipo Empregado em String.
O código da listagem 6.10 apresenta a classe EmpregadoAssalariado. Esta classe herda
de Empregado alguns métodos, inclusive os de Pessoa. É possível dizer que EmpregadoAs-
salariado é um Empregado e por consequencia, uma Pessoa.
A classe EmpregadoAssalariado não é abstrata, logo deve obrigatoriamente implementar
o método calcularSalario. Observe que, para EmpregadoAssalariado, é possível dizer como
se calcula o salário. Basta retornar o salário mensal do empregado.
O código da listagem 6.11 apresenta a classe EmpregadoComissionado. Esta classe tam-
bém herda de Empregado alguns métodos.
Note que o método calcularSalario de EmpregadoComissionado retorna o resultado da
multiplicação das vendas brutas com o valor da comissão do empregado.
O código da listagem 6.12 apresenta a classe EmpregadoHorista. Esta classe também é
filha de Empregado. O seu método calcularSalario também é específico apenas para empre-
gados que trabalham por hora.
Até agora forão apresentadas quatro classes em nosso exemplo:

• Empregado

• EmpregadoAssalariado

• EmpregadoComissionado

• EmpregadoHorista

Todos estes empregados são do tipo Pessoa. Os empregados assalariados, horistas e


comissionados são do tipo empregados. Isto se deve por causa da herança.
Para finalizar este exemplo será construída a classe FolhaPagamento, descrita na listagem
6.13. Obseve neste exemplo que todos os empregados são instanciados e colocados em um

66 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

array de tipos Empregado. Quando este array é iterado pelo for os dados salariais são
impressos de acordo com o tipo de empregado. Isto é o polimorfismo: Apesar de todos os
empregados possuirem o método calcularSalario, este se comporta de forma diferente em
função do tipo do empregado.
Polimorfismo quer dizer: várias formas de executar a mesma ação, ou seja, várias formas
de executar o calcularSalario.

Listagem 6.9: Código da classe Empregado


1

2 public abstract class Empregado extends PessoaFisica {


3

4 public Empregado(String nome, String telefone) {


5 super(nome, telefone);
6 }
7

8 public String toString() {


9 return String.format("Nome:%s Telefone :%s Salario :%.2f" , getNome(),
10 getTelefone(), calcularSalario());
11 }
12

13 public abstract double calcularSalario();


14

15 }

Listagem 6.10: Código da classe EmpregadoAssalariado


1

2 public class EmpregadoAssalariado extends Empregado{


3

4 private double salario;


5

6 public EmpregadoAssalariado(String nome, String telefone, double salario) {


7 super(nome, telefone);
8 this.salario = salario;
9 }
10

11 public double calcularSalario() {


12 return salario;
13 }
14

15 public double getSalario() {


16 return salario;
17 }
18

19 public void setSalario(double salario) {


20 this.salario = salario;
21 }
22 }

Listagem 6.11: Código da classe EmpregadoComissionado


1

http://solutioin.com 67
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

2 public class EmpregadoComissionado extends Empregado{


3

4 private double vendasBrutas;


5 private double comissaoVendas;
6 public EmpregadoComissionado(String nome, String telefone,
7 double vendasBrutas, double comissaoVendas) {
8 super(nome, telefone);
9 this.vendasBrutas = vendasBrutas;
10 this.comissaoVendas = comissaoVendas;
11 }
12

13 public double calcularSalario() {


14 return vendasBrutas * comissaoVendas;
15 }
16

17 public double getVendasBrutas() {


18 return vendasBrutas;
19 }
20

21 public void setVendasBrutas(double vendasBrutas) {


22 this.vendasBrutas = vendasBrutas;
23 }
24

25 public double getComissaoVendas() {


26 return comissaoVendas;
27 }
28

29 public void setComissaoVendas(double comissaoVendas) {


30 this.comissaoVendas = comissaoVendas;
31 }
32 }

Listagem 6.12: Código da classe EmpregadoHorista


1

2 public class EmpregadoHorista extends Empregado{


3

4 private int qtdHoras;


5 private double valorHora;
6 public EmpregadoHorista(String nome, String telefone, int qtdHoras,
7 double valorHora) {
8 super(nome, telefone);
9

10 this.qtdHoras = qtdHoras;
11 this.valorHora = valorHora;
12 }
13

14 public double calcularSalario() {


15 return qtdHoras * valorHora;
16 }
17

18 public int getQtdHoras() {


19 return qtdHoras;

68 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

20 }
21

22 public void setQtdHoras(int qtdHoras) {


23 this.qtdHoras = qtdHoras;
24 }
25

26 public double getValorHora() {


27 return valorHora;
28 }
29

30 public void setValorHora(double valorHora) {


31 this.valorHora = valorHora;
32 }
33 }

Listagem 6.13: Código da classe FolhaPagamento


1

2 public class FolhaPagamento {


3

4 public static void main(String[] args) {


5 Empregado [] empregados = new Empregado[3];
6 empregados[0] = new EmpregadoAssalariado("Maria", "231 -1234", 1500);
7 empregados[1] = new EmpregadoComissionado("Antonio", "241 -9876", 5000, 0.25);
8 empregados[2] = new EmpregadoHorista("Jose", "241 -9876", 40, 50);
9

10 for (int i = 0; i < empregados.length; i++) {


11 System.out.println(empregados[i]);
12 }
13

14 }
15

16 }

6.11. Conversão e casting


Após ter sido colocados, no exemplo da seção anterior, todos os empregados no Array
empregados como pode ser obtido o valor da comissão do empregado comissionado?
Observe que dentro do laço for isto não é mais possível pois todos os empregados são
tratados como do tipo Empregado.
Para isto existe o casting. A tradução de casting é atuar. Com o casting é possível fazer
o Empregado atuar como EmpregadoComissionado e assim buscar o valor da comissão.
Assim como nos filmes não é qualquer ator que pode atuar em um determinado papel,
também não será qualquer objeto que poderá atuar como EmpregadoComissionado, ape-
nas aqueles que foram instanciados como tal.
O casting é feito colocando o tipo desejado dentro de parêntesis na frente do objeto:

EmpregadoComissionado empComiss = (EmpregadoComissionado) empregados[i];

http://solutioin.com 69
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.11.1 A palavra-chave instanceof


Para testar o objeto é instancia de determinada classe e consequentemente pode ser feito
uma operação de casting dele para essa classe é utilizado a palavra-chave instanceof.
O código da listagem 6.14 apresenta um exemplo de utilização do operador instanceof.
Observe o teste do objeto empregados[i]. Este teste retornará true se esse objeto for do tipo
EmpregadoComissionado.

if(empregados[i] instanceof EmpregadoComissionado){


. . .
}

Listagem 6.14: Exemplo de utilização do operador instanceof


1

2 public class FolhaPagamentoMelhorado {


3

4 public static void main(String[] args) {


5 Empregado [] empregados = new Empregado[3];
6 empregados[0] = new EmpregadoAssalariado("Maria", "231 -1234", 1500);
7 empregados[1] = new EmpregadoComissionado("Antonio", "241 -9876", 5000, 0.25);
8 empregados[2] = new EmpregadoHorista("Jose", "241 -9876", 40, 50);
9

10 for (int i = 0; i < empregados.length; i++) {


11 System.out.println(empregados[i]);
12 if(empregados[i] instanceof EmpregadoComissionado){
13 EmpregadoComissionado empComiss = (EmpregadoComissionado) empregados[i];
14 System.out.printf("\nEmpregado comissionado , comissão: %d",
15 empComiss.getComissaoVendas());
16 }
17 System.out.println();
18 }
19

20 }
21

22 }

6.12. Métodos e classe do tipo final


Em uma seção anterior foi apresentado que variáveis do tipo final representam constantes.
O modificador final também pode ser usando em classes e em métodos.
Uma classe do tipo final não pode ser herdada, ou seja, não pode ter sub-classes.
Um método do tipo final não pode ser sobrescrito.

70 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

6.13. Interfaces
Interfaces são equivalentes a classes com todos os métodos abstratos. A palavra chave
interface é utilizada para declara-la.
Há um vários motivos na engenharia de software onde é importante que os progra-
madores concordem com um contrato que diz como determinados componentes de soft-
ware se comunicarão. Cada grupo precisa estar habilitado a escrever código sem o conhec-
imento de como este trabalha. Geralmente estes contratos são as interfaces.
É como dirigir! Vários tipos de motoristas, em locais diferentes do mundo, é capaz de
dirigir qualquer carro sem conhecer como este funciona. Porque para os motoristas basta
conhcecer a interface que faz o carro funcionar. Para o motorista, basta saber que o freio,
acelerador, câmbio, etc, se comportarão conforme ele espera. Não é necessário saber se o
carro possui direção elétrica ou hidráulica, como foi implementado os freios ou se o motor
funciona com combustíveis renováveis ou não. Basta conhecer a interface de comunicação
que é oferecida ao motorista.
Outro exemplo são os eletrodomésticos. Quando você adquire um eletrodoméstico, como
um liquidificador, não é necessário preocupar-se se os plugues deste servirá nas tomadas
de nossas casas. Existe a certeza que sim porque o fabricante do eletrodoméstico construiu
o plugue de acordo com a interface das tomadas residenciais.

6.13.1 Interfaces em Java


Em Java as interfaces também são tipos de dados similar às classes. As interfaces contém
apenas constantes, e assinaturas de métodos. Os métodos não possuem corpo. Interfaces
não podem ser instanciadas. São somente implementadas por classes ou herdadas de outras
interfaces.
O código da listagem 6.15 apresenta um exemplo de interface. Note o uso da palavra-
chave interface e que os métodos desta não possuem corpo, apenas estão declarados.
Os códigos das listagens 6.17 e 6.16 apresentam as classes que implementam a interface
Animal. Observe o uso da palavra chave implements.
Na listagem 6.18 é apresentado a utilização das interfaces. Note o uso do método newIn-
stance para instanciação das classes. Nesta classe é apresentado um prompt para o usuário
indagando-o qual animal deseja instanciar.
Após a instanciação do animal é executado os métodos alimentar e locomover deste.
Não se preocupe com o uso das palavras-chaves: try e catch. Apenas utilize conforme o
exemplo. Em um capítulo posterior será apresentado mais detalhes sobre estas palavras.

Listagem 6.15: Interface Animal


1

3 public interface Animal {


4

5 void alimentar();
6 void locomover();
7

http://solutioin.com 71
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

8 }

Listagem 6.16: Classe Aguia para o exemplo de interfaces


1

3 public class Aguia implements Animal{


4

5 public void alimentar() {


6 System.out.println("A águia caça a sua presa em voo e a devora!");
7 }
8

9 public void locomover() {


10 System.out.println("A águia se locomove voando!");
11 }
12

13 @Override
14 public String toString() {
15 return "Aguia";
16 }
17 }

Listagem 6.17: Classe Tigre para o exemplo de interfaces


1

3 public class Tigre implements Animal{


4

5 public void alimentar() {


6 System.out.println("O tigre caça a sua presa e a devora!");
7 }
8

9 public void locomover() {


10 System.out.println("O tigre se locomove correndo!");
11 }
12

13 @Override
14 public String toString() {
15 return "Tigre";
16 }
17

18 }

Listagem 6.18: Exemplo da aplicação de interfaces


1

4 public class Zoo {


5

6 public static void main(String[] args) {


7 Animal [] animais = new Animal[2];
8 animais[0] = new Aguia();

72 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

9 animais[1] = new Tigre();


10 for (Animal a : animais) {
11 System.out.println(a);
12 a.alimentar();
13 a.locomover();
14 }
15

16 }
17

18 }

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

6.14. Exercícios
1. O que é o coletor de lixo?

2. Explique a referência this.

3. O que é encapsulamento?

4. O que são enumerações? Crie um Enum para representar o estado civil.

5. O que são pacotes?

6. Qual a relação entre pacotes e diretórios?

7. O que é herança?

8. O que é sobrescrita de métodos?

9. Explique a palavra chave super.

10. Qual a diferença entre a palavra-chave super e a palavra-chave this?

11. Explique o modificador de acesso protected.

12. O que é a classe Object?

13. Qual a diferença entre utilizar == e equals para comparar objetos?

14. Para que serve o método toString?

15. O que é polimorfismo?

16. O que é casting?

http://solutioin.com 73
Francisco Calaça, Otávio Calaça
Versão 1.1 um pouco mais de orientação a objetos

17. Explique a utilidade do operador instanceof.

18. O que são interfaces?

74 http://solutioin.com
Francisco Calaça, Otávio Calaça
T R ATA M E N T O D E E X C E Ç Õ E S
7
Os aplicativos devem estar preparados para resolver situações inesperadas como quando
um usuário digita um campo texto onde devia ser numérico ou uma data fora do padrão.
Nestes casos ocorrem exceções à forma normal da execução da rotina. Neste capítulo será
apresentado o mecanismo de exceções do Java, as palavras chaves try cath throw e throws.

7.1. O que são exceções


Uma exceção é um evento, que ocorre durante a execução de um programa, e interrompe
o fluxo normal deste.
Quando ocorre uma exceção em um método, este cria um objeto que contem informaçoes
sobre o tipo de exceção, ou erro, incuido o seu tipo, o estado do programa, a pilha de
chamada de métodos. Quando é criada uma exceção esta deve ser lançada para que possa
ser capturada em um local específico.
Depois do método ter laçado uma exceção, a execução do sistema procurará, na pilha de
chamada de métodos, algum bloco de código que poderá manipular essa exceção.
As instruções que serão executadas para manipular determinada exceção deve ser es-
crito dentro de blocos catch (Em inglês, capturas). Se não for encontrado um bloco catch
apropriado para tratar a exceção, o programa terminará.

7.2. Como tratar exceções


7.2.1 O bloco try
O primeiro passo para tratar exceções é envolver o código que pode lançar uma com um
bloco try. Em geral, o bloco try é escrito da seguinte forma:

try {
código que pode lançar exeção
}
catch(Exception e){
código que será exeucutado quando uma exceção ocorrer.
}

Observe que todo o código que poderá lançar alguma exceção é colocado dentro de um
bloco try.

75
Versão 1.1 tratamento de exceções

7.2.2 O bloco catch


As exceções são associadas a tipos. Mais adiante você saberá sobre estes tipos. Qualquer
erro que pode ocorrer dentro de um bloco try poderá ser capturado por um bloco catch.
Neste bloco deve ficar todo o código necessário ao tratamento de determinada exceção
como, por exemplo, apresentar uma mensagem de erro ao usuário.
O código da listagem 7.1 apresenta um exemplo de código em que pode acontecer os
seguintes erros:

• O usuário pode informar um valor não numérico.

• O usuário pode informar zero no denominador.

Como exercício, escreva este código e execute. Tente executá-lo passando informações
incorretas, como zero no denominador, ou valores não numéricos.
Para tratar estes erros adequadamente utilize o bloco try . . . catch.
O código da listagem 7.2 apresenta o código da listagem 7.1 com tratamento de erros.
Observe que os possíveis locais para ocorrencia de erros são:

int numerador = new Integer(numeradorString);


int denominador = new Integer(denominadorString);

Quando o usuário informar um valor não numérico e este o programa tentar converte-lo
para int.
outro local:

int quociente = numerador / denominador;


int resto = numerador % denominador;

Quando o usuário informar ZERO como denominador.


Para tratar estes dois possíveis erros estes códigos foram envolvidos com o bloco try e os
blocos catch’s responsáveis pelo tratamento de cada erro específico:

catch (NumberFormatException e) {
showMessageDialog(null, "Informe apenas números inteiros.");
} catch (ArithmeticException e) {
showMessageDialog(null, "O denominador não pode ser ZERO.");
}

Observe que é possível colocar quantos blocos catch’s quantos forem necessários e que
as exceções possuem tipos, neste caso, NumberFormatException para erros de formatação
numérica e ArithmeticException para erros de aritimética, como divisão por zero.
Em cada bloco catch foi adicionado o código necessário para tratar este tipo de erro,
neste caso, apenas a apresentação de uma mensagem ao usuário.

76 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 tratamento de exceções

Listagem 7.1: Exemplo de código que poderá lançar uma exceção


1 package capitulo7;
2

3 import javax.swing.JOptionPane;
4

5 public class Divisao {


6

7 public static void main(String[] args) {


8 String numeradorString = JOptionPane.showInputDialog("Digite o númerador:");
9 String denominadorString = JOptionPane.showInputDialog("Digite o denominador:");
10

11 int numerador = new Integer(numeradorString);


12 int denominador = new Integer(denominadorString);
13

14 int quociente = numerador / denominador;


15 int resto = numerador % denominador;
16

17 String texto = String.format("Quociente :%d, Resto:%d", quociente,


18 resto);
19

20 JOptionPane.showMessageDialog(null, texto);
21 }
22 }

Listagem 7.2: Exemplo do tratamento de exceções


1 package capitulo7;
2

3 import javax.swing.JOptionPane;
4

5 public class DivisaoMelhorado {


6

7 public static void main(String[] args) {


8 String numeradorString = JOptionPane.showInputDialog("Digite o númerador:");
9 String denominadorString = JOptionPane.showInputDialog("Digite o denominador:");
10

11 try {
12 int numerador = new Integer(numeradorString);
13 int denominador = new Integer(denominadorString);
14

15 int quociente = numerador / denominador;


16 int resto = numerador % denominador;
17

18 String texto = String.format("Quociente :%d, Resto:%d",


19 quociente, resto);
20

21 JOptionPane.showMessageDialog(null, texto);
22 } catch (NumberFormatException e) {
23 JOptionPane.showMessageDialog(null, "Informe apenas números inteiros.");
24 } catch (ArithmeticException e) {
25 JOptionPane.showMessageDialog(null, "O denominador não pode ser ZERO.");
26 }

http://solutioin.com 77
Francisco Calaça, Otávio Calaça
Versão 1.1 tratamento de exceções

27 }
28 }

7.3. Exceções checadas e exceções não checadas


O Java possui dois tipos de exceções:

• as checadas em tempo de compilação;

• as não checadas em tempo de compilação;

As exceções checadas em tempo de compilação devem, obrigatoriamente, serem tratadas


na compilação, ou seja, o uso do try . . . catch é obrigatório. Em capítulos posteriores serão
apresentados elementos que lançam exceções que possuem essa característica - obrigato-
riedade no tratamento.
As exceções não checadas em tempo de compilação não possuem obrigatoriedade no
seu tratamento. As exceções apresentadas no código da listagem 7.2 não possuem esta
obrigatoriedade. Todas as exceções não checadas devem herdar de RuntimeException ou
suas subclasses.
Porque os projetistas decidem em forçar um método a lançar uma exceção? Qualquer
exceção checada pode ser lançada por um método como parte da lógica do método como
tratamento de erros de usuário, etc.
A próxima questão é: Se é interessante lançar exceções checadas e obrigar o tratamento
no código, porque lançar exceções que herdam de RuntimeException, ou seja, exeções não
checadas?
A resposta é que qualquer exceção não checada representa um erro do sistema, como
divisão por zero, acesso a elementos inexistentes de arrays, etc.
Em Geral, não lance uma RuntimeException ou sua subclasse simplesmente porque você
não quer obrigar o tratamento de determinado problema.
Uma boa regra para lançamento de exceções é: Se a aplicação cliente pode resolver o
problema lance uma exceção checada em tempo de compilação. Se a aplicação cliente não
pode resolver, lance uma exceção não checada em tempo de compilação.

7.4. Como declarar novos tipos de exceções


Toda exceção deve, obrigatoriamente, herdar de Exception. O código da listagem 7.3 apre-
senta um exemplo. Lembre-se que quando a exceção herda de RuntimeException (que é
subclasse de Exception) esta torna-se uma exceção não checada. Se a exceção não herdar
de RuntimeException (ou suas subclasses) ela passa a ser uma exceção checada.
Observe que a classe Exception herda de Throwable, ou seja, toda exceção é do tipo
throwable.

Listagem 7.3: Exemplo de declaração de uma nova exceção


1 package capitulo7;
2

78 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 tratamento de exceções

3 public class AutenticacaoException extends Exception{


4

5 public AutenticacaoException(String mensagem) {


6 super(mensagem);
7 }
8

9 }

7.5. Como lançar exceções


É utilizada a palavra chave throw para lançar uma exceção:

throw new AutenticacaoException("Erro ao realizar a autenticação");

Observe que a expressão throw necessita apenas de um argumento: O objeto do tipo


Throwable.
O código da listagem 7.4 mostra um exemplo. Observe o método autenticar. Ele verifica
duas coisas: Se o login estiver vazio e se a senha e o login informado estão corretos. Note
que para cada tipo de problema é lançada a Exceção AutenticacaoException com uma men-
sagem apropriada. O método main invoca o método autenticar e este captura as exceções
do tipo AutenticacaoException mostrando a mensagem para o usuário.

Listagem 7.4: Exemplo de lançamento de uma exceção


1 package capitulo7;
2

3 import javax.swing.JOptionPane;
4

5 public class Autenticador {


6

7 public static void autenticar(String login, String senha) throws


AutenticacaoException{
8 /*
9 * Verifica se o usuário digitou um login.
10 */
11 if(login.length() == 0){
12 throw new AutenticacaoException("Login vazio");
13 }
14

15 /*
16 * Verifica o login e a senha do usuário.
17 * Esta verificação normalmente é feita com dados vindos de um Banco de Dados
18 * ou LDAP. Colocamos o usuario e a senha no código para facilitar
19 * o entendimento.
20 */
21 if(!"java".equals(login) || !"123".equals(senha)){
22 throw new AutenticacaoException("Usuário ou senha inválidos");
23 }
24 }

http://solutioin.com 79
Francisco Calaça, Otávio Calaça
Versão 1.1 tratamento de exceções

25

26 public static void main(String[] args) {


27 String login = JOptionPane.showInputDialog("Digite o Login:");
28 String senha = JOptionPane.showInputDialog("Digite a Senha:");
29 try {
30 autenticar(login, senha);
31 JOptionPane.showMessageDialog(null, "Autenticado");
32 } catch (AutenticacaoException e) {
33 JOptionPane.showMessageDialog(null, e.getMessage());
34 }
35 }
36

37 }

7.6. Hierarquia das exceções


A Hierarquia das exceções é apresentada na figura 7.1. A classe pai de todas as Exceções
é Throwable. Observe que existem duas derivações: Exception e Error. Error são erros não
tratáveis em código como falta de memória. Exception são exceções tratáveis. A classe Ex-
ception possui uma subclasse especial: RuntimeException. Todas as exceções que derivam
de RuntimeException são exceções não verificadadas (nao existe obrigtoriedade no seu
tratamento). As outras exceções, que não herdam de RuntimeException, mas são subclasses
de Exception são exceções verificadas (existe a obrigatoriedade no seu tratamento).

Figura 7.1: Hierarquia da exceções

80 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 tratamento de exceções

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

7.7. Exercícios
1. Explique o que são exceções.

2. Qual a utilidade do bloco try?

3. Explique o bloco catch.

4. Qual a diferença entre exceões checadas e exceções não checadas?

5. Como criar novas exceções?

6. Qual a palavra chave utilizada para lançar novas exeções?

http://solutioin.com 81
Francisco Calaça, Otávio Calaça
FLUXO DE DADOS
8
No mundo corporativo é vital a transferência de informações entre computadores. Esta
troca é feita através de fluxos de informação. Qualquer troca de dados, como rede, arquivos,
dispositivos IO é vista como um fluxo de dados em Java.
Este capítulo apresentará exemplos de fluxo de dados de arquivos e de rede com a
construção de um editor de texto simples e a construção de um trocador de mensagens
entre computadores.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

8.1. A classe File


A classe File existe para representar um arquivo. Ela não é utilizada para escrever, ler, ou
alterar arquivos. Simplesmente para representá-los. Possui um construtor onde é informado
a localização do arquivo:

File arquivo = new File(‘‘c:\\arquivo.txt’’)

8.2. Como escrever em arquivos


Para escrever em arquivos será utilizada a classe Formatter do pacote java.util. Existem
outras formas de escrever em um arquivo utilizando classes como FileWriter, DataOutput-
Stream, etc. Para entender os exemplos preocupe-se apenas com a classe Formatter.
O código da listagem 8.1 apresenta um exemplo de escrita em arquivos. Note o uso da
classe Formatter para realizar a escrita. Nesse exemplo também foi utilizado a classe File.
Observe o uso do método close(). Este método fecha o fluxo. Nunca se esqueça dele.

Listagem 8.1: Exemplo de escrita em arquivos


1 package capitulo8;
2

3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.util.Formatter;

83
Versão 1.1 fluxo de dados

8 public class ExemploEscrita {


9

10 public static void main(String[] args) {


11 File arquivo = new File("c:\\ arquivo.txt");
12 try {
13 Formatter fluxo = new Formatter(arquivo);
14 fluxo.format("Exemplo de escrita do capitulo 10");
15 fluxo.close();
16 System.out.println("Arquivo criado ...");
17 } catch (FileNotFoundException e) {
18 e.printStackTrace();
19 }
20 }
21

22 }

8.3. Como ler arquivos


Para ler um arquivo texto será utilizada a classe Scanner do pacote java.util. Como na es-
crita existem outras formas de ler arquivos. Para entender os exemplos preocupe-se apenas
com a classe Scanner.
O código da listagem 8.2 apresenta um exemplo de leitura de arquivos. Note o uso da
classe Scanner para ler o arquivo. Assim como no exemplo de escrita, a classe File foi
utilizada para representar um arquivo. Após a leitura do arquivo não se esqueça de fechar
o fluxo com o método close().

Listagem 8.2: Exemplo de leitura em arquivos


1 package capitulo8;
2

3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.util.Scanner;
6

7 public class ExemploLeitura {


8

9 public static void main(String[] args) {


10 File arquivo = new File("c:\\ arquivo.txt");
11 System.out.println("Lendo arquivo :\n");
12 try {
13 Scanner fluxo = new Scanner(arquivo);
14 while(fluxo.hasNext()){
15 System.out.println(fluxo.nextLine());
16 }
17 fluxo.close();
18 } catch (FileNotFoundException e) {
19 e.printStackTrace();
20 }

84 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

21 }
22

23 }

8.4. Um editor de texto simples


Este tópico apresentará um editor de texto que reunirá todos os conhecimentos apresenta-
dos até agora. O código está na listagem 10.6. O código:

Container c = getContentPane();

c.setLayout(new BorderLayout());
c.add(botaoAbrir, BorderLayout.NORTH);
c.add(botaoSalvar, BorderLayout.SOUTH);
c.add(new JScrollPane(areaTexto), BorderLayout.CENTER);

cria a tela. Note o uso da classe BorderLayout. Esta classe define um layout que posiciona
componentes com informações NORTH para o topo, SOUTH para colocar algo abaixo,
CENTER para colocar algo no centro, etc.
A tela do editor de texto é apresenta na figura 10.6.
O código:

botaoAbrir.addActionListener(this);
botaoSalvar.addActionListener(this);

adiciona o listener de evento nos botões.


Neste exemplo a classe JFileChooser foi utilizada para criar a tela de escolha de arquivos:
para salvar ou para abrir.

Figura 8.1: Tela do editor de Texto

Listagem 8.3: Editor de texto simples

http://solutioin.com 85
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

1 package capitulo8;
2 import java.awt.BorderLayout;
3 import java.awt.Container;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.util.Formatter;
9 import java.util.Scanner;
10 import java.util.StringTokenizer;
11

12 import javax.swing.JButton;
13 import javax.swing.JFileChooser;
14 import javax.swing.JFrame;
15 import javax.swing.JOptionPane;
16 import javax.swing.JScrollPane;
17 import javax.swing.JTextArea;
18

19 public class EditorTexto extends JFrame implements ActionListener{


20 JButton botaoAbrir = new JButton("Abrir");
21 JButton botaoSalvar = new JButton("Salvar");
22 JTextArea areaTexto = new JTextArea();
23

24 public EditorTexto(){
25 Container c = getContentPane();
26

27 c.setLayout(new BorderLayout());
28 c.add(botaoAbrir, BorderLayout.NORTH);
29 c.add(botaoSalvar, BorderLayout.SOUTH);
30 c.add(new JScrollPane(areaTexto), BorderLayout.CENTER);
31

32 botaoAbrir.addActionListener(this);
33 botaoSalvar.addActionListener(this);
34

35 setTitle("Editor de Texto");
36 setSize(800,600);
37 setDefaultCloseOperation(EXIT_ON_CLOSE);
38 setVisible(true);
39 }
40

41 public void actionPerformed(ActionEvent e) {


42 JFileChooser jfc = new JFileChooser();
43

44 try {
45 if(e.getSource() == botaoAbrir){
46 jfc.showOpenDialog(this);
47 File file = jfc.getSelectedFile();
48 abrirArquivo(file);
49 }else if(e.getSource() == botaoSalvar){
50 jfc.showSaveDialog(this);
51 File file = jfc.getSelectedFile();
52 salvarArquivo(file);

86 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

53 }
54 }catch (FileNotFoundException e1) {
55 JOptionPane.showMessageDialog(null, "Arquivo não encontrado!");
56 }
57 }
58

59 private void salvarArquivo(File file) throws FileNotFoundException{


60 Formatter saida = new Formatter(file);
61 StringTokenizer token = new StringTokenizer(areaTexto.getText(), "\n");
62 while(token.hasMoreElements()){
63 saida.format("%s%n", token.nextElement());
64 }
65 saida.close();
66 }
67

68 private void abrirArquivo(File file) throws FileNotFoundException{


69 String texto = "";
70 Scanner scan = new Scanner(file);
71 while(scan.hasNext()){
72 texto += scan.nextLine() + "\n";
73 }
74 areaTexto.setText(texto);
75 scan.close();
76 }
77

78 public static void main(String[] args) {


79 new EditorTexto();
80 }
81 }

8.5. Serialização de objetos


Até agora os fluxos apresentados foram apenas de String. É possível também trafegar obje-
tos em fluxos de dados. Objetos Java podem ser salvos em arquivos, transmitido pela rede,
etc. Para que os objetos possam ser transmitidos de um lugar para o outro é necessário que
eles implementem a interface Serializable do pacote java.util. Quando a classe implementa
esta interface é necessário criar um atributo:

private static final long serialVersionUID = 1L;

para que não haja problemas com versões de classes. Esta é a única garantia que o objeto
trafegado, apesar de estar com os pacotes, métodos, etc idênticos possuam a mesma versão
de suas classes nos computadores envolvidos.
O eclipse possui um assistente para criar este atributo.

http://solutioin.com 87
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

8.6. Um trocador de mensagens simples


O próximo exemplo será de um trocador de mensagens. A mensagem trafegará atravéz de
objetos da classe Mensagem apresentada na listagem 8.4.
Observe que esta classe implementa a interface Serializable e possui o atributo:

private static final long serialVersionUID = 1L;

não se preocupe em criar este atributo. Peça para o eclipse criar para você.
A classe Enviador, apresentada na listagem 8.5 envia as mensagens. O código responsável
por isto é:

Socket socket = new Socket("127.0.0.1", 12345);


ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(mens);

a classe Socket cria uma comunicação com o ip 127.0.0.1 (que é a sua máquina local)
na porta 12345. A classe ObjectOutputStream cria um fluxo de dados de saida e utiliza
o socket criado na linha anterior. O método writeObjetct(mens) escreve o objeto no fluxo
criado na linha anterior.
A classe Receptor, apresentada na listagem 8.6 recebe as mensagens e as imprime no
console. Note que esta classe possui um laço infinito while(true). Este laço fará com que o
receptor receba mensagens enquanto estiver rodando.

server = new ServerSocket(12345);


Socket socket = server.accept();

ObjectInput ois = new ObjectInputStream(socket.getInputStream());


Mensagem mens = (Mensagem) ois.readObject();
System.out.println(mens);

a classe ServerSocket cria um socket na máquina e abre a porta 12345 (esta deverá estar
disponível). O método server.accept() aguarda até alguém enviar uma mensagem por meio
destar porta (lembre-se do Enviador que enviará mensagens por esta porta). Foi utilizado
o método readObject() para ler o objeto que está sendo trafegado, no caso, Mensagem.

Listagem 8.4: Classe Mensagem


1 package capitulo8;
2

3 import java.io.Serializable;
4

5 public class Mensagem implements Serializable {


6

7 private static final long serialVersionUID = 1;


8

9 private String remetente;


10 private String descricao;

88 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

11

12 public String getDescricao() {


13 return descricao;
14 }
15

16 public void setDescricao(String descricao) {


17 this.descricao = descricao;
18 }
19

20 public String getRemetente() {


21 return remetente;
22 }
23

24 public void setRemetente(String remetente) {


25 this.remetente = remetente;
26 }
27

28 public String toString() {


29 return String.format("%-30s-%s", remetente, descricao);
30 }
31 }

Listagem 8.5: Classe que envia mensagens


1 package capitulo8;
2

3 import java.io.IOException;
4 import java.io.ObjectOutputStream;
5 import java.net.Socket;
6 import java.net.UnknownHostException;
7

8 import javax.swing.JOptionPane;
9

10 public class Enviador {


11 public static void main(String[] args) {
12 String resposta;
13 do {
14 resposta = JOptionPane.showInputDialog("Mensagem:");
15 Mensagem mens = new Mensagem();
16 mens.setRemetente("Seu Nome");
17 mens.setDescricao(resposta);
18

19 try {
20 Socket socket = new Socket("127.0.0.1", 12345);
21 ObjectOutputStream oos = new ObjectOutputStream(socket
22 .getOutputStream());
23 oos.writeObject(mens);
24 } catch (UnknownHostException e) {
25 e.printStackTrace();
26 } catch (IOException e) {
27 e.printStackTrace();
28 }
29

http://solutioin.com 89
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

30 } while (!resposta.equals("sair"));
31 }
32 }

Listagem 8.6: Receptor de mensagens


1 package capitulo8;
2

3 import java.io.ObjectInput;
4 import java.io.ObjectInputStream;
5 import java.net.ServerSocket;
6 import java.net.Socket;
7

8 public class Receptor {


9

10 public static void main(String[] args) {


11 ServerSocket server = null;
12 while (true) {
13 try {
14 server = new ServerSocket(12345);
15 Socket socket = server.accept();
16

17 ObjectInput ois = new ObjectInputStream(socket.getInputStream());


18 Mensagem mens = (Mensagem) ois.readObject();
19 System.out.println(mens);
20

21 ois.close();
22 socket.close();
23 server.close();
24 } catch (Throwable e) {
25 e.printStackTrace();
26 } finally {
27 try {
28 server.close();
29 } catch (Exception e) {
30 e.printStackTrace();
31 }
32 }
33

34 }
35 }
36

37 }

90 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 fluxo de dados

8.7. Exercícios

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

1. Qual a utilidade da classe File?

2. Descreva o processo para escrita em arquivos.

3. Descreva o processo para leitura de arquivos.

4. O que é serialização de objetos?

5. Na serialização de objetos para que serve o atributo serialVersionUID?

http://solutioin.com 91
Francisco Calaça, Otávio Calaça
GENÉRICOS E COLEÇÕES
9
Em um capítulo anterior foi abordado os Arrays. Um dos problemas dos arrays é a impos-
sibilidade de alterar seu tamanho. Neste capítulo serão abordadas outras coleções como
Listas, Conjuntos e Mapas. Estas coleções permitem ter seu tamanho alterado em tempo
de execução e se comportam de forma diferente se aproximando ao comportamento do
mundo real.

9.1. o que são genéricos


Genéricos existem para diminuir os erros de Conversão de classes do tipo ClassCastExcep-
tions.
Veja o código da listagem 9.1. Esta listagem apresenta a classe Caixa que pode aceitar
qualquer tipo de objeto. A listagem 9.2 mostra o uso dessa classe. Observe na listagem 9.3
um erro comum. Apesar da caixa aceitar qualquer tipo de objetos, são esperados apenas
objetos do tipo Integer o que, por falta de atenção, pode ser de outros tipos (a caixa aceita
qualquer tipo de dados).
Com Generics é possível restringir os tipos para tipos específicos. O código da listagem
9.4 apresenta a nova caixa, com suporte a generics.
Observe, na listagem 9.5 que, na declaração da caixa, é possível informar qual o tipo de
objetos que a caixa conterá, assim evitando erros de conversão.
Voltando ao código da CaixaGenérica (listagem 9.4) note a declaração da classe:

public class CaixaGenerica <E>

observe o uso de: < E >. Este trecho de código Especifica que tudo o que for informado
dentro das chaves < ... > será considerado apenas como E. No código da listagem 9.5 foi
colocado < Integer >, ou seja, onde tiver “E” será considerado “Integer”. Assim o método:

public void setObjeto(E objeto)

será considerado:

public void getObjeto(Integer objeto)

Se, na declaração da classe CaixaGenérica for utilizado < String > onde tiver < E > será
considerado como String.
Assim, evita-se erros de conversão por ser possível informar o tipo que estará na caixa
no moment da sua declaração.

93
Versão 1.1 genéricos e coleções

Listagem 9.1: Classe Caixa


1 package capitulo9;
2 public class Caixa {
3

4 private Object objeto;


5

6 public Object getObjeto() {


7 return objeto;
8 }
9

10 public void setObjeto(Object objeto) {


11 this.objeto = objeto;
12 }
13

14 }

Listagem 9.2: Classe CaixaDemo1


1 package capitulo9;
2 public class CaixaDemo1 {
3 public static void main(String[] args) {
4

5 Caixa caixaDeInteiros = new Caixa();


6

7 caixaDeInteiros.setObjeto(10);
8 Integer someInteger = (Integer) caixaDeInteiros.getObjeto();
9 System.out.println(someInteger);
10 }
11 }

Listagem 9.3: Classe CaixaDemo2


1 package capitulo9;
2 public class CaixaDemo2 {
3 public static void main(String[] args) {
4

5 Caixa caixaDeInteiros = new Caixa();


6

7 /*
8 * note que estamos adicionando String na caixa
9 * propositalmente para provocar um erro de conversão
10 */
11

12 caixaDeInteiros.setObjeto("10");
13

14 Integer someInteger = (Integer) caixaDeInteiros.getObjeto();


15 System.out.println(someInteger);
16 }
17 }

Listagem 9.4: Classe CaixaGenerica

94 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

1 package capitulo9;
2 public class CaixaGenerica <E>{
3

4 private E objeto;
5

6 public E getObjeto() {
7 return objeto;
8 }
9

10 public void setObjeto(E objeto) {


11 this.objeto = objeto;
12 }
13

14 }

Listagem 9.5: Classe CaixaGenericaDemo


1 package capitulo9;
2 public class CaixaGenericaDemo {
3 public static void main(String[] args) {
4

5 CaixaGenerica<Integer> caixaDeInteiros = new CaixaGenerica<Integer>();


6

7 caixaDeInteiros.setObjeto(10);
8 Integer someInteger = caixaDeInteiros.getObjeto();
9 System.out.println(someInteger);
10 }
11 }

9.2. Introdução a coleções


Uma coleção é um objeto que representa um grupo de objetos facilitando a manipulação
destes. Existem várias formas de reunir informações:

• Listas

• Conjuntos

• Mapas

• Filas

• Pilhas

9.3. Listas
As Listas apresentam as seguintes características:

• Podem conter elementos duplicados

http://solutioin.com 95
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

• Podem ser ordenadas

Para exemplificar, compare com as listas do mundo real. Pense em uma lista de com-
pras que você fará em um supermercado. Os elementos desta lista podem ser ordenados,
seguindo um critério qualquer. Outro detalhe é que os elementos desta lista podem ser
duplicados.
A interface List é a interface de todas as listas. Implementam esta interface as classes
ArrayList e Vector.
O código da listagem 9.6 apresenta um exemplo do uso de listas. Note o uso da interface
List para declarar as listas. Neste exemplo foi utilizada a classe ArrayList para instanciar a
lista.
O código:

Collections.sort(cores);

ordena a lista de cores em ordem alfabética.

Listagem 9.6: Exemplo de uso de Lista


1 package capitulo9;
2 import java.util.ArrayList;
3 import java.util.Collections;
4 import java.util.List;
5

6 public class ExemploLista {


7 public static void main(String[] args) {
8 List<String> cores = new ArrayList<String>();
9 cores.add("Azul");
10 cores.add("Vermelho");
11 cores.add("Preto");
12 cores.add("Cinza");
13 cores.add("Laranja");
14 cores.add("Amarelo");
15 cores.add("Verde");
16 cores.add("Azul");
17

18 for(String c : cores){
19 System.out.printf("Cor: %s\n",c);
20 }
21

22 Collections.sort(cores);
23 System.out.println("Cores após ordenação");
24 for(String c : cores){
25 System.out.printf("Cor: %s\n",c);
26 }
27

28 }
29 }

96 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

9.4. Conjuntos
Os conjuntos apresentam as seguintes características:

• Não podem conter elementos duplicados

• Não podem ser ordenados

Para exemplificar, pense no conjunto de laranjas em uma sacola. Não é possível dizer
qual é a primeira laranja, ou seja, não é possível ordena-las. Também não é possível duplicar
laranjas. Cada laranja é única.
Os conjuntos são definidos pela interface Set. Implementam esta interface as classes
HashSet e TreeSet.
O código da listagem 9.7 apresenta um exemplo do uso de conjuntos. Observe o uso da
interface Set para declarar o conjunto. Neste exemplo foi utilizada a classe HashSet para
instanciar o conjunto.
Nessa listagem foram inseridas, propositalmente, duas entradas para a cor azul. Após a
execução desta classe, observe que a saída do programa imprime a cor azul apenas uma
vez. Isto demonstra a incapacidade dos conjuntos em conter elementos duplicados. Note
também que a ordem impressa não é igual a ordem inserida no código.

Listagem 9.7: Exemplo de uso de Conjuntos


1 package capitulo9;
2 import java.util.HashSet;
3 import java.util.Set;
4

5 public class ExemploConjunto {


6 public static void main(String[] args) {
7 Set<String> cores = new HashSet<String>();
8 cores.add("Azul");
9 cores.add("Vermelho");
10 cores.add("Preto");
11 cores.add("Amarelo");
12 cores.add("Verde");
13 cores.add("Azul");//Repetido propositalmente
14

15 for(String c : cores){
16 System.out.printf("\nCor: %s",c);
17 }
18 }
19 }

9.5. Mapas
Os mapas apresentam as seguintes características:

• Associam chaves a valores

http://solutioin.com 97
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

• As chaves não podem ser repetidas

O código da listagem 9.8 apresenta um exemplo do uso de mapas. Assim como nos
exemplos de Listas e Conjuntos, foi utilizada uma interface para referenciar, no caso Map.
Uma das classes que implementa esta interface é a classe HashMap. Observe nesse exemplo
a associação de vegetações com regiões brasileiras.
Se for adicionado uma outra chave “cerrado”, por exemplo, esta sobrescreverá a existente
pois nos mapas não podem existir chaves duplicadas.

Listagem 9.8: Exemplo de uso de Mapas


1 package capitulo9;
2 import java.util.HashMap;
3 import java.util.Map;
4

5 import javax.swing.JOptionPane;
6

7 public class ExemploMapa {


8 public static void main(String[] args) {
9 Map<String, String> vegetacoes = new HashMap<String, String>();
10

11 vegetacoes.put("cerrado", "centro -oeste");


12 vegetacoes.put("floresta tropical", "norte");
13 vegetacoes.put("caatinga", "nordeste");
14 vegetacoes.put("mata atlântica", "costa brasileira");
15

16 String escolha = JOptionPane.showInputDialog("Digite uma vegetação:"


17 + vegetacoes.keySet());
18 JOptionPane.showMessageDialog(null, vegetacoes.get(escolha));
19 }
20 }

A Listagem 9.9 apresenta um exemplo um pouco mais complexo de mapa. Neste exem-
plo é realizada a contagem da quantidade de produtos com o mesmo nome existe na lista.
Observe que no final o código:

for(Entry<String, Integer> e : mapaContagem.entrySet()){


System.out.printf("%s: %d\n", e.getKey(), e.getValue());
}

é utilizado para percorrer os elementos do mapa que associa os produtos com suas
respectivas quantidades.

Listagem 9.9: Exemplo de uso de Mapas na contagem de elementos de uma lista


1 package capitulo9;
2 import java.util.ArrayList;
3 import java.util.HashMap;
4 import java.util.List;
5 import java.util.Map;
6 import java.util.Map.Entry;
7

98 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

9 public class ExemploMapaContagem {


10

11 public static void main(String[] args) {


12

13 List<String> lista = new ArrayList<String>();


14 lista.add("Cerveja");
15 lista.add("Carvão");
16 lista.add("Picanha");
17 lista.add("Cerveja");
18 lista.add("Cerveja");
19 lista.add("Cerveja");
20 lista.add("Cerveja");
21 lista.add("Cerveja");
22 lista.add("Costela");
23 lista.add("Costela");
24 lista.add("Pão com alho");
25 lista.add("Pão com alho");
26 lista.add("Pão com alho");
27 lista.add("Pão com alho");
28

29 Map<String, Integer> mapaContagem = new HashMap<String, Integer>();


30 for (String s : lista) {
31 Integer qtd = mapaContagem.get(s);
32 if(qtd == null){
33 qtd = 0;
34 }
35 qtd++;
36 mapaContagem.put(s, qtd);
37 }
38

39 for(Entry<String, Integer> e : mapaContagem.entrySet()){


40 System.out.printf("%s: %d\n", e.getKey(), e.getValue());
41 }
42 }
43

44 }

9.5.1 Properties
As propriedades são mapas que podem ser persistidos, ou seja, salvos em algum lugar. Um
exemplo de arquivo properties é:

#Propriedades do Sistema
telefone=3131-2363
descricao=Supermercado da Esquina
endereco=Rua 2

Observe a semelhança com os mapas, para cada entrada existe uma informação, ou
seja,para a entrada telefone tem-se a informação: 3131-2363.

http://solutioin.com 99
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

Java possui um tipo de mapa que tem a habilidade de persistir suas informações, são as
Properties. Estas classes possuem o método:

prop.store( . . .);

para a escrita dos dados, conforme pode ser visto na listagem 9.10
e o método:

prop.load( . . . );

para carregar os dados a partir de um fluxo, conforme pode ser visto na listagem 9.11

Listagem 9.10: Exemplo de escrita em arquivos properties


1 package capitulo9;
2 import java.io.FileNotFoundException;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.util.Properties;
6

7 public class ExemploPropertiesEscrita {


8 public static void main(String[] args) {
9 Properties prop = new Properties();
10 prop.put("descricao", "Supermercado da Esquina");
11 prop.put("endereco", "Rua 2");
12 prop.put("telefone", "3131 -2363");
13 try {
14 FileOutputStream fos = new FileOutputStream("c:\\ prop.properties");
15 prop.store(fos, "Propriedades do Sistema");
16 fos.close();
17 System.out.println("Propriedades salvas");
18 } catch (FileNotFoundException e) {
19 e.printStackTrace();
20 } catch (IOException e) {
21 e.printStackTrace();
22 }
23 }
24 }

Listagem 9.11: Exemplo de leitura de arquivos properties


1 package capitulo9;
2 import java.io.FileInputStream;
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.util.Properties;
6

7 import javax.swing.JOptionPane;
8

9 public class ExemploPropertiesLeitura {


10 public static void main(String[] args) {
11 try {
12 FileInputStream fis = new FileInputStream("c:\\ prop.properties");
13 Properties prop = new Properties();

100 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

14 prop.load(fis);
15 fis.close();
16 String nomeProp = JOptionPane.showInputDialog("Qual propriedade " +
17 "deseja ver? (descricao , endereco , telefone)" );
18 JOptionPane.showMessageDialog(null, prop.getProperty(nomeProp));
19 } catch (FileNotFoundException e) {
20 e.printStackTrace();
21 } catch (IOException e) {
22 e.printStackTrace();
23 }
24 }
25 }

9.6. Pilhas
Pilhas são estrutura de dados onde o último elemento que entra é o primeiro que sai - LIFO
(last-in-first-out). É possível exemplificar com uma pilha de livros. O primeiro livro a ser
emplilhado é o último que sai da pilha.
Um exemplo de pilha pode ser visto no código da listagem 9.12. Após executar este
exemplo o primeiro nome a ser impresso foi “Carlos” mas foi o último a ser adicionado na
pilha.

Listagem 9.12: Exemplo de pilha


1 package capitulo9;
2

3 import java.util.Stack;
4

5 public class ExemploPilha {


6

7 public static void main(String[] args) {


8 Stack<String> alunos = new Stack<String>();
9 alunos.push("Maria");
10 alunos.push("Antonio");
11 alunos.push("Joaquim");
12 alunos.push("Carlos");
13

14 while(!alunos.empty()){
15 System.out.println(alunos.pop());
16 }
17 }
18

19 }

http://solutioin.com 101
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

9.7. Filas
Filas são estruturas de dados onde o primeiro elemento que entra é o primeiro elemento
que sai - FIFO (first-in-first-out). Como nas filas dos caixas, a primeira pessoa que entra é a
primeira pessoa que poderá pagar.
O código da listagem 9.13 apresenta um exemplo de Fila.

Listagem 9.13: Exemplo de Fila


1 package capitulo9;
2

3 import java.util.LinkedList;
4 import java.util.Queue;
5

6 public class ExemploFila {


7

8 public static void main(String[] args) {


9 Queue<String> alunos = new LinkedList<String>();
10 alunos.offer("Maria");
11 alunos.offer("Antonio");
12 alunos.offer("Joaquim");
13 alunos.offer("Carlos");
14

15 while(!alunos.isEmpty()){
16 System.out.println(alunos.poll());
17 }
18 }
19

20 }

9.8. Ordenação de Listas


Uma das características de Listas é poder ser ordenada. Para ordenar uma lista pode-se
utilizar a interface Comparator e o método sort da classe Collections.
Observe o exemplo onde existem alunos que serão ordenados por idade.
A classe Aluno está na listagem 9.14. Possui os atributos nome e idade.
O método compare retorna um int, que pode ser:

• negativo se o primeiro objeto for menor que o segundo

• zero se os objetos forem iguais

• positivo se o primeiro objeto for maior que o segundo

Não se preocupe com o código:

return (int)(a1.getIdade() - a2.getIdade();

102 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

Apenas se atenha ao fato de que este método retornará algo negativo se a1 for menor
que a2, zero se forem iguais e positivo se a1 for maior.
O código do comparador por idade está na Listagem 9.15 e

Listagem 9.14: Classe Aluno do exemplo de ordenação


1 package capitulo9;
2

3 public class Aluno {


4

5 private String nome;


6

7 private int idade;


8

9 public Aluno(String nome, int idade) {


10 this.nome = nome;
11 this.idade = idade;
12 }
13

14 public String toString(){


15 return String.format("Aluno: %-10s - %3d", nome, idade);
16 }
17

18 public String getNome() {


19 return nome;
20 }
21

22 public void setNome(String nome) {


23 this.nome = nome;
24 }
25

26 public int getIdade() {


27 return idade;
28 }
29

30 public void setIdade(int idade) {


31 this.idade = idade;
32 }
33 }

Listagem 9.15: Comparador por idade


1 package capitulo9;
2 import java.util.Comparator;
3

4 public class ComparadorIdade implements Comparator<Aluno>{


5

6 public int compare(Aluno a1, Aluno a2) {


7 return a1.getIdade() - a2.getIdade();
8 }
9

10 }

http://solutioin.com 103
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

Listagem 9.16: Exemplo de ordenacao


1 package capitulo9;
2

3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6

8 public class ExemploOrdenacao {


9

10 public static void main(String[] args) {


11 List<Aluno> alunos = new ArrayList<Aluno>();
12 for(int i = 0; i < 15; i++){
13 int idade = (int)(Math.random() * 5) + 10;
14 String nome = "Aluno nr. " + i;
15 Aluno a = new Aluno(nome, idade);
16 alunos.add(a);
17 }
18

19 System.out.println("Lista original:");
20

21 for(Aluno a : alunos){
22 System.out.println(a);
23 }
24

25 System.out.println("\nLista ordenada por idade:");


26

27 Collections.sort(alunos, new ComparadorIdade());


28 for(Aluno a : alunos){
29 System.out.println(a);
30 }
31

32 }
33 }

9.9. Exercícios

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

1. O que são genéricos?

2. Descreva sobre Listas.

3. Descreva sobre Conjuntos.

104 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 genéricos e coleções

4. Descrevas sobre Mapas.

5. Qual as diferenças entre listas e conjuntos?

6. O que são properties? Qual a classe responsável por persistir as properties em um


arquivo?

7. O que é pilha?

8. O que é fila?

9. Quais os procedimentos necessários para ordenar uma lista de String’s? E uma lista
de objetos da classe Pessoa?

10. Adicione o atributo nota na classe da Listagem 9.14. Crie a classe ComparadorNota
seguindo o exemplo da Listagem 9.15. Altere o código da Listagem 9.16 para também
ordenar os alunos por nota.

http://solutioin.com 105
Francisco Calaça, Otávio Calaça
UML: UNIFIED MODELING LANGUAGE
10
Este capítulo lhe fornecerá uma visão rápida dos fundamentos da UML. Tenha em mente
que isto não é um tutorial detalhado sobre UML, mas apenas uma rápida introdução a
UML que pode ser lida como um tutorial UML. Se você gostaria de aprender mais sobre
a Linguagem de Modelagem Unificada, ou generalidades sobre análise e desenho de soft-
ware, consulte um dos muitos livros disponíveis sobre o tópico. Existem também muitos
tutoriais na Internet os quais você pode usar como ponto de partida.
A Unified Modelling Language (UML) é uma linguagem ou notação de diagramas para
especificar, visualizar e documentar modelos de ’software’ orientados por objetos. O UML
não é um método de desenvolvimento, o que significa que não lhe diz o que fazer primeiro
ou o que fazer depois ou como desenhar o seu sistema, mas ajuda-o a visualizar o seu
desenho e a comunicar com os outros. O UML é controlado pelo Object Management
Group (OMG) e é a norma da indústria para descrever graficamente o ’software’.
O UML está desenhado para o desenho de ’software’ orientado por objetos e tem uma
utilização limitada para outros paradigmas de programação.
A UML é composta por muitos elementos de modelo que representam as diferentes
partes de um sistema de software. Os elementos UML são usados para criar diagramas,
que representam um determinada parte, ou um ponto de vista do sistema.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

10.1. Diagrama de Classe


Diagramas de Classe mostram as diferentes classes que fazem um sistema e como elas se
relacionam. Os Diagramas de Classe são chamados diagramas “estáticos” porque mostram
as classes, com seus métodos e atributos bem como os relacionamentos estáticos entre elas:
quais classes “conhecem” quais classes ou quais classes “são parte” de outras classes, mas
não mostram a troca de mensagens entre elas.

10.1.1 Classe
Um Classe define os atributos e os métodos de um conjunto de objetos. Todos os objetos
desta classe (instâncias desta classe) compartilham o mesmo comportamento, e possuem

107
Versão 1.1 uml: unified modeling language

o mesmo conjunto de atributos (cada objeto possui seu próprio conjunto). O termo “Tipo”
é algumas vezes usado ao invés de Classe, mas é importante mencionar que estes dois
termos não são a mesma coisa, e Tipo é um termo mais genérico.
Em UML Classes são representadas por retângulos, com o nome da classe, e podem tam-
bém mostrar os atributos e operações da classe em dois outros “compartimentos” dentro
do retângulo.

Figura 10.1: Representação visual de uma Classe em UML

10.1.1.1 Atributos
Na UML, atributos são mostrados com pelo menos seu nome, e podem também mostrar
seu tipo, valor inicial e outras propriedades. Atributos podem também ser exibidos com
sua visibilidade:

• + indica atributos públicos

• # indica atributos protegidos

• - indica atributos privados

10.1.1.2 Operações
Operações (métodos) também são exibidos com pelo menos seu nome, e podem tam-
bém mostrar seus parâmetros e valores de retorno. Operações podem, como os Atributos,
mostras sua visibilidade:

• + indica operações públicas

• # indica operações protegidas

• - indica operações privadas

10.1.2 Associações de Classe


Classes podem relacionar-se (ser associada com) com outras de diferentes maneiras:

10.1.2.1 Generalização
A herança é um dos conceitos fundamentais da programação orientada por objetos, nos
quais uma classe “ganha” todos os atributos e operações da classe que herda, podendo

108 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 uml: unified modeling language

sobrepor ou modificar algumas delas, assim como adicionar mais atributos ou operações
próprias.
EM UML, uma associação Generalização entre duas classes coloca-as numa hierarquia
representando o conceito de herança de uma classe derivada de uma classe base. Em UML,
Generalizações são representadas por uma linha conectando duas classes, com uma seta
no lado da classe base.

Figura 10.2: Representação visual de uma generalização em UML

10.1.2.2 Associações
Um associação representa um relacionamento entre classes, e fornece a semântica comum
e a estrutura para muitos tipos de “conexões” entre objetos.
Associações são o mecanismo que permite objetos comunicarem-se entre si. Elas de-
screvem a conexão entre diferentes classes (a conexão entre os objetos atuais é chamada
conexão do objeto, ou link.
Associações podem ter um regra que especifica o propósito da associação e pode ser
uni ou bidirecional (indicando se os dois objetos participantes do relacionamento podem
mandar mensagens para o outro, ou se apenas um deles sabe sobre o outro). Cada ponta
da associação também possui uma valor de multiplicidade, que dita como muitos objetos
neste lado da associação pode relacionar-se com o outro lado.
Em UML, associações são representadas como linhas conectando as classes participantes
do relacionamento, e podem também mostrar a regra e a multiplicidade de cada um dos
participantes. A multiplicidade é exibida como um intervalo [min...máx] de valores não
negativos, com uma estrela (*) no lado máximo representando infinito.

Figura 10.3: Representação visual de uma Associação em UML

10.1.2.3 Agregação
Agregações são um tipo especial de associação no qual as duas classes participantes não
possuem em nível igual, mas fazem um relacionamento “todo-parte”. Uma Agregação de-
screve como a classe que possui a regra do todo, é composta (tem) de outras classes, que

http://solutioin.com 109
Francisco Calaça, Otávio Calaça
Versão 1.1 uml: unified modeling language

possuem a regra das partes. Para Agregações, a classe que age como o todo sempre tem
uma multiplicidade de um.
Em UML, Agregações são representadas por uma associação que mostra um romboide
no lado do todo.

Figura 10.4: Representação visual de um relacionamento Agregação em UML

10.1.2.4 Composição
Composições são associações que representam agregações muito fortes. Isto significa que
Composições formam relacionamentos todo-parte também, mas o relacionamento é tão
forte que as partes não pode existir independentes. Elas existem somente dentro do todo,
e se o todo é destruído as partes morrem também.
Em UML, Composições são representadas por um romboide sólido no lado do todo.

Figura 10.5: Representação visual de um relacionamento Composição em UML

10.2. Diagrama de Caso de Uso


Diagramas de Caso de Uso descrevem relacionamentos e dependências entre um grupo de
Caso de Uso e os Atores participantes no processo.
É importante observar que Diagramas de Caso de Uso não são adequados para represen-
tar o desenho, e não podem descrever os mecanismos internos de um sistema. Diagramas
de Caso de Uso são feitos para facilitar a comunicação com os futuros usuários do sistema,
e com o cliente, e são especialmente úteis para determinar os recursos necessários que o
sistema deve ter. Diagramas de Caso de Uso dizem o quê o sistema deve fazer, mas não
fazem - e não podem - especificar como isto será conseguido.

10.2.1 Caso de Uso


Um Caso de Uso descreve - do ponto de vista dos atores - um grupo de atividades num
sistema que produz um resultado concreto e tangível.
Casos de Uso são descrições de interações típicas entre os usuários de um sistema e o
sistema propriamente dito. Eles representam a interface externa do sistema e especificam
um conjunto de exigências do que o sistema deve fazer (lembre-se: somente o quê, não
como).

110 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 uml: unified modeling language

Quando trabalhar com Casos de Uso, é importante lembrar-se de algumas regras simples:

• Cada Caso de Uso está relacionado com no mínimo um ator;

• Cada Caso de Uso possui um iniciador (isto é um ator);

• Cada Caso de Uso liga-se a um resultado relevante (um resultado com “valor de
negócio”);

Casos de Uso também podem ter relacionamentos com outros Casos de Uso. Os três
tipos mais comuns de relacionamento entre Casos de Uso são:

• «inclui-se» que especifica que um Caso de Uso toma lugar dentro de outro Caso de
Uso

• «estende» que especifica que em determinadas situações, ou em algum ponto (chamado


um ponto de extensão) um Caso de Uso será estendido por outro.

• Generalização especifica que um Caso de Uso herda as características do “Super”


Caso de Uso, e pode sobrepor algumas delas ou adicionar novas de maneira semel-
hante a herança entre classes.

10.2.2 Ator
Um ator é uma entidade externa (fora do sistema) que interage com o sistema participando
(e frequentemente iniciando) um Caso de Uso. Atores podem ser pessoas reais (por exem-
plo usuários do sistema), outro sistema de computador ou eventos externos.
Atores não representam as pessoa física ou sistemas, mas sua regra. Isto significa que
quando uma pessoa interage com o sistema de diferentes maneiras (assumindo diferentes
regras) ela será representada por diversos atores. Por exemplo um pessoa que fornece su-
porte ao cliente por telefone e recebe ordens do cliente para o sistema pode ser representado
por um ator da “Equipe de Suporte” e um ator “Representante de Vendas”

10.2.3 Descrição do Caso de Uso


Descrição do Caso de Uso são narrativas de texto do Caso de Uso. Elas usualmente tomam
a forma de uma nota ou um documento que é de alguma maneira ligado ao Caso de Uso,
e explana o processo ou atividades que tomarão lugar no Caso de Uso.

10.3. Demais diagramas


Além dos diagramas de classe e de caso de uso, existem os outros seguintes diagramas:

• Diagrama de Sequência mostra objetos e uma sequência das chamadas do método


feitas para outros objetos.

http://solutioin.com 111
Francisco Calaça, Otávio Calaça
Versão 1.1 uml: unified modeling language

Figura 10.6: Representação visual de alguns casos de uso

• Diagrama de Colaboração mostra objetos e seus relacionamentos, colocando ênfase


nos objetos que participam na troca de mensagens

• Diagrama de Estado mostra estados, mudanças de estado e eventos num objeto ou


uma parte do sistema

• Diagrama de Atividade mostra atividades e as mudanças de uma atividade para


outra com os eventos ocorridos em alguma parte do sistema

• Diagrama de Componente mostra os componentes de programação de alto nível


(como KParts ou Java Beans).

• Diagrama de Distribuição mostra as instâncias dos componentes e seus relaciona-


mentos. Os Diagramas de Entidade-Associação mostram os dados e as relações e as
restrições entre os dados.

112 http://solutioin.com
Francisco Calaça, Otávio Calaça
THREADS
11
Thread, ou linha de execução em português, é uma forma de um processo dividir a si
mesmo em duas ou mais tarefas que podem ser executadas simultaneamente.
Uma linha de execução permite que o usuário do seu programa, por exemplo, utilize
uma funcionalidade do ambiente enquanto outras linhas de execução realizam outros cál-
culos e operações. Os sistemas que suportam apenas uma única linha de execução são
chamados de monothread e aqueles sistemas que suportam múltiplas linhas de execução
são chamados de multithread.

11.1. Processos e Threads


Em programação concorrente, há duas unidades básicas: processos e threads. Em Java a
programação concorrente é normalmente concebida com threads.
Um sistema computacional normalmente possui muitos processos e threads ativos. Es-
teja ele sendo executado em uma máquina com um processador ou em uma máquina
multiprocessada.

11.1.1 Processos
Um processo geralmente tem um conjunto completo e restrito de recursos para sua exe-
cução, ou seja, cada processo tem seu próprio espaço de memória.
Processos são sinonimos de programas e aplicações. Como o espaço de memória e restrito
a cada processo, a comunicação entre processos é feita através do sistema operecional com
pipes e sockets. Esta comunicação pode ser feita entre processos na mesma máquina ou em
diferentes máquinas.

11.1.2 Threads
Threads são, algumas vezes, chamadas de processos leves. Threads existem dentro dos
processos, cada processo possui pelo menos uma thread. Threads podem compartilhar
recursos do processos, como memória e arquivos abertos. Isto é muito eficiente para a
comunição de recursos.
Execução multithread é um caracteristica da plataforma Java. Cada aplicação Java é com-
posta de várias thread. As threads tornam os programas mais eficientes pois, com elas, é
possível realizar mais de uma atividade simultaneamente. Uma thread possui a habilidade
de criar novas threads.

113
Versão 1.1 threads

11.2. Criação de Threads


Cada thread está associada com uma instancia da classe Thread. Há duas formas de criar
uma Thread:

• Implementando a interface Runnable

• Estendendo a classe Thread

Independente da forma que se cria a thread o código a ser executado pela thread deve
estar no método run:
public void run()
Para iniciar a thread é necessário executar o método start:
suaThread.start()
A listagem 11.1 apresenta um exemplo de Thread que é criada estendendo a classe
Thread. O uso desta thread está na classe da listagem 11.2. Note o uso do método start
para iniciar esta thread.
A listagem 11.3 apresenta um exemplo de Thread que é criada implementado a interface
Runnable. O uso desta thread está na classe da listagem 11.4. Também foi utilizado o
método start para iniciar a thread.

Listagem 11.1: Thread criada estendendo da classe Thread


1 package capitulo11;
2

3 public class PrimeiraThread extends Thread {


4

5 public PrimeiraThread(String nome) {


6 super(nome);
7 }
8

9 public void run() {


10 for (int i = 0; i < 10000; i++) {
11 System.out.printf("\n Thread: %s (executando) - %5d", getName(), i++);
12 }
13 }
14 }

Listagem 11.2: Execução da Thread que estendeu a classe thread


1 package capitulo11;
2

3 public class ExemploThread {


4 public static void main(String[] args) {
5 PrimeiraThread thread1 = new PrimeiraThread(" **** ");
6 PrimeiraThread thread2 = new PrimeiraThread("####");
7 thread1.start();
8 thread2.start();
9 }
10 }

114 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

Listagem 11.3: Thread criada implementando Runnable


1 package capitulo11;
2

3 public class SegundaThread implements Runnable {


4

5 private String nome;


6

7 public SegundaThread(String nome) {


8 this.nome = nome;
9 }
10

11 public void run() {


12 for (int i = 0; i < 10000; i++) {
13 System.out.printf("\n Thread: %s (executando) - %5d", nome, i++);
14 }
15 }
16 }

Listagem 11.4: Execução da Thread que implementou Runnable


1 package capitulo11;
2

3 public class ExemploThread2 {


4 public static void main(String[] args) {
5 SegundaThread st1 = new SegundaThread(" **** ");
6 SegundaThread st2 = new SegundaThread("####");
7

8 Thread thread1 = new Thread(st1);


9 Thread thread2 = new Thread(st2);
10

11 thread1.start();
12 thread2.start();
13 }
14 }

11.3. A classe Executors


A nova API de threads permite um melhor gerenciamento das threads utilizando pool.
Desta forma é possível criar um pool de Threads e especificar a quantidade máxima de
threads estará em execução simultaneamente. A listagem 11.5 apresenta um exemplo de
utilização do pool de threads. Neste exemplo o pool é criado com o método:
ExecutorService threads = Executors.newFixedThreadPool(2)
note que serão executadas apenas duas threads simultaneamente.

threads.execute(t1);
threads.execute(t2);
threads.execute(t3);

http://solutioin.com 115
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

são colocadas três threads no pool. Como apenas duas threads serão executadas a terceira
irá esperar uma das duas anteriores terminar para começar sua execução.

Listagem 11.5: Exemplo de utilização do pool de threads


1 package capitulo11;
2

3 import java.util.concurrent.*;
4

5 public class ExemploThread3 {


6 public static void main(String[] args) {
7 SegundaThread t1 = new SegundaThread(" **** ");
8 SegundaThread t2 = new SegundaThread("####");
9 SegundaThread t3 = new SegundaThread("$$$$");
10

11 ExecutorService threads = Executors.newFixedThreadPool(2);


12 threads.execute(t1);
13 threads.execute(t2);
14 threads.execute(t3);
15 threads.shutdown();
16 }
17 }

11.4. Métodos sleep e yield


O método Thread.sleep faz com que a thread suspenda sua execução por um período es-
pecífico. Após o término do periodo a thread volta ao estado de executável podendo entrar
em execução ou não dependendo da sua prioridade. A figura 11.1 ilustra esse método.
O método Thread.yield faz com que a thread desista de sua atual execução. Suponha que
você executa muitas threads no computador e que estas threads estão sendo mal geren-
ciadas e que algumas não conseguem concluir algumas atividades. Ao ser executado o
método yield provocará a desistência momentânea da thread em execução e possibilitará
a entrada de outra thread para a execução. Essa thread aguardará até a CPU tornar-se
disponível novamente.
Note que ela poderá voltar a ser executada quando o gerenciador de threads do sistema
solicitar. A figura 11.2 ilustra esse método.

11.5. Sincronização
Quando duas threads compartilham dados é comum que haja problemas com sincroniza-
ção. Para que você entenda melhor este problema observe o exemplo. A classe Troca está
na listagem 11.6. Note que esta classe possui o método trocar que recebe um boolean. Se o
boolean for true as variáveis a e b receberão 5 e 7, sendo false receberão 11 e 13. A thread
está na listagem 11.7. A classe que instancia o objeto do tipo Troca e as threads está na
listagem 11.8. Note que é criado apenas um objeto do tipo Troca e este objeto é compartil-
hado entre as threads es1 e es2. Uma dessas threads é instanciada com true a outra com

116 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

Figura 11.1: Método Thread.sleep

Figura 11.2: Método Thread.yield

http://solutioin.com 117
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

false. isto fará com que o comportamento do metodo trocar da classe Troca seja diferente
para cada thread. Ao executar este exemplo é apresentada a seguinte saída:
5 = 11 e 7 = 13
11 = 5 e 13 = 7
5 = 11 e 7 = 13
11 = 5 e 13 = 7
5 = 11 e 7 = 13

Isto acontece porque as threads não estão sincronizadas. Uma thread inicia o trabalho,
a outra termina. Para resolver este problema é necessário sincronizar o método trocar:
synchronized public void trocar(boolean bol). Ao acrescentar a palavra chave synchro-
nized no método fará com que este não possa ser executado por duas threads simultanea-
mente.

Listagem 11.6: Objeto Troca que está compartilhado entre a threads


1 package capitulo11;
2

3 public class Troca {


4 private int a;
5

6 private int b;
7

8 public void trocar(boolean bol) throws InterruptedException {


9 if (bol) {
10 a = 5;
11 b = 7;
12 } else {
13 a = 11;
14 b = 13;
15 }
16 Thread.sleep(500);
17

18 if (bol) {
19 System.out.printf("%d = 5 e %d = 7 \n", a, b);
20 } else {
21 System.out.printf("%d = 11 e %d = 13 \n", a, b);
22 }
23 }
24 }

Listagem 11.7: Thread que acessará o objeto Troca


1 package capitulo11;
2

3 public class Operador implements Runnable {


4 private boolean bol;
5 private Troca obj;
6

7 public Operador(Troca obj, boolean bol) {


8 this.bol = bol;
9 this.obj = obj;

118 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

10 }
11

12 public void run() {


13 while (true) {
14 try {
15 obj.trocar(bol);
16 } catch (InterruptedException e) {
17 e.printStackTrace();
18 }
19 }
20 }
21 }

Listagem 11.8: Exemplo de threads não sincronizadas


1 package capitulo11;
2

3 import java.util.concurrent.ExecutorService;
4 import java.util.concurrent.Executors;
5

7 public class ExemploSinc {


8

9 public static void main(String[] args) {


10 Troca obj = new Troca();
11 Operador es1 = new Operador(obj, true);
12 Operador es2 = new Operador(obj, false);
13

14 ExecutorService t1 = Executors.newFixedThreadPool(2);
15 t1.execute(es1);
16 t1.execute(es2);
17 t1.shutdown();
18 }
19 }

11.6. O verificador de primos


Para exemplificar melhor o uso de threads as listagens 11.9 e 11.10 apresentam um Verifi-
cador de números primos. Este exemplo consegue verificar vários primos simultaneamente
porque a classe VerificadorPrimo da listagem 11.9 é uma thread. A classe TestePrimo cria
uma nova thread de verificação a cada número informado pelo usuário.
Listagem 11.9: Thread que verifica se um número é primo (utiliza um algoritmo lento de verificação
para demonstrar melhor o exemplo)
1 package capitulo11;
2

3 public class VerificadorPrimo extends Thread {


4

5 private long numero;

http://solutioin.com 119
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

7 public VerificadorPrimo(long numero) {


8 this.numero = numero;
9 }
10

11 public void run() {


12 boolean primo = true;
13 for (int i = 2; i < numero; i++) {
14 if ((numero % i) == 0) {
15 primo = false;
16 }
17 }
18

19 if (primo) {
20 System.out.printf("\nO número: %d é primo", numero);
21 } else {
22 System.out.printf("\nO número: %d não é primo", numero);
23 }
24 }
25 }

Listagem 11.10: Verificador de números primos


1 package capitulo11;
2

3 import javax.swing.JOptionPane;
4

5 public class TestePrimo {


6 public static void main(String[] args) {
7 String resposta;
8 do {
9 resposta =
10 JOptionPane.showInputDialog("Digite um número");
11 try {
12 long numero = new Long(resposta);
13 VerificadorPrimo vf = new VerificadorPrimo(numero);
14 vf.start();
15 } catch (NumberFormatException e) {
16 JOptionPane.showMessageDialog(null,
17 "número invalido" );
18 }
19

20 } while (!resposta.equals("sair"));
21 }
22 }

120 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 threads

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

11.7. Exercícios
1. O que são threads?

2. Qual a diferença entre processos e threads?

3. Descreva as duas formas de se criar uma thread.

4. O que são pool de threads?

5. Qual a diferença entre os métodos sleep e yield?

6. Qual o objetivo de utilização da palavra chave synchronized?

http://solutioin.com 121
Francisco Calaça, Otávio Calaça
S T R I N G S E D ATA S
12
Converter Datas em Strings e Strings em Datas é um dos assuntos deste capítulo. Esta é
uma tarefa comum em softwares uma vez que a maior forma de entrada de dados em
um sistema é texto e este texto deve, algumas vezes, ser convertido em data para correta
manipulação. Outra coisa,normalmente é necessária, é formatar uma data em textos para
que seja melhor apresentada ao usuário.
Na versão 5 do Java foi acrescentado a saída formatada assunto também abordado neste
capítulo. Com a saída formatada é mais simples a formatação de números, datas e outros.

12.1. As classes Date e Calendar


A classe Date é utilizada para representar momentos no tempo. A maior parte dos seus
metodos estão deprecados, ou seja, não são mais utilizados. Para manipulação de datas e
horas existe a classe Calendar. Por ser uma classe abstrata utiliza-se o método getInstance:

Calendar.getInstance();

Para obter a data e hora atuais pode ser utilizado o construtor default da classe Date:

Date hoje = new Date();

A listagem 12.1 apresenta um exemplo de uso da classe Calendar.

Listagem 12.1: Exemplo de uso da classe Calendar


1 package capitulo12;
2

3 import java.util.Calendar;
4

5 public class ExemploCalendar {


6

7 public static void main(String[] args) {


8 Calendar calendar = Calendar.getInstance();
9 int diaAno = calendar.get(Calendar.DAY_OF_YEAR);
10 int ano = calendar.get(Calendar.YEAR);
11

12 System.out.printf("\nEstamos no %d dia do ano de %d", diaAno, ano);


13 }
14

15 }

123
Versão 1.1 strings e datas

12.2. Formatação de Datas


É muito comum um sistema necessitar converter uma data em uma String ou uma String
em uma data. Para estes casos é possível utilizar a classe SimpleDateFormat. Esta classe im-
plementa a interface DateFormat e possui métodos que são capazes tanto em formatar uma
data em um String ou em converter uma String em uma data. A listagem 12.2 apresenta
um exemplo de conversão de String em data e formatação desta data em outra String.
Para converter uma String em uma data utiliza-se o método parse. Este método lança
uma exeção se a String não puder ser convertida.
O método format formata uma data em uma String.

Listagem 12.2: Exemplo de formatação de datas


1 package capitulo12;
2

3 import java.text.DateFormat;
4 import java.text.ParseException;
5 import java.text.SimpleDateFormat;
6 import java.util.Date;
7

8 import javax.swing.JOptionPane;
9

10 public class ExemploFormatacaoData {


11

12 public static void main(String[] args) {


13 DateFormat formatadorEntrada = new SimpleDateFormat(
14 "dd/MM/yyyy" );
15 DateFormat formatadorSaida = new SimpleDateFormat(
16 "’Data Informada:’ dd ’de’ MMMM ’de’ yyyy - ’(’EEEE ’)’" );
17

18 String dataTexto = JOptionPane


19 .showInputDialog("Digite uma data:");
20 try {
21 Date data = formatadorEntrada.parse(dataTexto);
22 String dataFormatada = formatadorSaida.format(data);
23 JOptionPane.showMessageDialog(null, "Data digitada: "
24 + dataFormatada);
25 } catch (ParseException e) {
26 e.printStackTrace();
27 }
28

29 }
30

31 }

124 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 strings e datas

12.3. A classe String


Strings são objetos que contém uma cadeia de caracteres. Em Java são imutáveis, portanto
uma vez criadas não podem ser alteradas. Para exemplificar, caso ocorra uma concatenação
de Strings, um novo objeto é criado, e o antigo, será coletado pelo coletor de lixo. O método
charAt é utilizado para consultar caracteres pelo índice.
Para comparar Strings, assim como qualquer outro objeto Java, utiliza-se o método equals.
Este método retorna true quando os valores entre as Strings são iguais e false caso sejam
diferentes.

12.4. A classe StringBuffer


As classes StringBuffer e StringBuilder possibilitam a alteração de uma cadeia de caracteres
o que torna o processamento mais rápido uma vez que não é necessário criar Strings a cada
concatenação. A listagem 12.3 apresenta uma comparação de concatenação de Strings entre
String e StringBuffer.

Listagem 12.3: Comparação da concatenação de Strings entre StringBuffer e a classe String


1 package capitulo12;
2

3 public class RankingString {


4

5 private static int quantidade = 10000;


6

7 public static long concatenarComString() {


8 long t1 = System.currentTimeMillis();
9

10 String texto = "";


11 for (int i = 0; i < quantidade; i++) {
12 texto += "a";
13 }
14

15 long t2 = System.currentTimeMillis();
16 return t2 - t1;
17 }
18

19 public static long concatenarComStringBuffer() {


20 long t1 = System.currentTimeMillis();
21

22 StringBuffer texto = new StringBuffer("");


23 for (int i = 0; i < quantidade; i++) {
24 texto.append("a");
25 }
26

27 long t2 = System.currentTimeMillis();
28 return t2 - t1;
29 }
30

http://solutioin.com 125
Francisco Calaça, Otávio Calaça
Versão 1.1 strings e datas

31 public static void main(String[] args) {


32 long tempoStringBuffer = concatenarComStringBuffer();
33 System.out.printf("Tempo com StringBuffer: %d ms \n", tempoStringBuffer);
34

35 long tempoString = concatenarComString();


36 System.out.printf("Tempo com String: %d ms \n", tempoString);
37 }
38 }

12.5. Saída formatada


A saída formatada está disponível a partir do Java 5.0. Igual à saída formatada das lingua-
gens C e C++ permite a formação de Strings utilizando uma String formatadora:

System.out.printf(‘‘\%s, \%s’’, texto1, texto2);

Observe que a string formatadora “%s, %s” recebe os parâmetros texto1 e texto2 o os
formata uma após o outro separados com uma vírgula.
Observe que a passatem dos parâmetros texto1 e texto2 são impressos na mesma ordem
que aparecem. É possível alterar esta ordem utilizando indices.
O exemplo

System.out.printf(‘‘\%2\$s, \%1\$s’’, texto1, texto2);

irá imprimir os parâmetros texto1 e texto2 na ordem contraria em que aparecem.

12.5.1 Caracteres de conversão


Para formatar Strings é possível utilizar uma vasta quantidade de caracteres de conversão,
dependendo do tipo da informação a ser formatada. A tabela 12.1 apresenta uma uma lista
dos caracteres de formatação utilizados com Java.
É possível ajustar o tamanho da saída do parâmetro acrescentando um valor antes do
caractere de conversão.:

%5d

imprimirá um número inteiro decimal e reservará um espaço de cinco caracteres para


isto.
Para números com ponto flutuante é ajustar a quantidade de casas decimais que devem
ser apresentadas. Isto se faz acrescentando um ponto e um número com a quantidade de
casas decimais a apresentar:

\%.2

Este exemplo apresentará um número com ponto flutuante com duas casas decimais.
A listagem 12.4 apresenta um exemplo com várias opções de formatação.

126 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 strings e datas

%s Utilizado com Strings


%d Utilizado com números inteiros decimais
%o Utilizado com números inteiros octais
%x Utilizado com números inteiros hexadec-
imais (utilize “%X” para que as letras
aparecam maiúsculas)
%f Utilizado com números com ponto flutu-
ante
%t Utilizado com datas. Deve ser combi-
nado com os formatadores da tabela ??
para produzir um resultado.

Tabela 12.1: Caracteres de conversão de String

%F Formata uma data


%H mostra a hora de uma data
%M mostra o minuto de uma data
%S mostra o segundo de uma data
%m mostra o mês de uma data
%d mostra o dia de uma data

Tabela 12.2: tablecaption

http://solutioin.com 127
Francisco Calaça, Otávio Calaça
Versão 1.1 strings e datas

Listagem 12.4: Exemplo de saída formatada


1 package capitulo12;
2

3 import java.util.Date;
4

5 public class ExemploSaidaFormatada {


6

7 public static void main(String[] args) {


8

9 /*
10 * Exemplo de formatação de números inteiros
11 */
12 System.out.println("Formatação de inteiros");
13 int inteiro = 123;
14 System.out.printf("%10s %10s %10s", "DECIMAL", "OCTAL", "HEXADECIMAL");
15 System.out.printf("\n%1$10d %1$10o %1$10X", inteiro);
16

17 /*
18 * Exemplo de formatação de ponto flutuante
19 */
20 System.out.println("\n\nFormatação de ponto flutuantes");
21 double flutuante = 1.2345;
22 System.out.printf("%.3f", flutuante);
23

24 /*
25 * Formatação de Datas e Horas
26 */
27 System.out.println("\n\nFormatação de datas e horas");
28 Date hoje = new Date();
29 System.out.printf("Hora atual: %1$tH:%1$tM:%1$tS", hoje);
30 System.out.printf("\nData formatada: %1$tF", hoje);
31 System.out.printf("\nData atual: %1$td/%1$tm/%1$tY", hoje);
32

33 }
34 }

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

12.6. Exercícios
1. Qual a diferença do uso das classes Date e Calendar?

2. Crie uma classe que receba a data no formato dd/MM/yyyy e converta para o for-
mato yyyy-mm-dd utilizando a classe SimpleDateFormat.

128 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 strings e datas

3. Descreva a classe String.

4. Qual a diferença entre String e StringBuffer?

http://solutioin.com 129
Francisco Calaça, Otávio Calaça
JDBC
13
Um Sistema Gerenciador de Banco de Dados (SGBD) é o conjunto de programas de com-
putador responsáveis pelo gerenciamento de uma base de dados. O principal objetivo é
retirar da aplicação o trabalho e a responsabilidade de gerenciar o acesso e a segurança
de suas informações. Em bancos de dados relacionais é utilizada a linguagem SQL para
manipulação dos registros.
Normalmente as pessoas chamam os SGBDs de apenas Banco de Dados. No decorrer
deste capítulo onde estiver o termo Banco de Dados entenda que são estas estruturas com-
plexas de armazenamento de informações.
JDBC (Java Database Connectivity) é a API do Java para trabalhar com Banco de Dados.
Com ela é possível executar instruções ler registros executar funções no Banco de Dados.
Trata-se de um conjunto de interfaces e classes que possuem os métodos necessários para as
mais diversas atividades com um banco de dados. As interfaces são implementadas pelos
drivers JDBC que são específicos para cada banco.

13.1. Conexão com banco de dados


Para se conectar em um Banco de dados com o JDBC é necessários as seguintes infor-
mações:

• O Driver do banco

• A URL de conexão

• O usuário

• A senha

• O caminho para o Driver (arquivo .jar)

A classe apresentada na listagem 13.1 mostra um exemplo de conexão com o Banco de


Dados. O Driver é passado com o seguinte método:

Class.forName("org.postgresql.Driver");

A url, usuário e a senha com o seguinte método:

DriverManager.getConnection(
"jdbc:postgresql://localhost/treinamento",
"postgres", "123456");

131
Versão 1.1 jdbc

A configuração do caminho para Driver é feita nas propriedades do projeto, na opção


Java Build Path, conforme a figura 13.1.

Listagem 13.1: Classe Conexao


1 package capitulo13;
2

3 import java.sql.*;
4

5 public class Conexao {


6 private static String driver = "org.postgresql.Driver";
7 private static String url = "jdbc:postgresql :// localhost/treinamento";
8 private static String usuario = "postgres";
9 private static String senha = "123456";
10

11 public static Connection getConexao() {


12 try {
13 Class.forName(driver);
14 return DriverManager.getConnection(url, usuario, senha);
15 } catch (ClassNotFoundException e) {
16 e.printStackTrace();
17 return null;
18 } catch (SQLException e) {
19 e.printStackTrace();
20 return null;
21 }
22 }
23 }

Figura 13.1: Configuração do CLASSPATH para o Driver JDBC

132 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

13.2. A linguagem SQL


SQL é um linguagem de consulta a registros em um Banco de dados Relacional. As in-
struções SQL apresentadas a seguir utilizarão como referência a tabela CLIENTE

13.2.1 SELECT
Instrução para consulta de registros. Sua sintaxe é:

SELECT <LISTA DOS CAMPOS DA TABELA> FROM <TABELA>

Um Exemplo: Para buscar todos os registros da tabela CLIENTE pode ser utilizado o
seguinte SQL:

SELECT CODIGO, NOME, TELEFONE, ENDERECO, NASCIMENTO FROM CLIENTE

Um outra forma, não aconselhada, de busca de registros é a utilização do asterisco (*):


SELECT * FROM CLIENTE

13.2.2 Cláusula WHERE


Permite filtrar os registros em uma consulta, alteração ou exclusão. Sua sintaxe é:

WHERE <NOME DO CAMPO> = <VALOR>

Para buscar o registro da tabela CLIENTE onde o código vale 5:

SELECT CODIGO, NOME, TELEFONE, ENDERECO, NASCIMENTO FROM CLIENTE WHERE CODIGO = 5

13.2.3 O Operador LIKE


É possível realizar busca com aproximação de valores utilizando a expressão LIKE. Se o
objetivo é buscar todos os nomes da tabela CLIENTE que comecem com “Ma” pode-se
utilizar a seguinte instrução SQL:

SELECT CODIGO, NOME, CPFCNPJ, ENDERECO, MUNICIPIO FROM CLIENTE WHERE NOME LIKE ’Ma%’

O caracter “%” substituirá com zero ou mais caracteres na busca. O caracter _ substi-
tuirá apenas com um caracter.

http://solutioin.com 133
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

13.2.4 INSERT
Permite incluir registros em uma tabela no banco de dados. Sua sintaxe é:

INSERT INTO <NOME DA TABELA> (<NOME DOS CAMPOS>) VALUES (<VALOR DOS CAMPOS>).

Para incluir um registro na tabela de CLIENTE pode ser utilizado o seguinte SQL:

INSERT INTO CLIENTE (NOME, CPFCNPJ, ENDERECO, MUNICIPIO, UF)


VALUES (’ANA MARIA’, ’321.321.321-01’, ’Rua 2 Centro’, ’GOIANIA’, ’GO’).

13.2.5 UPDATE
Permite alterar registros em um tabela. Sua sintaxe é:

UPDATE <NOME DA TABELA> SET <CAMPO> = <VALOR> WHERE <CAMPO> = <VALOR>

Note a existência da cláusula WHERE. Se não for especificada todos os registros da tabela
serão alterados para <VALOR>.
Para alterar o nome do CLIENTE com código 5 para Joao Carlos pode ser utilizada a
seguinte instrução:

UPDATE CLIENTE SET NOME = ’Joao Carlos’ WHERE ID = 5

13.2.6 DELETE
Permite excluir registros em uma tabela. Sua sintaxe é:

DELETE FROM <NOME DA TABELA> WHERE <CAMPO> = <VALOR>

Note o uso da cláusula WHERE. Sem especifica-la todos os registros da tabela serão
excluídos.
Para excluir o registro com código 5 da tabela é utilizada a seguinte instrução:

DELETE FROM CLIENTE WHERE ID = 5

13.3. Como executar instruções SQL e obter


registros
Após realizada a conexão é possível executar instrções SQL. Para isto é necessário a criação
de um Statement. Existem três tipos de Statements:

• Statement - para execução de instruções estáticas, ou seja, sem parâmetros.

134 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

• PreparedStatement - para a execução de instruções com parâmetros

• CallableStatement - para a execuções de funções do Banco de Dados.

A classe da listagem 13.2 apresenta um exemplo de execução de instruções.


Note que há dois tipos execuções: as que têm a função de buscar registros e as que tem
a função de alterar registros.
O comando SQL utilizado para buscar registros é o SELECT. Para a execução de um
SELECT é necessário o método executeQuery. Este método retorna um ResultSet que pos-
sibilita a navegação no resultado. A interface ResultSet possui alguns métodos úteis e estes
estão listados na tabela 13.1.

next ir ao próximo registro, retorna true se existir um


próximo registro e false se este não existir.
getString(<NOME DO CAMPO>) retorna o valor (no formato String) contido no respec-
tivo campo da tabela.

Tabela 13.1: Leitura de um ResultSet

Os comando SQL para alteração de registros são o INSERT, UPDATE e DELETE. Para a
execução destes comandos podem ser utilizados os métodos

execute
ou
executeUpdate

Listagem 13.2: Primeiro Exemplo de acesso a banco de dados


1 package capitulo13;
2

3 import java.sql.*;
4

5 public class ExemploJDBC {


6

7 public static void main(String[] args) {


8 Connection con = Conexao.getConexao();
9 try {
10 Statement stmt = con.createStatement();
11 ResultSet rs = stmt.executeQuery("select * from cliente");
12

13 while (rs.next()) {
14 System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
15 rs.getString("nome"), rs.getString("cpfCnpj"),
16 rs.getString("endereco"),
17 rs.getString("municipio"),
18 rs.getString("uf"));
19 }
20

21 con.close();
22 } catch (SQLException e) {
23 e.printStackTrace();

http://solutioin.com 135
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

24 }
25 }
26 }

13.3.1 PreparedStatement
Com a interface PreparedStatement é possível passar parâmetros para as instruções SQL.
No lugar dos parâmetros são utilizados pontos de interrogação (?):

PreparedStatement pstmt = con.prepareStatement(‘‘SELECT * FROM CLIENTE WHERE ID = ?’’);


pstmt.setInt(1, 5);

Observe que após a criação da instrução é necessário passar os parâmetros com setInt.
Exite também o setString, setDate, setLong, enfim, uma infinidade de possibilidades de
passagem de valores para a instrução.

13.4. Execução em Lote


É possível executar instruções SQL em lote. Esta técnica torna a execução muito mais ráp-
ida do que executar uma instrução de cada vez. A listagem 13.3 apresenta um teste de
velocidade entre a utilização

Listagem 13.3: Exemplo de execução em Batch


1 package capitulo13;
2

3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7

8 public class ExemploExecucaoBatch {


9

10 public static Connection con = Conexao.getConexao();


11

12 static void limparTabela(){


13 try {
14 Statement stmt = con.createStatement();
15 stmt.execute("delete from cliente");
16 } catch (SQLException e) {
17 e.printStackTrace();
18 }
19 }
20

21 public static long executarSemBatch(){


22 limparTabela();
23 long t1 = System.currentTimeMillis();
24 try {

136 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

25 PreparedStatement pstmt = con.prepareStatement("insert into cliente "


26 + "(nome , cpfCnpj , endereco , municipio , uf) "
27 + "values (?, ?, ?, ?, ?)");
28 for(int i = 0; i < 50000; i++){
29 pstmt.setString(1, "nome");
30 pstmt.setString(2, "cpfCnpj");
31 pstmt.setString(3, "endereco");
32 pstmt.setString(4, "municipio");
33 pstmt.setString(5, "uf");
34 pstmt.execute();
35 }
36 } catch (SQLException e) {
37 e.printStackTrace();
38 }
39 long t2 = System.currentTimeMillis();
40 return t2 - t1;
41 }
42

43 public static long executarComBatch(){


44 limparTabela();
45 long t1 = System.currentTimeMillis();
46 try {
47 PreparedStatement pstmt = con.prepareStatement("insert into cliente "
48 + "(nome , cpfCnpj , endereco , municipio , uf) "
49 + "values (?, ?, ?, ?, ?)");
50 for(int i = 0; i < 50000; i++){
51 pstmt.setString(1, "nome");
52 pstmt.setString(2, "cpfCnpj");
53 pstmt.setString(3, "endereco");
54 pstmt.setString(4, "municipio");
55 pstmt.setString(5, "uf");
56 pstmt.addBatch();
57 }
58 pstmt.execute();
59 } catch (SQLException e) {
60 e.printStackTrace();
61 }
62 long t2 = System.currentTimeMillis();
63 return t2 - t1;
64 }
65

66

67 public static void main(String[] args) {


68 long t1 = executarComBatch();
69 System.out.printf("Com Batch: %d (ms)\n", t1);
70

71 long t2 = executarSemBatch();
72 System.out.printf("Sem Batch: %d (ms)\n", t2);
73 }
74 }

http://solutioin.com 137
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

13.5. Tabela de Clientes


Para exemplificar os conceitos de Banco de Dados veja agora uma agenda de clientes. A
listagem 13.4 apresenta a classe Cliente.

Listagem 13.4: Classe Cliente


1 package capitulo13;
2

3 public class Cliente {


4

5 private int id;


6

7 private String nome;


8

9 private String cpfCnpj;


10

11 private String endereco;


12

13 private String municipio;


14

15 private String uf;


16

17 public int getId() {


18 return id;
19 }
20

21 public void setId(int id) {


22 this.id = id;
23 }
24

25 public String getNome() {


26 return nome;
27 }
28

29 public void setNome(String nome) {


30 this.nome = nome;
31 }
32

33 public String getCpfCnpj() {


34 return cpfCnpj;
35 }
36

37 public void setCpfCnpj(String cpfCnpj) {


38 this.cpfCnpj = cpfCnpj;
39 }
40

41 public String getEndereco() {


42 return endereco;
43 }
44

45 public void setEndereco(String endereco) {

138 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

46 this.endereco = endereco;
47 }
48

49 public String getMunicipio() {


50 return municipio;
51 }
52

53 public void setMunicipio(String municipio) {


54 this.municipio = municipio;
55 }
56

57 public String getUf() {


58 return uf;
59 }
60

61 public void setUf(String uf) {


62 this.uf = uf;
63 }
64 }

A listagem 13.5 apresenta a classe ClienteDao. Observe que foi colocada nesta classe os
métodos de acesso ao Banco de Dados como incluir, excluir e listar. Colocar os métodos
que acessam o Banco de Dados fora da entidade Cliente é uma boa prática de programação
pois facilita a alteração da estrutura de dados.

Listagem 13.5: Classe ClienteDao - acessa os recursos no Banco de Dados


1 package capitulo13;
2

3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.sql.Statement;
8 import java.util.ArrayList;
9 import java.util.List;
10

11 public class ClienteDao {


12

13 private Cliente mapear(ResultSet rs) throws SQLException{


14 Cliente cliente = new Cliente();
15 cliente.setId(rs.getInt("id"));
16 cliente.setNome(rs.getString("nome"));
17 cliente.setCpfCnpj(rs.getString("cpfCnpj"));
18 cliente.setEndereco(rs.getString("endereco"));
19 cliente.setMunicipio(rs.getString("municipio"));
20 cliente.setUf(rs.getString("uf"));
21 return cliente;
22 }
23

24 public void incluir(Cliente cliente) {


25 Connection con = Conexao.getConexao();
26 try {

http://solutioin.com 139
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

27 try {
28 PreparedStatement pstmt = con.prepareStatement("insert into cliente " +
29 "(nome , cpfcnpj , endereco , municipio , uf) values (?, ?, ?, ?, ?)" );
30 pstmt.setString(1, cliente.getNome());
31 pstmt.setString(2, cliente.getCpfCnpj());
32 pstmt.setString(3, cliente.getEndereco());
33 pstmt.setString(4, cliente.getMunicipio());
34 pstmt.setString(5, cliente.getUf());
35 pstmt.execute();
36 } finally {
37 con.close();
38 }
39 } catch (SQLException e) {
40 e.printStackTrace();
41 }
42 }
43

44 public List<Cliente> listar() {


45 Connection con = Conexao.getConexao();
46 List<Cliente> resultado = new ArrayList<Cliente>();
47 try {
48 try {
49 Statement stmt = con.createStatement();
50 ResultSet rs = stmt.executeQuery("select * from cliente");
51 while (rs.next()) {
52 Cliente cliente = mapear(rs);
53 resultado.add(cliente);
54 }
55 } finally {
56 con.close();
57 }
58 } catch (SQLException e) {
59 e.printStackTrace();
60 }
61 return resultado;
62 }
63

64 public void excluir(int id){


65 Connection con = Conexao.getConexao();
66 try {
67 try {
68 PreparedStatement pstmt = con.prepareStatement("delete from cliente where
id = ?" );
69 pstmt.setInt(1, id);
70 pstmt.execute();
71 } finally {
72 con.close();
73 }
74 } catch (SQLException e) {
75 e.printStackTrace();
76 }
77 }

140 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

78

79 }

A listagem 13.6 apresenta a classe Agenda. Esta classe obtém as informações com o
usuário do sistema armazena no Banco de Dados e apresenta a lista de clientes cadastrados.

Listagem 13.6: A Agenda


1 package capitulo13;
2

3 import java.util.List;
4

5 import javax.swing.JOptionPane;
6

7 public class ClienteInclusao {


8

9 public static void main(String[] args) {


10 Cliente cliente = new Cliente();
11 cliente.setNome(JOptionPane.showInputDialog("Nome:"));
12 cliente.setCpfCnpj(JOptionPane.showInputDialog("Cpf/Cnpj:"));
13 cliente.setEndereco(JOptionPane.showInputDialog("Endereço:"));
14 cliente.setMunicipio(JOptionPane.showInputDialog("Município:"));
15 cliente.setUf(JOptionPane.showInputDialog("UF:"));
16

17 ClienteDao cdao = new ClienteDao();


18 cdao.incluir(cliente);
19

20 List<Cliente> clientes = cdao.listar();


21 for(Cliente c : clientes){
22 System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
23 c.getNome(),
24 c.getCpfCnpj(),
25 c.getEndereco(),
26 c.getMunicipio(),
27 c.getUf());
28 }
29 }
30 }

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

13.6. Exercícios
1. O que é JDBC ?

http://solutioin.com 141
Francisco Calaça, Otávio Calaça
Versão 1.1 jdbc

2. Descreva os passos necessários para obter um conexao (Connection) Java com o Banco
de dados.

3. No exemplo da agenda implemente a funcionalidade que exclui clientes.

4. O que é SQL? Quais os comandos básicos e sua sintaxe?

5. Qual a diferença entre o Statement e o PreparedStatement?

6. Pesquise o motivo da execução em lote ser mais rápida.

142 http://solutioin.com
Francisco Calaça, Otávio Calaça
J AVA P E R S I S T E N C E A P I C O M
14
H I B E R N AT E

14.1. Mapeamento objeto relacional


Mapeamento objeto-relacional (ou ORM) é uma técnica de desenvolvimento utilizada para
reduzir o trabalho de programar sistemas orientados aos objetos que utilizam bancos de
dados relacionais. As tabelas do banco de dados são representadas através de classes e os
registos de cada tabela são representados como instâncias das classes correspondentes.
Com esta técnica, diminui-se consideravelmente a utilização de comandos em linguagem
SQL. O desenvolvedor irá usar uma interface de programação simples que faz todo o
trabalho de persistência.
Não é necessária uma correspondência direta entre as tabelas de dados e as classes do
programa. A relação entre as tabelas onde originam os dados e o objeto que os disponi-
biliza é configurada pelo programador, isolando o código do programa das alterações à
organização dos dados nas tabelas do banco de dados.
Em resumo, mapeamento objeto/relacional é a automatização das operações entre o
mundo objeto e o mundo relacional. É utilizado na persistência de objetos em aplicações
Java para tabelas em um banco de dados relacional.

14.2. Configurações iniciais


Para que os exemplos deste capítulo funcionem, é necessário realizar algumas configu-
rações prévias. Inicialmente, crie uma pasta, dentro do diretório src do seu projeto, chamada
META-INF. Copie para esta pasta o arquivo persistence.xml. O conteúdo deste arquivo está
na Listagem 18.12. Este arquivo também está disponibilizado na pasta AmbienteTrabalho/-
Material/materialJpa/config. A Figura 14.1 ilustra este passo.

Figura 14.1: Configuração do arquivo persistence.xml

143
Versão 1.1 java persistence api com hibernate

O próximo passo é a configuração das dependências da JPA. Para isto, clique com o botão
direito do mouse sobre o projeto e vá em Properties. Clique em Java Build Path. Adicione
os arquivos .jar que estão no diretório AmbienteTrabalho/Material/materialJpa/libJpa. A Figura
14.2 ilustra este passo.

Figura 14.2: Configuração das dependências da JPA.

14.3. A criação do primeiro exemplo


Agora será criado o modelo desenvolvido no capitulo de JDBC utilizando JPA. A classe
Cliente deverá ser anotada com @Entity do pacote javax.persistence. A anotação @Entity
instrui ao provedor de persistência de que a classe em questão deverá ser mapeada para
um banco de dados e que também será gerenciada pelo EntityManager. A listagem 14.1
apresenta as anotações necessárias para utilização da classe Cliente como entidade da JPA.

Listagem 14.1: Classe Cliente com as anotações da JPA


1 package capitulo14;
2

3 import javax.persistence.Entity;
4 import javax.persistence.GeneratedValue;
5 import javax.persistence.Id;
6

7 @Entity
8 public class Cliente {
9

144 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

10 @Id
11 @GeneratedValue
12 private int id;
13

14 private String nome;


15

16 private String cpfCnpj;


17

18 private String endereco;


19

20 private String municipio;


21

22 private String uf;


23

24 public int getId() {


25 return id;
26 }
27

28 public void setId(int id) {


29 this.id = id;
30 }
31

32 public String getNome() {


33 return nome;
34 }
35

36 public void setNome(String nome) {


37 this.nome = nome;
38 }
39

40 public String getCpfCnpj() {


41 return cpfCnpj;
42 }
43

44 public void setCpfCnpj(String cpfCnpj) {


45 this.cpfCnpj = cpfCnpj;
46 }
47

48 public String getEndereco() {


49 return endereco;
50 }
51

52 public void setEndereco(String endereco) {


53 this.endereco = endereco;
54 }
55

56 public String getMunicipio() {


57 return municipio;
58 }
59

60 public void setMunicipio(String municipio) {


61 this.municipio = municipio;

http://solutioin.com 145
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

62 }
63

64 public String getUf() {


65 return uf;
66 }
67

68 public void setUf(String uf) {


69 this.uf = uf;
70 }
71 }

14.4. O arquivo persistence.xml


O arquivo persistence.xml é o “coração” da JPA. É nele que serão definidas as configu-
rações das conexões, entidades que serão persistidas e o comportamento do engine da JPA.
Este arquivo deve ficar dentro do diretório META-INF do classpath da aplicação. As con-
figurações deste arquivo dependerão da implementação JPA utilizada: Hibernate, TopLink,
KODO, etc.
A listagem 18.12 apresenta o exemplo do arquivo persistence.xml com a implementação
do Hibernate. As propriedades desse arquivo estão descritas na tabela 14.1.

hibernate.hbm2ddl.auto update - cria as tabelas conforme as anotações das enti-


dades
hibernate.dialect Configura o dialeto a ser usado no banco. Mais dialetos
podem ser vistos na Tabela 14.2
hibernate.connection.driver_class Configura o driver do banco de dados
hibernate.connection.username Configura o usuário do banco de dados
hibernate.connection.password Configura a senha do banco de dados
hibernate.connection.url Configura a url de conexão com o banco de dados
hibernate.show_sql se true mostra no log as expressões SQL utilazadas

Tabela 14.1: Alguns dos parâmetros do hibernate

Listagem 14.2: Arquivo persistence.xml do nosso projeto


1 <?xml version="1.0" encoding="UTF -8"?>
2 <persistence version="1.0"
3 xmlns="http://java.sun.com/xml/ns/persistence"
4 xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns
/persistence/persistence _ 1 _ 0.xsd" >
6 <persistence-unit name="aulajpa">
7 <properties>
8 <property name="hibernate.hbm2ddl.auto" value="update"/>
9 <property name="hibernate.show _ sql" value="true"/>
10

146 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

11 <property name="hibernate.dialect" value="org.hibernate.dialect.


PostgreSQLDialect" />
12 <property name="hibernate.connection.driver _ class" value="org.postgresql.
Driver" />
13 <property name="hibernate.connection.url" value="jdbc:postgresql: //
localhost/treinamento" />
14 <property name="hibernate.connection.username" value="postgres"/>
15 <property name="hibernate.connection.password" value="123456"/>
16 </properties>
17 </persistence-unit>
18 </persistence>

Banco de Dados Dialeto


DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL com InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL com MyISAM org.hibernate.dialect.MySQLMyISAMDialect
Oracle (qualque versão) org.hibernate.dialect.OracleDialect
Oracle 9i org.hibernate.dialect.Oracle9iDialect
Oracle 10g org.hibernate.dialect.Oracle10gDialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Informix org.hibernate.dialect.InformixDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Ingres org.hibernate.dialect.IngresDialect
Progress org.hibernate.dialect.ProgressDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Interbase org.hibernate.dialect.InterbaseDialect
Pointbase org.hibernate.dialect.PointbaseDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
Firebird org.hibernate.dialect.FirebirdDialect

Tabela 14.2: Alguns dos dialetos do hibernate

http://solutioin.com 147
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

14.5. O EntityManager
Inicialmente deve ser criada uma instância de EntityManagerFactory. Isto é realizado
através do código:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("aulajpa");

neste momento, o engine da JPA irá validar as tabelas em relação às classes anotadas. Em
alguns engines (como é o caso do Hibernate) é possível configurar para que, neste momento,
também sejam criadas as tabelas no banco de dados.
O EntityManager pode ser criado ou obtido de uma EntityManagerFactory. Você precisa
utilizar um EntityManagerFactory para criar instâncias de EntityManager.
O método createEntityManager() retorna uma instância de EntityManager. Esta instân-
cia irágerenciar o contexto de persistência. A classe da listagem 14.3 apresenta um exemplo
de utilização do EntityManager.

Listagem 14.3: Classe ContatoDao exemplificando a utilização do EntityManager


1 package capitulo14;
2

3 import java.util.List;
4

5 import javax.persistence.EntityManager;
6 import javax.persistence.EntityManagerFactory;
7 import javax.persistence.Persistence;
8 import javax.persistence.Query;
9

10 public class ClienteDaoJpa {


11

12 private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("


aulajpa" );
13

14 private EntityManager em = emf.createEntityManager();


15

16 public void incluir(Cliente cliente) {


17 em.getTransaction().begin();
18 em.persist(cliente);
19 em.getTransaction().commit();
20 }
21

22 public List<Cliente> listar() {


23 Query query = em.createNativeQuery("select * from cliente", Cliente.class);
24 return query.getResultList();
25 }
26

27 public void excluir(int id){


28 em.getTransaction().begin();
29 Cliente c = em.find(Cliente.class, id);
30 em.remove(c);
31 em.getTransaction().commit();
32 }

148 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

33

34 }

14.6. A inclusão de clientes com JPA


A classe da listagem 14.4 apresenta nossa agenda na versão JPA.

Listagem 14.4: Classe Agenda


1 package capitulo14;
2

3 import java.util.List;
4

5 import javax.swing.JOptionPane;
6

7 public class ClienteInclusaoJpa {


8

9 public static void main(String[] args) {


10 Cliente cliente = new Cliente();
11 cliente.setNome(JOptionPane.showInputDialog("Nome:"));
12 cliente.setCpfCnpj(JOptionPane.showInputDialog("Cpf/Cnpj:"));
13 cliente.setEndereco(JOptionPane.showInputDialog("Endereço:"));
14 cliente.setMunicipio(JOptionPane.showInputDialog("Município:"));
15 cliente.setUf(JOptionPane.showInputDialog("UF:"));
16

17 ClienteDaoJpa cdao = new ClienteDaoJpa();


18 cdao.incluir(cliente);
19

20 List<Cliente> clientes = cdao.listar();


21 for(Cliente c : clientes){
22 System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
23 c.getNome(),
24 c.getCpfCnpj(),
25 c.getEndereco(),
26 c.getMunicipio(),
27 c.getUf());
28 }
29 }
30 }

14.6.1 Persistindo entidades


Persistir uma entidade é o ato de inseri-la em um banco de dados. Você persiste enti-
dades que ainda não foram criadas no banco de dados. Para isso utilize o método per-
siste(entidade) do EntityManager.

http://solutioin.com 149
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

14.6.2 Localizando entidades


O EntityManager possui o método find(classe, id) cujo objetivo é o de localizar entidades
no banco de dados. Sua forma de utilização é:

em.find(Cliente.class, 2)

neste caso será retornado o registro com id = 2 da tabela que persiste os objetos do tipo
Cliente.

14.6.3 Removendo entidades


Para remover entidades de um banco de dados utilize o método remove(entidade). So-
mente podem ser removidas entidades que estão no estado de gerenciadas. Para isto é
necessário localiza-las antes com find().

14.6.4 Mesclando entidades


Se a entidade não estiver no estado de gerenciada é possível mesclar as alterações com
as informações do banco de dados. Isto é realizado com o método merge(entidade). Este
método recebe uma entidade não gerenciada e retorna esta mesma entidade gerenciada.

14.7. Relacionamento entre classes


Existem quatro tipos de relacionamentos:

• Um para um - @OneToOne

• Um para muitos - @OneToMany

• Muitos para um - @ManyToOne

• Muitos para muitos - @ManyToMany

Para exemplificar o relacionamento @OneToMany foram criadas as classes das listagens


14.6 e 14.5. Observe a utilização da @OneToMany na propriedade disciplinas da classe
Curso. Esta anotação descreve a existência de vários cursos para cada disciplina.
A listagem 14.7 cria um objeto do tipo Disciplina e adiciona vários objetos do tipo Curso
na disciplina. Após isto é utilizada a JPA-QL para consultar os cursos com suas respectivas
disciplinas.

Listagem 14.5: Classe Curso do exemplo de relacionamento @OneToMany


1 package capitulo14;
2

3 import static javax.persistence.CascadeType.ALL;

150 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

4 import static javax.persistence.FetchType.EAGER;


5

6 import java.util.ArrayList;
7 import java.util.List;
8

9 import javax.persistence.Entity;
10 import javax.persistence.GeneratedValue;
11 import javax.persistence.Id;
12 import javax.persistence.JoinColumn;
13 import javax.persistence.OneToMany;
14

15 @Entity
16 public class Curso {
17

18 @Id
19 @GeneratedValue
20 private int id;
21

22 private String nome;


23

24 @JoinColumn(name="curso _ id")
25 @OneToMany(cascade=ALL, fetch = EAGER)
26 private List<Disciplina> disciplinas = new ArrayList<Disciplina>();
27

28 public String toString() {


29 StringBuffer sb = new StringBuffer(nome);
30 sb.append("\n");
31 for(Disciplina disciplina : disciplinas){
32 sb.append(" " );
33 sb.append(disciplina);
34 sb.append("\n");
35 }
36 return sb.toString();
37 }
38

39 public int getId() {


40 return id;
41 }
42

43 public String getNome() {


44 return nome;
45 }
46

47 public void setNome(String nome) {


48 this.nome = nome;
49 }
50

51 public List<Disciplina> getDisciplinas() {


52 return disciplinas;
53 }
54 }

http://solutioin.com 151
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

Listagem 14.6: Classe Disciplina do exemplo de relacionamento @OneToMany


1 package capitulo14;
2

3 import javax.persistence.Entity;
4 import javax.persistence.GeneratedValue;
5 import javax.persistence.Id;
6

7 @Entity
8 public class Disciplina {
9

10 @Id
11 @GeneratedValue
12 private int id;
13

14 private String nome;


15

16 private int cargaHoraria;


17

18 public String toString() {


19 return String.format("%s - %s", nome, cargaHoraria);
20 }
21

22 public int getId() {


23 return id;
24 }
25

26 public String getNome() {


27 return nome;
28 }
29

30 public void setNome(String nome) {


31 this.nome = nome;
32 }
33

34 public int getCargaHoraria() {


35 return cargaHoraria;
36 }
37

38 public void setCargaHoraria(int cargaHoraria) {


39 this.cargaHoraria = cargaHoraria;
40 }
41 }

Listagem 14.7: Classe Escola do exemplo de relacionamento @OneToMany


1 package capitulo14;
2

3 import java.util.List;
4

5 public class Escola {


6

7 public static void main(String[] args) {

152 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

8 Disciplina disciplina1 = new Disciplina();


9 disciplina1.setNome("Matematica");
10

11 Disciplina disciplina2 = new Disciplina();


12 disciplina2.setNome("Portugues");
13

14 Disciplina disciplina3 = new Disciplina();


15 disciplina3.setNome("Fisica");
16

17 Curso curso = new Curso();


18 curso.setNome("Nucleo comum");
19 curso.getDisciplinas().add(disciplina1);
20 curso.getDisciplinas().add(disciplina2);
21 curso.getDisciplinas().add(disciplina3);
22

23 CursoDaoJpa cursoDaoJpa = new CursoDaoJpa();


24 cursoDaoJpa.incluir(curso);
25

26 List<Curso> cursos = cursoDaoJpa.listar();


27 for(Curso c : cursos){
28 System.out.println(c);
29 }
30

31 }
32

33 }

14.8. Formas de obtenção de id’s


Uma chave primária é a identidade de um determinado bean de entidade. Cada bean de
entidade deve ter uma chave primaria e esta deve ser única. A chave primaria pode mapear
para uma ou mais propriedades.
A JPA permite quatro estratégias:

• TABLE - designa uma tabela relacional definida pelo usuário a partir da qual as
chaves numéricas serão geradas.

• SEQUENCE - Interage com as sequences dos bancos de dados que suportam esta
tecnologia como Oracle, PostGres, HSQLDB, etc.

• IDENTITY - Utilizada em bancos de dados com suporte a esta forma de geração de


ID’s como o SQL Server e o Derby.

• AUTO - Utilizada em banco de dados que possuem a funcionalidade autoincrement.

No exemplo foi utilizada a estratégia SEQUENCE por ser esta suportada pelo banco de
dados Postgres, utilizado neste livro. A classe Cliente apresentada na listagem 14.1 contém
este exemplo.
Se desejar configurar o nome da sequence no banco de dados, utilize a seguinte sintaxe:

http://solutioin.com 153
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="produto_seq")
@SequenceGenerator(sequenceName="produto_seq", name="produto_seq",
allocationSize=1, initialValue=1)

14.9. JPQL - A linguagem consulta da Jpa


O Java Persistence Query Language (JPQL) é uma linguagem de consulta orientada a obje-
tos definidos como parte da especificação da Java Persistence API (JPA).
Para realizar consultas de objetos é utilizada a JPQL, uma linguagem de consulta de
objetos que será traduzida, pela JPA, na linguagem de consulta estruturada: SQL.
A classe da 14.5 apresenta um exemplo de JPQL.
JPQL é usado para fazer consultas em entidades armazenadas em um banco de dados
relacional. Ela é fortemente inspirada na linguagem SQL, e suas consultas assemelham
à sintaxe das consultas SQL. A diferença é que operam com objetos de entidade JPA ao
invés de diretamente operar com as tabelas de banco de dados. Além de recuperar objetos
(consultas SELECT), JPQL é compatível com atualizações (UPDATE e DELETE).
Por exemplo, para retornar os cursos (Listagem 14.5) ordenados pelo nome, bastaria
utilizar:

select c from Curso c order by c.nome

Outro exemplo, para retornar apenas os cursos que contenham a disciplica com nome
FÍSICA, basta utilizar:

select c from Curso c left join fetch c.disciplinas d where d.nome = ’FÍSICA’

14.9.1 Passagem de parâmetros


Para passar parâmetros para as consultas você deve utilizar a seguinte estratégia:

Query query = em.createQuery(select c from Curso c where c.nome = :nome);


query.setParameter("nome", ’Java’);

neste caso, serão retornados todos os registros que contém nome igual a Java.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

154 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java persistence api com hibernate

14.10. Exercícios
1. O que é o mapeamento objeto-relacinal?

2. Quais os procedimentos necessários para tornar um bean apto a trabalhar com JPA?

3. Para que serve o EntityManager?

4. Quais os tipos de relacionamentos existem na JPA?

5. O que é o arquivo persistence.xml?

6. Quais as formas de obtenção de primary keys existem na JPA?

7. O que é JPA-QL ?

http://solutioin.com 155
Francisco Calaça, Otávio Calaça
A P L I C AT I V O S W E B
15
Construir aplicativos WEB consiste em misturar muitas tecnologias como HTML, CSS e
JavaScript em um aplicativo. A grande vantagem dos aplicativos WEB é o fato que a exe-
cução deles está no servidor e que a conectividade é máxima. É possível utilizar aplicativos
WEB em qualquer região do mundo bastando apenas estar conectado com o sistema.
É possível construir aplicativos WEB com Java. O que consistem em apenas utilizar a
tecnologia Java para gerar CSS, HTML e JavaScript.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

15.1. XML
XML é a abreviação de EXtensible Markup Language (Linguagem extensível de marcação).
Trata-se de uma linguagem que é considerada uma grande evolução na internet.
O XML é uma especificação técnica desenvolvida pelo W3C (World Wide Web Consor-
tium - entidade responsável pela definição da de padrões da internet), para ser um padrão
de comunicação entre sistemas. Em Java além de troca de informações entre sistemas o
XML também é muito utilizado para configurar recursos. O XML provê uma representação
estruturada dos dados. Isto o torna amplamente utilizado e de fácil utilização. É possível
representar vários tipos de estrutura de dados com XML.
O XML provê um padrão que pode codificar o conteúdo, as semânticas e as esquema-
tizações para uma grande variedade de aplicações desde simples até as mais complexas,
dentre elas:

• Um simples documento.

• Um registro estruturado tal como uma ordem de compra de produtos.

• Um objeto com métodos e dados como objetos Java ou controles ActiveX.

• Um registro de dados. Um exemplo seria o resultado de uma consulta a bancos de


dados.

• Apresentação gráfica, como interface de aplicações de usuário.

• Entidades e tipos de esquema padrões.

157
Versão 1.1 aplicativos web

• Todos os links entre informações e pessoas na web.

O XML é considerado de grande importância na Internet e em grandes intranets porque


provê a capacidade de inter operação dos computadores por ter um padrão flexível e aberto
e independente de dispositivo. As aplicações podem ser construídas e atualizadas mais rap-
idamente e também permitem múltiplas formas de visualização dos dados estruturados.
Para ser considerado válido um arquivo xml deve, obrigatoriamente:

• ter todas as suas tags fechadas;

• ter apenas uma tag principal;

• todos os valores dos atributos devem ser escritos entre aspas.

Na listagem 15.1 é apresentado um exemplo de arquivo xml.

Listagem 15.1: Exemplo de xml


1 <dados>
2 <pessoa nome="Manoel">
3 <endereco rua="Rua 2" numero="30" />
4 <endereco rua="Av Goias" numero="2" />
5 </pessoa>
6 </dados>

15.2. HTML
HTML (acrônimo para a expressão inglesa HyperText Markup Language, que significa Lin-
guagem de Marcação de Hipertexto) é uma linguagem de marcação utilizada para produzir
páginas na Web. Documentos HTML podem ser interpretados por navegadores.

15.2.1 A estrutura básica de um documento HTML


A estrutura de um documento HTML apresenta os seguintes componentes:

<html>
<head>
<title>Título do Documento</title>
</head>
<body>
texto,
imagem,
links,
...
</body>
</html>

158 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

<table> Gera uma tabela


<tr> Uma linha em uma tabela
<td> Uma célula em uma tabela
<link> liga recursos na página
<form> Cria um formulário
<input> Cria um campo de entrada
de dados

Tabela 15.1: Algumas tags HTML

As tags básicas de HTML são:

• < html >: define o início de um documento HTML e indica ao navegador que todo
conteúdo posterior deve ser tratado como uma série de códigos HTML.

• < head >: define o cabeçalho de um documento HTML, que traz informações sobre
o documento que está sendo aberto.

• < body >: define o conteúdo principal, o corpo do documento. Esta é a parte do doc-
umento HTML que é exibida no navegador. No corpo podem-se definir propriedades
comuns a toda a página, como cor de fundo, margens, e outras formatações.

15.2.1.1 Cabeçalho
Dentro do cabeçalho existem os seguintes comandos:

• < title >: define o título da página, que é exibido na barra de título dos navegadores.

• < style >: define formatação em CSS.

• < script >: define programação de certas funções em página com scripts, podendo
adicionar funções de JavaScript.

• < link >: define ligações da página com outros arquivos como feeds, CSS, scripts,
etc.

• < meta >: define propriedades da página, como codificação de caracteres, descrição
da página, autor, etc. São meta informações sobre documento. Tais campos são muitos
usados por motores de busca para obterem mais informações sobre o documento,
afim de classificá-lo melhor. Por exemplo, pode-se adicionar o código < meta name="description"
content="descrição da sua página" / > no documento HTML para indicar ao motor
de busca que texto de descrição apresentar junto com a ligação para o documento.

15.2.2 Outras tags HTML


Algumas das tags HTML podem ser vistas na tabela 15.1.

http://solutioin.com 159
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

15.3. JavaScript
JavaScript é uma linguagem de programação criada pela Netscape em 1995, que a princípio
se chamava LiveScript, para atender, principalmente, as seguintes necessidades:

• Validação de formulários no lado cliente (programa navegador);

• Interação com a página. Assim, foi feita como uma linguagem de script. Javascript
tem sintaxe semelhante à do Java, mas é totalmente diferente no conceito e no uso.

Possui as seguintes características

• Oferece tipagem dinâmica - tipos de variáveis não são definidos;

• É interpretada, ao invés de compilada;

• Oferece bom suporte a expressões regulares (característica também comum a lingua-


gens de script).

Sua união com o CSS é conhecida como DHTML. Usando o Javascript, é possível modi-
ficar dinamicamente os estilos dos elementos da página em HTML.
Dada sua enorme versatilidade e utilidade ao lidar com ambientes em árvore (como
um documento HTML), foi criado a partir desta linguagem um padrão ECMA, o ECMA-
262, também conhecido como ECMAScript. Este padrão é seguido, por exemplo, pela lin-
guagem ActionScript da Adobe.
O uso de JavaScript em páginas HTML deve ser informado ao navegador da seguinte
forma:

<script type="text/javascript">

/* aqui fica o script */

</script>

Caso contrário, o navegador irá interpretar o script como sendo código HTML, escrevendo-
o na página.
Na listagem 15.2 é apresentado um exemplo de JavaScript. Neste exemplo existem duas
funções: clicar e formatarData. A função clicar incrementa o valor o botão a cada vez que é
clicado no botão. A função formatarData formata uma data com as barras quando o campo
de data perde o foco.

Listagem 15.2: Exemplo de JavaScript


1 <html>
2 <head>
3 <title>Exemplo de JavaScript</title>
4 </head>
5

6 <script type="text/javascript">
7 var qtdVezes = 0;

160 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

8 function clicar(comp){
9 qtdVezes++;
10 complemento = qtdVezes > 1 ? "es" : "";
11 comp.value = qtdVezes + " vez" + complemento;
12 }
13

14 function formatarData(comp){
15 data = comp.value;
16 data = data.substring(0,2) + "/" + data.substring(2,4) + "/" +
17 data.substring(4,8);
18 comp.value = data;
19 }
20 </script>
21

22 <body>
23 Clique no botão:
24 <input type="button" value="Clique" onclick="javascript:clicar(this)"/>
25 <br/>
26 Data:<input type="text" onblur="javascript:formatarData(this)"/>
27 </body>
28 </html>

15.4. CSS
Cascading Style Sheets, ou simplesmente CSS, é uma linguagem de estilo utilizada para
definir a apresentação de documentos escritos em uma linguagem de marcação, como
HTML ou XML. Seu principal benefício é prover a separação entre o formato e o conteúdo
de um documento.
Ao invés de colocar a formatação dentro do documento, o desenvolvedor cria um link
(ligação) para uma página que contém os estilos, procedendo de forma idêntica para todas
as páginas de um site. Quando quiser alterar a aparência do site basta portanto modificar
apenas um arquivo, o arquivo de estilo.
As especificações do CSS podem ser obtidas no site da W3C "Word Wide Web Consor-
tium", um consórcio de diversas empresas que buscam estabelecer padrões para a internet.
É importante notar que nenhum browser suporta igualmente as definições do CSS. Desta
forma, o webdesigner deve sempre testar suas folhas de estilo em browsers de vários fab-
ricantes, e preferencialmente em mais de uma versão, para se certificar de que o que foi
codificado realmente seja apresentado da forma desejada.
Com a variação de atualizações dos navegadores (browsers) como Internet Explorer que
ficou sem nova versão de 2001 a 2006, o suporte ao CSS pode variar. O Internet Explorer
6, por exemplo, tem suporte total a CSS1 e praticamente nulo a CSS2. Navegadores mais
modernos como Opera, Internet Explorer 7 e Mozilla Firefox tem suporte maior, inclusive
até a CSS 3, ainda em desenvolvimento.
O código:

/* comentário em css */
body

http://solutioin.com 161
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

{
font-family: Arial, Verdana, sans-serif;
background-color: #FFFFFF;
margin: 5px 10px;
}

define fonte padrão Arial, caso não exista substitui por Verdana, caso não exista define
qualquer fonte sem serifa. Define também a cor de fundo do corpo da página.
Na listagem 15.3 é apresentado um exemplo de uma página HTML. Note a tag link:

<link href="estilo.css" type="text/css" rel="stylesheet"/>

Esta tag faz ligação com o arquivo da listagem 15.4 que é o arquivo CSS. Observe que no
estilo.css existem definições de formatação das tags da página da listagem 15.3.

Listagem 15.3: Exemplo de página HTML


1 <html>
2 <head>
3 <link href="estilo.css" type="text/css" rel="stylesheet"/>
4 <title>Primeira página HTML</title>
5 </head>
6 <body>
7 <h1>Tabela de Cursos</h1>
8 <table>
9 <tr>
10 <th>Curso</th>
11 <th>Carga Horária</th>
12 <th>Instrutor</th>
13 </tr>
14 <tr>
15 <td>Java</td>
16 <td>80 Horas</td>
17 <td>Francisco</td>
18 </tr>
19 <tr>
20 <td>Delphi</td>
21 <td>160 Horas</td>
22 <td>Danilo</td>
23 </tr>
24 <tr>
25 <td>Linux</td>
26 <td>160 Horas</td>
27 <td>Diogo</td>
28 </tr>
29 </table>
30 </body>
31 </html>

Listagem 15.4: estilo.css - exemplo de css


1 h1{

162 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

2 font-family: verdana;
3 font-size: 25pt;
4 color: #00aa22;
5 font-weight: bold;
6 }
7

8 th{
9 font-family: verdana;
10 font-size: 15pt;
11 color: #0022aa;
12 }
13 td{
14 font-family: verdana;
15 font-size: 12pt;
16 color: #00aa22;
17 background-color: #ccccff;
18 }

15.5. Aplicativos Web com Java


Para a construção de aplicativos WEB utilizando o Java será necessário todas as tecnologias
apresentadas:
• Html, para construção do conteúdo

• CSS, para construção da apresentação

• JavaScript, para construção do dinamismo como as máscaras


A linguagem Java deverá ser executada em um servidor e está auxiliará a criação de
conteúdo html, css e javascript. Existem vários servidores WEB. Comumente é chamado de
contêiner o servidor que executa o código java.
Neste livro será utilizado o contêiner WEB chamado tomcat na sua versão 5.5.

15.5.1 Instalação do Tomcat


Para instalar o tomcat siga as seguintes instruções:
Faça o download do tomcat através do site tomcat.apache.org
Descompacte o arquivo. (Preferencialmente dentro do diretório AreaDeTabalho/MeusAplica-
tivos).
Configure a variável de ambiente

JAVA_HOME

para o diretório raiz onde está instalado o JDK.


Vá ao diretorio bin do tomcat e execute o comando startup.bat
Abra o browser e acesse o endereço http://localhost:8080. Se aparecer uma página
ilustrada na figura 15.1 o tomcat está devidamente instalado.

http://solutioin.com 163
Francisco Calaça, Otávio Calaça
Versão 1.1 aplicativos web

Figura 15.1: Tela inicial do tomcat

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

15.6. Exercícios
1. O que são arquivos xml?

2. O que são arquivos html?

3. O que é JavaScript?

4. Crie um script JavaScript para colocar a máscara de data em um campo.

5. O que é css?

6. Pesquise sobre o padrão w3c tableless.

7. Quais os procedimentos necessários para instalação do tomcat?

164 http://solutioin.com
Francisco Calaça, Otávio Calaça
S E RV L E T S
16
Servlet é uma tecnologia que insere novos recursos a um servidor, a definição mais usada
é que são consideradas extensões de servidores, essa tecnologia disponibiliza ao desen-
volvedor do sistema uma interface para o servidor de aplicação, através de uma API. As
aplicações baseadas em Servlet geram conteúdo dinâmico e interagem com os clientes, uti-
lizando o modelo request/response (requisição e resposta) do protocolo HTTP. Apesar de
normalmente utilizam o protocolo HTTP, os Servlets não são restritos a ele.
Um Servlet necessita de um contêiner Web para ser executado. Este contêiner Web pode
ser um servidor de aplicações como o JBoss, GlassFish, Apache Gerônimo, etc ou apenas
um contêiner como o Tomcat.
A estrutura de um Servlet é simples, basicamente são classes Java que implementam a
interface Servlet. Os servlets que responderão ao protocolo HTTP (a maioria) deveom es-
tender a classe HttpServlet, que implementa a interface Servlet. Além disto é necessário
configurar o Servlet no descritor de implantação da aplicação. Este descritor de implan-
tação é o arquivo web.xml.

16.1. Estrutura de uma aplicação web Java


As aplicações Java WEB seguem a estrutura apresentada na figura 16.1. Nesta figura é
possível observar os seguintes elementos:

• app1 - É o contexto. É o diretório onde fica armazenada a aplicação

• WEB-INF - É o diretório onde ficam as classes java, as bibliotecas e os arquivos de


configuração.

• classes - É o diretório onde ficam as classes Java. Este diretório é opcional, precisa
existir apenas se existirem classes Java na aplicação.

• lib - É o diretório onde ficam os arquivos .jar. Este diretório é opcional, precisa existir
apenas se existirem arquivos .jar.

• web.xml - É o descritor de implantação. Este arquivo possui as configurações gerais


da aplicação. Este arquivo é obrigatório.

16.2. Construindo o primeiro Servlet


Para exemplificar a estrutura de um aplicativo WEB Java observe o exemplo. Na listagem
16.1 é apresentada a classe do servlet. Observe que esta classe estende HttpServlet. O

165
Versão 1.1 servlets

Figura 16.1: Exemplo de estrutura de uma aplicação WEB

método doGet é o método executado quando ocorre uma requisição a esse servlet. Note
que nesse método é gerada uma resposta html que será apresentada no browser.
Para que tudo funcione corretamente é necessário montar a estrutura de um aplicativo
web apresentado na figura 16.1. Primeiramente crie o diretório app1. Dentro do diretório
app1 crie o diretório WEB-INF. dentro do diretório WEB-INF crie o diretório classes. Com-
pile a classe PrimeiroServlet e após isto coloque o pacote capitulo16 gerado dentro do
diretório classes. Note que para compilar essa classe é necessário ter o arquivo servlet.jar
configurado no classpath de compilação. Este arquivo pode ser encontrado dentro de com-
mon/lib do tomcat instalado. Crie o descritor de implantação apresentado na listagem
18.10 e coloque-o dentro do diretório WEB-INF. Certifique-se de ter ficado como a figura
16.1.
Após ter montado esta estrutura coloque-a dentro do diretório webapps do tomcat in-
stalado no capítulo anterior. Certifique-se de que o tomcat esteje sendo executado. Acesse
o endereço: http://localhost:8080/app1/prim. Se aparecer a figura 16.2 tudo funcionou
corretamente.

Listagem 16.1: Classe PrimeiroServlet. Um exemplo de servlet


1 package capitulo16;
2

3 import java.io.IOException;
4 import java.io.PrintWriter;
5

6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11

12 @WebServlet("/PrimeiroServlet")
13 public class PrimeiroServlet extends HttpServlet {
14

15 public void doGet(HttpServletRequest request, HttpServletResponse response) throws


ServletException, IOException {
16 response.setContentType("text/html");
17 PrintWriter out = response.getWriter();
18 out.println("<HTML >");
19 out.println("<HEAD ><TITLE >Primeiro Servlet </TITLE ></HEAD >");

166 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

20 out.println("<BODY >");
21 out.println("<H1>PRIMEIRO SERVLET FUNCIONANDO ...</H1>");
22 out.println("</BODY >");
23 out.println("</HTML >");
24 out.close();
25 }
26

27 }

Listagem 16.2: O descritor de implantação web.xml


1 <web-app>
2 <display-name>Exemplo de servlet</display-name>
3

4 <servlet>
5 <servlet-name>primeiro</servlet-name>
6 <servlet-class>capitulo16.PrimeiroServlet</servlet-class>
7 </servlet>
8

9 <servlet-mapping>
10 <servlet-name>primeiro</servlet-name>
11 <url-pattern>/prim</url-pattern>
12 </servlet-mapping>
13 </web-app>

Figura 16.2: O primeiro servlet funcionando

16.3. Como fazer no eclipse


O eclipse nos ajuda a construir um projeto WEB de forma mais fácil. Isto não o isenta de
entender bem toda a estrutura de um aplicativo WEB.

http://solutioin.com 167
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Vá em File - New - Project. Escolha Dynamic Web Project, conforme ilustrado na figura
16.7.
Na tela seguinte é possível configurar o nome da aplicação e em qual servidor será
executada. Escolha Apache Tomcat v5.5 conforme a figura 16.8. Se não aparecer esta opção
clique no botão New e configure.
Na tela seguinte é possível configurar os FrameWorks utilizados neste projeto. Deixe
como está. Esta tela está ilustrada na figura 16.9.
Por último é possível configurar o nome do contexto. O diretório onde ficará os arquivos
WEB e o diretório onde ficarão os arquivos .java conforme mostra a figura 16.10.

Figura 16.3: Novo projeto Web no eclipse

16.4. Atendendo requisições com o método get


A listagem 16.3 apresenta a classe do servlet que receberá as informações através do método
get. Note que todo o código que atenderá a requisição fica dentro do método doGet. Este
método recebe dois parâmetros um do tipo HttpServletRequest que possui as informações
da requisição e um do tipo HttpServletResponse que possibilita a construção da resposta.
É utilizado o método getParameter:

String nascimento = request.getParameter("nascimento");

para buscar as informações que vêm da requisição.


A listagem 16.4 apresenta a página html que invocará o servlet e enviará as informações
através do método get. Note o uso da tag

<form action="ExemploGet" method="GET">

168 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Figura 16.4: Novo projeto Web no eclipse

http://solutioin.com 169
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Figura 16.5: Novo projeto Web no eclipse

Figura 16.6: Novo projeto Web no eclipse

170 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Figura 16.7: Novo projeto Web no eclipse

Figura 16.8: Configuração do nome do projeto

http://solutioin.com 171
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Figura 16.9: Configuração dos frameworks web

Figura 16.10: Configuração do diretório dos fontes e dos arquivos web

172 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

o atributo action descreve qual recurso será invocado quando for clicado no botao submit
e o atributo method descreve qual método será utilizado, no caso GET.
Observe que os parâmetros que você digitou no formulário aparecem na url enviada
pelo browser. Esta é a característica do método get: envia os parâmetros através da URL.

Listagem 16.3: Servlet do exemplo de passagem de parâmetros com o método get


1 package capitulo16;
2

3 import java.io.IOException;
4 import java.io.PrintWriter;
5

6 import javax.servlet.RequestDispatcher;
7 import javax.servlet.ServletException;
8 import javax.servlet.annotation.WebServlet;
9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12

13 @WebServlet("/ExemploGet")
14 public class ExemploGet extends HttpServlet {
15

16 protected void doGet(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
17 response.setContentType("text/html");
18 PrintWriter out = response.getWriter();
19 String nome = request.getParameter("nome");
20 String nascimento = request.getParameter("nascimento");
21

22 out.println("<html >");
23 out.println("<body >");
24 out.printf("%s nasceu em %s", nome, nascimento);
25 out.println("</body >");
26 out.println("</html >");
27 out.close();
28 }
29 }

Listagem 16.4: Página Html que enviará as informações através do método get
1 <html>
2 <head>
3 <title>Exemplo Get</title>
4 </head>
5 <body>
6 <form action="ExemploGet" method="get">
7 Nome: <input type="text" name="nome" /><br/>
8 Data de nascimento: <input type="text" name="nascimento" /><br/>
9 <input type="submit" value="Enviar"/>
10 </form>
11 </body>
12 </html>

http://solutioin.com 173
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

16.5. Atendendo requisições com o método post


Diferente do método get o método post envia as informações para o servidor no corpo da
solicitação. As informações não aparecerão na URL como no método GET.
A listagem 16.5 apresenta o servlet que atenderá às requisições post. Note que agora foi
implementado o método doPost.
A listagem 16.6 apresenta a página que enviará as informações através do método post.
Note que a unica diferença com o envio com método GET é o atributo method da tag form
que agora é POST.
Listagem 16.5: Servlet do exemplo de passagem de parâmetros com o método post
1 package capitulo16;
2

3 import java.io.IOException;
4 import java.io.PrintWriter;
5

6 import javax.servlet.RequestDispatcher;
7 import javax.servlet.ServletException;
8 import javax.servlet.annotation.WebServlet;
9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12

13 @WebServlet("/ExemploPost")
14 public class ExemploPost extends HttpServlet {
15

16 protected void doPost(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
17 response.setContentType("text/html");
18 PrintWriter out = response.getWriter();
19

20 String nome = request.getParameter("nome");


21 String endereco = request.getParameter("endereco");
22 String salario = request.getParameter("salario");
23

24 out.println("<html >");
25 out.println("<body");
26 out.printf("Nome: %s <br/>", nome);
27 out.printf("Endereco: %s <br/>", endereco);
28 out.printf("Salario: %s <br/>", salario);
29 out.println("</body >");
30 out.println("</html >");
31 out.close();
32 }
33 }

Listagem 16.6: Página Html que enviará as informações através do método post
1 <html>
2 <head>
3 <title>Exemplo método post</title>

174 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

4 </head>
5 <body>
6 <form action="ExemploPost" method="POST">
7 <pre>
8 Nome: <input type="text" name="nome" />
9 Endereco: <input type="text" name="endereco" />
10 Salario: <input type="text" name="salario" />
11 <input type="submit" />
12 </pre>
13 </form>
14 </body>
15 </html>

16.6. Redirect
Para exemplificar o redirect pense em um Call Center. Imagine você ligando para um Call
Center para fazer uma reclamação de sua conta telefônica. Após ser atendido pelo primeiro
atendente você conta toda a história que originou a ligação. O atentende espera até você
terminar e diz: Não é comigo. Vou transfefir o senhor para o departamento responsável.
Você se irrita um pouco e diz: Tudo bem. Um novo antendente atente e solicita a você
que conte o problema a ele. Você conta o problema e ele o ouve até terminar. Quando
você termina o novo atendente diz: Também não é comigo. Vou transferir o senhor para o
departamento responsável. Aí você um pouco mais irritado espera. Na terceira vez conta,
novamente toda a história e assim vai.
Neste caso ocorre um redirect. Quando é feito um redirect entre recursos WEB com
o protocolo HTTP é como se fosse necessário contar novamente toda a história ao novo
recurso e fica claro, para o solicitante, que houve mudança de “servlet atendente”.
As páginas das Listagens 16.9 e 16.10 apresentam o resultado.
Note o uso do método sendRedirect:

response.sendRedirect(pagina);

para realizar o redirecionamento para a página de resultado. Com o redirect será feita
uma nova requisição para as páginas e você observará que, ao clicar no botão, automati-
camente será redirecionado para aprovado.html ou reprovado.html. Ficou claro que quem
originou a resposta foram as próprias páginas.

Listagem 16.7: Página inicial do exemplo com redirect


1 <html>
2 <head>
3 <title>Exemplo Redirect</title>
4 </head>
5 <body>
6 <form action="ExemploRedirect" method="post">
7 Salário: <input type="text" name="salario"/>
8 <input type="submit" value="Enviar"/>
9 </form>

http://solutioin.com 175
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

10 </body>
11 </html>

Listagem 16.8: Servlet do exemplo de Redirect


1 package capitulo16;
2

3 import java.io.IOException;
4

5 import javax.servlet.RequestDispatcher;
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11

12 @WebServlet("/ExemploRedirect")
13 public class ExemploRedirect extends HttpServlet {
14

15 protected void doPost(HttpServletRequest request,HttpServletResponse response)


throws ServletException, IOException {
16 double salario = Double.parseDouble(request.getParameter("salario"));
17 String pagina;
18 if(salario >= 5000){
19 pagina = "aprovado.html";
20 }else{
21 pagina = "reprovado.html";
22 }
23

24 response.sendRedirect(pagina);
25 }
26 }

Listagem 16.9: Tela que apresenta o resultado: aprovado


1 <html>
2 <head>
3 <title>Aprovado</title>
4 </head>
5 <body>
6 <h1 style="color: green;">LIMITE APROVADO</h1>
7 </body>
8 </html>

Listagem 16.10: Tela que apresenta o resultado: reprovado


1 <html>
2 <head>
3 <title>Rerovado</title>
4 </head>
5 <body>
6 <h1 style="color: red;">LIMITE REPROVADO</h1>
7 </body>

176 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

8 </html>

16.7. Forward
Diferente do redirect o forward esconde quem realizou a resposta. Seria como se você
tivesse ligado para o Call Center e contado o seu problema. O atendente falasse: -Espera um
pouco. Neste momento ele pergunta para um colega que é o especialista naquele problema
o que fazer. Após ter a resposta ele volta ao telefone e te conta a resposta. Você não teve que
contar novamente sua história. Você também não conheceu quem realmente solucionou seu
problema pois a única pessoa que você teve contato foi o atendente inicial. Isto é forward.
O servlet da listagem 16.12 apresenta um exemplo de forward. Para a realização do
forward foram utilizadas as seguintes instruções:

RequestDispatcher rd = request.getRequestDispatcher(pagina);
rd.forward(request, response);

Note que após clicar no botão você vê a resposta mas não percebe que foi gerada pelas
páginas aprovado.html ou reprovado.html.

Listagem 16.11: Página inicial do exemplo com forward


1 <html>
2 <head>
3 <title>Exemplo Forward</title>
4 </head>
5 <body>
6 <form action="ExemploForward" method="post">
7 Salário: <input type="text" name="salario"/>
8 <input type="submit" value="Enviar"/>
9 </form>
10 </body>
11 </html>

Listagem 16.12: Servlet do exemplo de Forward


1 package capitulo16;
2

3 import java.io.IOException;
4

5 import javax.servlet.RequestDispatcher;
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11

12 @WebServlet("/ExemploForward")
13 public class ExemploForward extends HttpServlet{
14

http://solutioin.com 177
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

15 protected void doPost(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
16 double salario = Double.parseDouble(request.getParameter("salario"));
17 String pagina;
18 if(salario >= 5000){
19 pagina = "aprovado.html";
20 }else{
21 pagina = "reprovado.html";
22 }
23

24 RequestDispatcher rd = request.getRequestDispatcher(pagina);
25 rd.forward(request, response);
26 }
27

28 }

16.8. Escopo de objetos web


Enquanto o usuário estiver em uma página, os valores do componente serão lembrados
mesmo quando a página for reexibida, como quando o usuário clica em um botão que
retorna nulo. No entanto, quando o usuário sai da página, os valores do componente desa-
parecem.
Para tornar os valores disponíveis para outras páginas, ou para a mesma página, caso o
usuário retorne à página, você precisa armazenar os valores. Quando você cria um projeto
a partir do IDE, ele cria três Beans gerenciados para armazenar os valores:

• Request - requisição

• Session - sessão

• Application - aplicação

A figura 16.11 ilustra esses escopos.

16.8.1 Request
Tudo que é armazenado no escopo de request é válido apenas enquanto durar uma requi-
sição. Se o usuário clicar em algum link ou algum servlet realizar um redirec as informações
armazenadas neste escopo se perdem.
Para acessar este escopo utilize os método:

request.getAttribute(‘‘bean’’); // para buscar informações do escopo


request.setAttribute(‘‘bean’’, bean); // para colocar informações no escopo.

178 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Figura 16.11: Ilustração dos escopos WEB

16.8.2 Session
Tudo que é armazenado no escopo de session é válido enquanto durar a sessao com o
usuário. Uma sessão normalmente é representada com uma janela do browser aberta. É
neste escopo que são armazenadas as informações de login do usuário ou o carrinho de
compras em uma loja virtual.
Para acessar este escopo utilize o método:

request.getSession().getAttribute(‘‘bean’’); //para buscar informações do escopo


request.getSession().setAttribute(‘‘bean’’, bean); // para colocar informações no escopo.

16.8.3 Application
Tudo que é armazenado no escopo de application é valido para todos os usuários mesmo
estando em browsers diferentes, mesmo estando em lugares diferentes. Em um chat seria
um bom local para armazenar as mensagens que devem ser vistas por todos.
Para acessar este escopo utilize o método:

getServletContext().getAttribute(‘‘bean’’); //para buscar informações do escopo


getServletContext().setAttribute(‘‘bean’’, bean); // para colocar informações no escopo.

16.9. Como distribuir uma aplicação web


No início deste capítulo foi apresentada a estrutura de um aplicativo web Java. Existem
uma série de detalhes a serem seguidos e que dificultam a distribuição de aplicações Java
uma vez que cada aplicativo consiste de vários arquivos. Para solucionar este problema é
possível comprimir todos estes arquivos que estão no contexto utilizando o formato zip em
um arquivo com extensão .war.

http://solutioin.com 179
Francisco Calaça, Otávio Calaça
Versão 1.1 servlets

Assim ao compactar o conteúdo da aplicação em um arquivo com extensão war tornará


mais fácil a distribuição dos aplicativos. Atenção é compactado o conteúdo da pasta app1,
não a pasta app1.
O eclipse possui uma ferramenta que faz isto de forma automática. Para isto, basta clicar
com o botão direito do mouse sobre o projeto e exportar o arquivo war.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

16.10. Exercícios
1. O que é um servlet?

2. Explique a estrutura de um aplicação Java.

3. Quais são os passos para implementação de um servlet ?

4. Qual o diretório do tomcat onde ficam armazenados as aplicações?

5. Diferencie os métodos get e post.

6. Qual a diferenca entre redirect e forward?

7. Quais os escopos de um aplicativo web?

8. O que são arquivos .war ?

180 http://solutioin.com
Francisco Calaça, Otávio Calaça
J AVA S E RV E R PA G E S
17
JavaServer Pages - JSP - é uma tecnologia que simplifica o processo de desenvolvimento
de aplicações web. Com JSP, os desenvolvedores podem rapidamente incorporar elemen-
tos dinâmicos em páginas da web, utilizando Java embutido e algumas tags. Estas tags
fornecem ao desenvolvedor um meio de acessar dados e lógica de negócio armazenados
em objetos Java sem ter que dominar as complexidades do desenvolvimento de aplicações.
O JSP também oferece a vantagem de ser facilmente codificado, facilitando assim a elab-
oração e manutenção de uma aplicação. Além disso, essa tecnologia permite separar a
programação lógica (parte dinâmica) da programação visual (parte estática), facilitando o
desenvolvimento de aplicações mais robustas, onde programador e designer podem trabal-
har no mesmo projeto, mas de forma independente.
Os arquivos jsp’s são convertido em servlet’s (arquivos .java) e compilados para arquivos
.class. Normalmente a primeira execução do jsp é mais lenta que as demais pois o contêiner
está realizando essa operação.

17.1. Elementos do Jsp


É possível inserir código Java dentro do servlet a ser gerado a partir do JSP. Isto pode ser
feito de três formas:

• Scriptlets: que insere dentro do servlet código Java

• Expressões: que tem seu valor escrito na página;

• Declarações: utilizadas para criarem métodos e classes dentro do JSP.

Cada um destes elementos será descrito a seguir.

17.1.1 Scriptlet
Scriptlets são trechos de código Java dentro de págianas HTML. Um Scriptlet fica entre as
tags

<% -- código java -- %>

O Trecho de código abaixo é um exemplo de página HTML, com scriptlets JSP que
escrevem na tela: “Olá Mundo”

<%

181
Versão 1.1 java server pages

String msg = "Olá Mundo";


out.println("Mensagem: "+msg+"!!");
%>

Scriptlets tem acesso à algumas variáveis definidas como request, session, etc.:

<%
String dados = request.getQueryString();
out.println("Dados anexados: " + dados);
%>

<% if (Math.random() < 0.5) { %>


Você está com <B>Sorte</B>!
<% } else { %>
Você não está com tanta <B>Sorte</B> assim!
<% } %>

17.1.2 Expressões
Uma expressão JSP é usada para escrever variáveis Java direntamente na página. Veja o
exemplo a seguir:

<%= Expressão Java %>

A expressão Java será convertida em uma String e escrita na página. Por exemplo, o
código seguinte:

Data atual: <%= new java.util.Date() %>

escreve a data utilizando o toString() da classe Date


A listagem 17.1 apresenta um exemplo de scriptlets e expressões. Após implementado,
para visualizar este exemplo, acesso a seguinte url no browser: http://localhost:8080/capitulo17/exemploJsp.j

Listagem 17.1: Arquivo exemploJsp.jsp. Apresenta um exemplo de scriptlets e expressões


1 <html>
2 <head>
3 <title>Exemplo de JSP</title>
4 </head>
5 <body>
6 <%for(int i = 0; i < 15; i++){ %>
7

8 Linha: <%=i %> <br/>


9

10 <%} %>
11

12 </body>
13 </html>

182 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

17.1.3 Declarações
Uma declaração JSP define métodos, campos ou classes que serão inseridos no corpo do
Servlet gerado pela página. Portanto, o código abaixo:

<%! void somar(int a, int b){ . . .} $ %> $

é capaz de declarar um método na página.

17.2. Diretivas
Uma diretiva JSP afeta toda a estrutura da página. Este é um exemplo de diretiva:

<%@ diretiva atributo=‘‘valor" %>

As diretivas existentes são:

• include - inclusão de um arquivo na posição da diretiva

• page - informações e metadados da página

• taglib - inclusão de taglibs

17.2.1 Diretiva include


A Listagem 17.2 apresenta o código do menu, que será inserido dentro das demais páginas.
Observe na Listagem 17.3 a utilização da diretiva include com o objetivo de incluir o código
do menu dentro da página index.jsp.

Listagem 17.2: Arquivo menu.jsp


1 <a href="index.jsp">Início</a>
2 <a href="exemploJsp.jsp">Primeiro Exemplo</a>
3 <a href="clientes.jsp">Lista de Clientes</a>
4 <a href="clientes -jstl.jsp">Lista de Clientes com JSTL</a>

Listagem 17.3: Arquivo index.jsp


1 <html>
2 <head>
3 <title>Página inicial</title>
4 </head>
5 <body>
6 <%@include file="menu.jsp" %>
7

8 <h1>Página inicial</h1>
9 </body>
10 </html>

http://solutioin.com 183
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

Depois de implementar os exemplos das Listagens 17.2 e 17.3 adicione o código:

<%@include file="menu.html" %>

no arquivo exemploJsp.jsp

17.2.2 Diretiva Page


Esta diretiva possui onze atributos diferentes. Observe primeiro como é a sua sintaxe:

<%@ page atributo1="valor1" atributo2="valor2" atributo3="valor3" ... %>

Por possuir múltiplos atributos a linguagem JSP permite que se declare várias diretivas
numa mesma página, porém a único atributo que pode ser repetido é o import.
Nas subseções à seguir serão descritos os atributos desta diretiva.

17.2.2.1 ContentType
Este atributo indica qual o tipo MIME (Multipurpose Internet Mail Extensions) da resposta
está sendo gerada pela JSP. Os tipos mais comuns são: “text/plain”, “text/html”, “tex-
t/xml”. Logo abaixo segue o exemplo usado como padrão para as JSPs.

<%@ page contentType="text/html" %>

17.2.2.2 pageEncoding
Define o caracter enconding da página.

<%@ page pageEncoding="UTF-8" %>

17.2.2.3 Extends
Serve para indicar a super classe que será usada pelo container JSP no momento de
tradução da página em um Servlet Java. Exemplo:

<%@ page extends="com.solutioin.taglib.jsp.primeirapagina" %>

17.2.2.4 Import
Com o atribuo import, diferente do extends, é capaz de estender um conjunto de classes
Java que poderão ser usadas nas páginas JSPs. Exemplo:

<%@ page import="java.util.List" %>

17.2.2.5 Language
Usado, em geral, para especificar Java como a linguagem de criação de script para a página.
Exemplo:

<%@ page language="java" %>

184 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

17.2.2.6 Info
Usado para inserir informações sumarizadas da página, não havendo restrições ao seu
tamanho. Exemplo:

<%@ page info="Java Para Web" %>

17.2.2.7 Session
Session é do tipo boolean, indica se a página está participando do gerenciamento de sessão.
Por exemplo, se quisermos dizer que uma página é parte de uma sessão, utiliza-se a
seguinte sintaxe:

<%@ page session="true" %>

17.2.2.8 Buffer
Responsável por controlar a saída bufferizada para uma página JSP. Se for ajustado para
“none” o conteúdo de uma JSP é passado instantaneamente à resposta HTTP. O tamanho
do buffer é descrito em kilobytes. Exemplo:

<%@ page buffer="20kb" %> ou <%@ page buffer="none" %>

17.2.2.9 AutoFlush
Semelhante ao Buffer, também é responsável por controlar a saída buferizada, mais exata-
mente o comportamento do container JSP quando já esteja cheio o Buffer de saída. Neste
caso é esvaziado automaticamente o Buffer de saída e o conteúd0o enviado para o servidor
HTTP que transmite para o Browser responsável pela solicitação. Sendo do tipo boolean,
sua sintaxe é dada abaixo:

<%@ page autoFlush="true" %>

17.2.2.10 isThreadSafe
Quando uma página JSP é compilada em um Servlet, ela deve ser capaz de atender a
múltiplas solicitações. Para isso devemos utilizar o atributo isThreadSafe, caso contrário é
necessário defini-lo como “false”. Exemplo:

<%@ page isThreadSafe="false" %>

17.2.2.11 errorPage
ErrorPage indica uma página alternativa que será exibida caso aconteça um erro não pre-
visto durante o processamento de uma página JSP no container. Exemplo:

<%@ page errorPage="/apostila/exemplos/erro.jsp" %>

http://solutioin.com 185
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

jsp:include Inclui um arquivo que foi gerado em


tempo de execução na página
jsp:useBean Busca um Bean instanciado.
jsp:setProperty Seta a propriedade de um JavaBean.
jsp:getProperty Insere a propriedade do JavaBean na
página.
jsp:forward Realiza um forward para outra página.
jsp:plugin Gera um código para embutir plugins
Java.

Tabela 17.1: tablecaption

17.2.2.12 isErrorPage
Responsável por define uma página JSP que servirá como a página de erro padrão para um
grupo de páginas JSP. Sendo do tipo boolean, sua sintaxe é descrita abaixo:

<%@ page isErrorPage="true"%>

17.3. Ações do JSP


Comandos que executam ações durante o processamento do JSP
São comandos na sintaxe XML que controlam o comportamento da execução do JSP. Com
ações JSP é possível inserir um arquivo dinamicamente, reutilizar um Java Bean, fazer um
forward para outra página ou gerar código HTML para um plugin Java. Algumas açoes
disponíveis são:

17.4. Biblioteca de tags JSTL


A JSTL (Standard Tag Library for JavaServer Pages) foi criada para organizar melhor o código
de um JSP evitando a inserção de código Java dentro das mesmas. Normalmente quem
edita as páginas JSP são web designers que não sabem programar em Java.
JSTL consiste em uma coleção de bibliotecas, tendo cada uma um propósito bem definido,
que permitem escrever páginas JSPs sem código Java, aumentando assim a legibilidade do
código e a interação entre desenvolvedores e web designers. Cada tag realiza um determi-
nado tipo de processamento (equivalente a código Java dentro de JSP). Exemplo de uma
página JSTL

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>


<html>
<body bgcolor="#FFFFFF">

<jsp:useBean id="agora" class="java.util.Date"/>

186 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

<br>
Hoje: <fmt:formatDate value="${agora}" />

<br> Agora: <fmt:formatDate value="${agora}" pattern="dd/MM/yyyy"/>


</body>
</html>

Versão Curta: 25/07/2005

Versão Longa: Segunda-feira, 25 de Julho de 2005

A taglib mais utilizada é a central. Normalmente é prefixada com “c”. Possui tags para
trabalhar com condicionais, loops, condicionais, dentre outras. Sua declaração é:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

Uma tag muito utilizada é a <c:forEach>. Esta tag permite percorrer uma lista de objetos
e apresenta-los na página.

17.4.1 EL - Expressão de Linguagem


As expressões EL estão sempre dentro de chaves, precedidas pelo símbolo cifrão:
${ . . . }

Exemplo:
${cliente.nome}

São utilizadas para referenciar objetos no código JSP:


Telefone: ${cliente.endereco}

ou ainda
<c:forEach items="${lista}" var="cliente">

O trecho de código abaixo apresenta todos os contatos de uma lista:


<table border="1">
<c:forEach items="${lista}" var="cliente">
<tr>
<td>${cliente.id}</td>
<td>${cliente.nome}</td>
<td>${cliente.endereco}</td>
<td>${cliente.municipio}</td>
<td>${cliente.uf}</td>
<td><a href="ClienteControl?acao=excluir&id=${cliente.id}">excluir</a></td>
</tr>
</c:forEach>
</table>

http://solutioin.com 187
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

17.5. MVC - Model View Control


Model-view-controller (MVC) é um padrão de arquitetura de software. Com o aumento
da complexidade das aplicações desenvolvidas torna-se fundamental a separação entre os
dados (Model) e o layout (View). Desta forma, alterações feitas no layout não afetam os
dados, e estes poderão ser reorganizados sem alterar o layout.
O MVC resolve o problema do reaproveitamento do modelo através da separação das
tarefas de acesso aos dados e lógica de negócio da lógica de apresentação e de interacção
com o usuário. Para isto é introduzido um componente entre a visão e o modelo: o Con-
troller.
Neste sentido, as camadas do MVC representam:
Model: A representação "domínio" específica da informação em que a aplicação opera.
Por exemplo, aluno, professor e turma fazem parte do domínio de um sistema acadêmico.
É comum haver confusão pensando que Model é um outro nome para a camada de domínio.
Lógica de domínio adiciona sentido à dados crus (por exemplo, calcular se hoje é aniver-
sário do usuário, ou calcular o total de impostos e fretes sobre um determinado carrinho
de compras). Muitas aplicações usam um mecanismo de armazenamento persistente (como
banco de dados) para armazenar dados. MVC não cita especificamente a camada para
acesso aos dados, porque subentende-se que estes métodos estariam encapsulados pelo
Model.
View: "Renderiza" o model em uma forma específica para a interação, geralmente uma
interface de usuário.
Controller: Processa e responde a eventos, geralmente ações do usuário, e pode invocar
alterações no Model.

17.5.1 O cadastro de clientes


Agora será apresentado uma versão WEB para o cadastro de clientes apresentado no Capí-
tulo 13. Para que este cadastro funcione é necessário criar o servlet ClienteControl. Este servlet
representa a camada de Controle do nosso exemplo. Seu código está na Listagem 18.4.
Na listagem 17.5 é apresentado o código da tela.

Listagem 17.4: Servlet que representa o Controle


1 package capitulo17;
2

3 import java.io.IOException;
4

5 import javax.servlet.RequestDispatcher;
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11

12 import capitulo13.Cliente;
13 import capitulo13.ClienteDao;

188 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

14

15 @WebServlet("/ClienteControl")
16 public class ClienteControl extends HttpServlet {
17

18 protected void doGet(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
19 String acao = request.getParameter("acao");
20 ClienteDao clienteDao = new ClienteDao();
21 if(acao == null){
22 request.setAttribute("lista", clienteDao.listar());
23 RequestDispatcher rd = request .getRequestDispatcher("cliente.jsp");
24 rd.forward(request, response);
25 }else if(acao.equals("excluir")){
26 int id = Integer.parseInt(request.getParameter("id"));
27 clienteDao.excluir(id);
28 response.sendRedirect("ClienteControl");
29 }else if(acao.equals("confirmar")){
30 Cliente cliente = new Cliente();
31 cliente.setNome(request.getParameter("nome"));
32 cliente.setCpfCnpj(request.getParameter("cpfCnpj"));
33 cliente.setEndereco(request.getParameter("endereco"));
34 cliente.setMunicipio(request.getParameter("municipio"));
35 cliente.setUf(request.getParameter("uf"));
36 clienteDao.incluir(cliente);
37 response.sendRedirect("ClienteControl");
38 }
39 }
40

41 protected void doPost(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException {
42 doGet(request, response);
43 }
44

45 }

Listagem 17.5: Página de cadastro de clientes


1 <%@ taglib prefix="c" uri="http ://java.sun.com/jsp/jstl/core"%>
2

3 <html>
4 <head>
5 <title>Cadastro de Clientes</title>
6 </head>
7 <body>
8

9 <%@ include file="menu.jsp" %>


10

11 <form action="ClienteControl">
12 <pre>
13 <input type="hidden" name="acao" value="confirmar"/>
14 Nome: <input type="text" name="nome"/>
15 CPF/CNPJ: <input type="text" name="cpfCnpj"/>
16 Endereço: <input type="text" name="endereco"/>

http://solutioin.com 189
Francisco Calaça, Otávio Calaça
Versão 1.1 java server pages

17 Município: <input type="text" name="municipio"/>


18 UF: <input type="text" name="uf"/>
19 <input type="submit" value="Confirmar"/>
20 </pre>
21 </form>
22

23 <table border="1" rules="all">


24 <c:forEach items="${lista}" var="cliente">
25 <tr>
26 <td>${cliente.id}</td>
27 <td>${cliente.nome}</td>
28 <td>${cliente.cpfCnpj}</td>
29 <td>${cliente.endereco}</td>
30 <td>${cliente.municipio}</td>
31 <td>${cliente.uf}</td>
32 <td><a href="ClienteControl?acao=excluir&id=${cliente.id}">excluir</a>
33 </td>
34 </tr>
35 </c:forEach>
36 </table>
37

38

39 </body>
40 </html>

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

17.6. Exercícios
1. O é o JSP?

2. Quais são os elementos de um JSP? Para que serve cada um deles?

3. Para que servem as diretivas ?

4. O que é a Expressão de Linguagem?

5. Explique o MVC.

6. No exemplo da Agenda WEB crie a funcionalidade alterar contatos.

190 http://solutioin.com
Francisco Calaça, Otávio Calaça
I N T R O D U Ç Ã O A O J AVA S E RV E R F A C E S
18
JavaServer Faces é um poderoso framework para desenvolvimento Java EE. Seus princípios
se baseiam no processamento de eventos gerados pelo usuário na página web como: um
clique no botão, alteração do conteúdo de um campo de texto.
O JSF usa o padrão MVC como base de funcionamento. Para ser processada uma página
JSF ela deve passar por um controlador representado pelo Servlet FacesServlet.
A execução de uma chamada JSF é dada pela seguinte seqüência: o FacesServlet recebe a
chamada, cria o FacesContext, logo é atribuído o controle ao ciclo de vida (LifeCycle) que
processa o contexto em 6 fases: reconstituição da view, aplicação dos valores da requisição,
validação dos dados, atualização do modelo de dados, chamada ao aplicativo e geração da
resposta.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

18.1. Fazendo JavaServer Faces funcionar


Para criar o primeiro projeto JavaServer Faces é necessário criar um projeto do tipo Dynamic
Web Project. Na tela onde você coloca o nome do projeto, configure o framework JavaServer
Faces v2.0 Project conforme ilustrado na Figura 18.1.
Clique em next. . . next. . . até encontrar a tela apresentada na Figura 18.3. Nesta tela, es-
colha: Disable Library Configuration conforme apresentado na figura.
Por último copie os arquivos .jar, disponibilizados na pasta Material para o diretório lib
do projeto, conforme ilustrado na Figura 18.3.

18.2. Managed bean


O Managed Bean é uma classe onde são colocados os códigos Java que são executados à
partir dos componentes da tela. Nele é possível escrever código Java para atenter a eventos
da tela, recebe dados, e executa tarefas. Trata-se e um classe que deve ter um construtor
default, getters e setters. Um Managed Bean não necessita herdar de nenhuma classe.
Um exemplo de Managed Bean pode ser visto na listagem 18.1.
O Managed Bean deve ser declarado no arquivo faces-config.xml da seguinte forma:

191
Versão 1.1 introdução ao javaserver faces

Figura 18.1: Escolha JavaServer Faces v2.0 Project

192 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

Figura 18.2: Escolha Disable Library Configuration

http://solutioin.com 193
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

Figura 18.3: Copie estes jar’s para o diretório lib

<managed-bean>
<managed-bean-name>exemploControl</managed-bean-name>
<managed-bean-class>aulajsf.ExemploControl</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Listagem 18.1: Exemplo do primeiro ManagedBean


1 package aulajsf;
2

3 import javax.faces.event.ActionEvent;
4

5 public class ExemploControl {


6

7 private String entrada;


8

9 private String saida;


10

11 public void executar(ActionEvent evt){


12 saida = String.format(" * %s - %s * ", entrada, entrada.toUpperCase());
13 }
14

15 public String getEntrada() {


16 return entrada;
17 }
18

194 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

19 public void setEntrada(String entrada) {


20 this.entrada = entrada;
21 }
22

23 public String getSaida() {


24 return saida;
25 }
26

27 public void setSaida(String saida) {


28 this.saida = saida;
29 }
30

31 }

18.3. Tags básicas


O JavaServer Faces possui dois conjuntos de tags:
• tags para renderização de componentes HTML
• tags Core

18.3.1 Tags JSF para renderização de HTML


As tags JSF HTML básicas podem ser vistas na tabela 18.1. Observe que elas estão rela-
cionadas com a taglib declarada com:
"http://java.sun.com/jsf/html"

As tags JSF HTML são utilizadas para construir componentes html na página como
tabelas, campos de entrada, etc. Existem projetos JSF como o Primefaces, Richfaces, Icefaces,
Myfaces que possuem mais componentes como calendário, tabela ordenável, menus, etc.

18.3.2 Tags Core do JSF


As tags core do JSF permitem passar informações de configurações para os componentes,
validações, conversões e metadados.
Algumas estão listadas na tabela 18.2. Estão na biblioteca de tags declarada :
"http://java.sun.com/jsf/core"

18.3.3 Exemplo de uso das Tags


Um exemplo de utilização das tags JSF pode ser visto na listagem 18.2. Observe que todo
o conteúdo JSF foi colocado dentro das tags:

http://solutioin.com 195
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

<h:head> HTML head


<h:body> HTML body
<h:form> HTML form
<h:inputText> Campo de entrada de texto (uma linha)
<h:inputTextarea> Campo de entrada de texto (multilinhas)
<h:inputSecret> Campo de entrada de senhas
<h:inputHidden> Campo escondido
<h:outputLabel> Rótulo para outros componentes
<h:outputLink> link HTML
<h:outputFormat> Igual a outputText, mas formata as mensagens
<h:outputText> Saída de texto
<h:commandButton> Botão: submit, reset ou pushbutton
<h:commandLink> Link que atua como um botão
<h:message> Apresenta a mensagem mais recente do componente
<h:messages> Apresenta todas as mensagens
<h:graphicImage> Apresenta uma imagem
<h:selectOneListbox> Listbox com seleção de um elemento
<h:selectOneMenu> ComboBox
<h:selectOneRadio> Conjunto de botões radio
<h:selectBooleanCheckbox> Checkbox
<h:selectManyCheckbox> Conjunto de checkboxes
<h:selectManyListbox> Listbox com seleção de vários elementos
<h:selectManyMenu> Menu multiselecionavel
<h:panelGrid> tabela HTML
<h:panelGroup> Agrupa dois ou mais componentes
<h:dataTable> Uma tabela utilizada para grid de dados
<h:column> Coluna em um dataTable

Tabela 18.1: Tags JSF para renderização de componentes HTML

<f:view> . . . </f:view>

A tag:

<h:inputText />

é utilizada para entrada de texto.


A tag:

<h:commandButton />

cria um botão que executa ações no Managed Bean.

196 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

<f:view> Cria uma visão


<f:facet> Possibilita configurar parâmetros de componentes
<f:convertDateTime> converte datas e horas

Tabela 18.2: Tags Core do JSF

Listagem 18.2: Exemplo da primerita tela JSF


1 <html xmlns="http://www.w3.org /1999/ xhtml"
2 xmlns:h="http :// java.sun.com/jsf/html"
3 xmlns:f="http ://java.sun.com/jsf/core">
4

5 <h:head>
6

7 </h:head>
8

9 <h:body>
10 <h:form>
11 <h:inputText value="#{ exemploControl.entrada}" />
12 <h:commandButton ajax="false"
13 actionListener="#{ exemploControl.executar}" value="Executar" />
14 <h:outputText value="#{ exemploControl.saida}" />
15 </h:form>
16 </h:body>
17 </html>

Dica:
Para acessar a tela da listagem 18.2 no browser, digite a url:
http://localhost:8080/aulajsf/faces/exemplo.xhtml
Após iniciar o servidor.

18.4. Expressões de Ligação - EL


Na listagem 18.2 forão utilizadas as expressões de ligações:

#{ . . . }

para ligar os componentes da página com o managed bean. Por exemplo, a expressão

#{exemploControl.entrada}

liga o campo de entrada de texto com o atributo nome da classe ExemploControl (Man-
agedBean). A expressão

#{exemploControl.executar}

http://solutioin.com 197
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

liga o método executar com o botão.


Não confunda as expressões de ligação do JSF com as expressões de linguagem vistas no
Capítulo 17. As expressões de ligação:

#{ . . . }

São capazes de setar e buscar os valores do bean.


Enquanto que as expressões de linguagem:

${ . . . }

São apenas capazes de buscar os valores do bean.

18.4.1 Ligações com atributos


Ao utilizar EL com atributos é necessário liga-las através do atributo value do componente
a ser ligado. Na listagem 18.2 os atributos: entrada e saida da classe ExemploControl foram
ligados com o atributo value dos componentes.
É obrigatória a existência do método get para o atributo a ser ligado. A necessidade do
método set é apenas para os componentes que alteram valores como os campos de entrada.

18.4.2 Ligações com métodos


Ao utilizar EL com métodos é necessário liga-las através dos atributos listados na tabela
18.3:

action para acões


actionListener para eventos de ação (clique do mouse no botão)
valueChangeListener para eventos de mudança de valor

Tabela 18.3: Tabela de tipos de ligações com métodos

Observe que existem dois tipos de ligações:

• com ações

• com listeners de eventos

As ligações com ações são utilizadas com as navegações entre páginas (assunto discutido
logo após). A assinatura do método de ação deve ser:

public String nomeMetodo()

Observe que este deve retornar uma String que será utilizada para a navegação.

As ligações com eventos são utilizadas com eventos de cliques e mudança de valores. As
assinaturas dos métodos devem ser:

198 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

public void nomeMetodo(ActionEvent evento)

para listeners de eventos de ação e

public void nomeMetodo(ValueChangeEvent evento)

para listeners de eventos de mudança de valor.

18.5. Configurar o Primefaces


Para o Primefaces funcionar corretamente, adicione o código da Listagem 18.3 no arquivo
web.xml.

Listagem 18.3: Configuração do Primefaces


1 <context-param>
2 <param-name>primefaces.THEME</param-name>
3 <param-value>blitzer</param-value>
4 </context-param>
5

6 <context-param>
7 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
8 <param-value>.xhtml</param-value>
9 </context-param>
10 <context-param>
11 <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
12 <param-value>*.xhtml</param-value>
13 </context-param>
14 <filter>
15 <filter-name>PrimeFaces FileUpload Filter</filter-name>
16 <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
17 </filter>
18 <filter-mapping>
19 <filter-name>PrimeFaces FileUpload Filter</filter-name>
20 <servlet-name>Faces Servlet</servlet-name>
21 </filter-mapping>
22

23 <servlet>
24 <servlet-name>Resource Servlet</servlet-name>
25 <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
26 </servlet>
27 <servlet-mapping>
28 <servlet-name>Resource Servlet</servlet-name>
29 <url-pattern>/primefaces_resource/*</url-pattern>
30 </servlet-mapping>

http://solutioin.com 199
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

18.6. Cadastro de Clientes


Nesta seção implementaremos a tela para cadastrar clientes. Serão utilizadas as classes
implementadas no Capítulo 13. Portanto, é necessário configurar o projeto aulajsf para se
referenciar ao projeto criado naquele capítulo.
A Listagem 18.4 apresenta o ManagedBean, que neste caso age como Controlador, do
cadastro de clientes. Após a implementação desta classe é necessário adicionar a seguinte
configuração no arquivo faces-config.xml:

<managed-bean>
<managed-bean-name>clienteControl</managed-bean-name>
<managed-bean-class>aulajsf.ClienteControl</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Esta configuração fará o ManagedBean ClienteControl acessível à partir do arquivo JSF.


A Listagem 18.5 apresenta o código para criação da tela para manter clientes.

Listagem 18.4: Controlador do cadastro de Clientes


1 package aulajsf;
2

3 import java.util.ArrayList;
4 import java.util.List;
5

6 import javax.faces.component.UIParameter;
7 import javax.faces.event.ActionEvent;
8 import javax.faces.model.SelectItem;
9

10 import org.primefaces.event.RowEditEvent;
11

12 import capitulo13.Cliente;
13 import capitulo13.ClienteDao;
14

15 public class ClienteControl {


16

17 private Cliente cliente = new Cliente();


18

19 private ClienteDao clienteDao = new ClienteDao();


20

21 private List<Cliente> clientes = new ArrayList<Cliente>();


22

23 public void confirmar(ActionEvent evt){


24 if(cliente.getId() == 0){
25 clienteDao.incluir(cliente);
26 }else{
27 clienteDao.alterar(cliente);
28 }
29 cliente = new Cliente();
30 listar(evt);
31 }

200 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

32

33 public void gravar(RowEditEvent event){


34 Cliente c = (Cliente) event.getObject();
35 clienteDao.alterar(c);
36 }
37

38 public List<SelectItem> getUfs(){


39 List<SelectItem> result = new ArrayList<SelectItem>();
40 for(EnumUf uf : EnumUf.values()){
41 result.add(new SelectItem(uf.toString(), uf.getDescricao()));
42 }
43 return result;
44 }
45

46 public void excluirCliente(ActionEvent evt){


47 UIParameter param = (UIParameter) evt.getComponent().findComponent("cliExcluir");
48 Cliente c = (Cliente) param.getValue();
49 clienteDao.excluir(c.getId());
50 listar(evt);
51 }
52

53 public void listar(ActionEvent evt){


54 clientes = clienteDao.listar();
55 }
56

57 public Cliente getCliente() {


58 return cliente;
59 }
60

61 public void setCliente(Cliente cliente) {


62 this.cliente = cliente;
63 }
64

65 public List<Cliente> getClientes() {


66 return clientes;
67 }
68

69

70

71 }

Listagem 18.5: Arquivo cliente.xhtml


1 <html xmlns="http://www.w3.org /1999/ xhtml"
2 xmlns:h="http :// java.sun.com/jsf/html"
3 xmlns:f="http ://java.sun.com/jsf/core"
4 xmlns:p="http :// primefaces.org/ui">
5

6 <h:head>
7

8 </h:head>
9

10 <h:body>

http://solutioin.com 201
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

11 <h:form>
12 <p:panel header="Manter Clientes">
13 <h:panelGrid columns="2">
14 <h:outputText value="Nome:" />
15 <p:inputText value="#{ clienteControl.cliente.nome}"></p:inputText>
16 <h:outputText value="CPF/CNPJ:" />
17 <p:inputText value="#{ clienteControl.cliente.cpfcnpj}"></p:inputText>
18 <h:outputText value="Endereço:" />
19 <p:inputText value="#{ clienteControl.cliente.endereco}"></p:inputText>
20 <h:outputText value=" M u n i c à p i o :" />
21 <p:inputText value="#{ clienteControl.cliente.municipio}"></p:inputText>
22 <h:outputText value="UF:" />
23 <p:inputText value="#{ clienteControl.cliente.uf}"></p:inputText>
24 <p:commandButton ajax="false"
25 actionListener="#{ clienteControl.confirmar}" value="Confirmar"></p:commandButton>
26 <p:commandButton ajax="false"
27 actionListener="#{ clienteControl.listar}" value="Listar"></p:commandButton>
28 </h:panelGrid>
29

30 <p:dataTable value="#{ clienteControl.clientes}" var="cli"


31 editable="true">
32 <f:facet name="header">
33 <h:outputText value="Clientes" />
34 </f:facet>
35 <p:ajax event="rowEdit" listener="#{ clienteControl.gravar}"></p:ajax>
36

37 <p:column headerText="Nome" sortBy="#{cli.nome}"


38 filterBy="#{cli.nome}">
39 <p:cellEditor>
40 <f:facet name="output">
41 <h:outputText value="#{cli.nome}" />
42 </f:facet>
43 <f:facet name="input">
44 <p:inputText value="#{cli.nome}" />
45 </f:facet>
46 </p:cellEditor>
47 </p:column>
48 <p:column headerText="Cpf/Cnpj" sortBy="#{cli.cpfcnpj}">
49 <h:outputText value="#{cli.cpfcnpj}" />
50 </p:column>
51 <p:column>
52 <p:tooltip for="editar" hideEffect="explode"
53 value="Clique aqui para editar #{cli.nome}" />
54 <p:rowEditor id="editar" />
55 </p:column>
56

57 <p:column headerText="UF" sortBy="#{cli.uf}" filterBy="#{cli.uf}">


58 <p:cellEditor>
59 <f:facet name="output">
60 <h:outputText value="#{cli.uf}" />
61 </f:facet>
62 <f:facet name="input">

202 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

63 <p:selectOneMenu value="#{cli.uf}">
64 <f:selectItem itemLabel="Selecione" />
65 <f:selectItems value="#{ clienteControl.ufs}"></f:selectItems>
66 </p:selectOneMenu>
67 </f:facet>
68 </p:cellEditor>
69 </p:column>
70

71 <p:column>
72 <p:commandButton actionListener="#{ clienteControl.excluirCliente}"
73 icon="ui-icon -trash">
74 <f:param id="cliExcluir" value="#{cli}"></f:param>
75 </p:commandButton>
76 </p:column>
77 </p:dataTable>
78 </p:panel>
79 </h:form>
80

81 </h:body>
82 </html>

18.7. Cadastro de Produtos (com JPA)


Listagem 18.6: Classe Produto
1 package aulajsf;
2

3 import javax.persistence.Entity;
4 import javax.persistence.GeneratedValue;
5 import javax.persistence.Id;
6

7 @Entity
8 public class Produto {
9

10 @Id
11 @GeneratedValue
12 private int id;
13

14 private String descricao;


15

16 private double valor;


17

18 private int quantidade;


19

20 public int getId() {


21 return id;
22 }
23

24 public void setId(int id) {


25 this.id = id;

http://solutioin.com 203
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

26 }
27

28 public String getDescricao() {


29 return descricao;
30 }
31

32 public void setDescricao(String descricao) {


33 this.descricao = descricao;
34 }
35

36 public double getValor() {


37 return valor;
38 }
39

40 public void setValor(double valor) {


41 this.valor = valor;
42 }
43

44 public int getQuantidade() {


45 return quantidade;
46 }
47

48 public void setQuantidade(int quantidade) {


49 this.quantidade = quantidade;
50 }
51

52 }

Listagem 18.7: Classe ProdutoDao


1 package aulajsf;
2

3 import java.util.List;
4

5 import javax.persistence.EntityManager;
6 import javax.persistence.EntityManagerFactory;
7 import javax.persistence.Persistence;
8 import javax.persistence.Query;
9

10 public class ProdutoDao {


11

12 private static EntityManagerFactory emf =


13 Persistence.createEntityManagerFactory("aulajpa");
14

15 private EntityManager em = emf.createEntityManager();


16

17 public void incluir(Produto p){


18 em.getTransaction().begin();
19 em.persist(p);
20 em.getTransaction().commit();
21 }
22

23 public void alterar(Produto p){

204 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

24 em.getTransaction().begin();
25 em.merge(p);
26 em.getTransaction().commit();
27 }
28

29 public Produto consultar(int id){


30 return em.find(Produto.class, id);
31 }
32

33 public void excluir(int id){


34 em.getTransaction().begin();
35 Produto p = consultar(id);
36 em.remove(p);
37 em.getTransaction().commit();
38 }
39

40 public List<Produto> listar(){


41 Query query = em.createQuery("select p from Produto p");
42 List<Produto> prods = query.getResultList();
43 return prods;
44 }
45

46 public List<Produto> listar(String descricao){


47 Query query = em.createQuery("select p from Produto p where upper(p.descricao)
like upper(: descricao)" );
48 query.setParameter("descricao", "%"+descricao+"%");
49 List<Produto> prods = query.getResultList();
50 return prods;
51 }
52

53 }

Listagem 18.8: Classe ProdutoControl


1 package aulajsf;
2

3 import java.util.ArrayList;
4 import java.util.List;
5

6 import javax.faces.event.ActionEvent;
7

8 import org.primefaces.event.RowEditEvent;
9

10 public class ProdutoControl {


11

12 private Produto produto = new Produto();


13

14 private List<Produto> produtos = new ArrayList<Produto>();


15

16 private ProdutoDao produtoDao = new ProdutoDao();


17

18 public void confirmar(ActionEvent evt){


19 produtoDao.alterar(produto);

http://solutioin.com 205
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

20 listar(evt);
21 produto = new Produto();
22 }
23

24 public void listar(ActionEvent evt){


25 produtos = produtoDao.listar();
26 }
27

28 public void gravar(RowEditEvent e){


29 Produto p = (Produto) e.getObject();
30 produtoDao.alterar(p);
31

32 }
33

34 public Produto getProduto() {


35 return produto;
36 }
37

38 public void setProduto(Produto produto) {


39 this.produto = produto;
40 }
41

42 public List<Produto> getProdutos() {


43 return produtos;
44 }
45

46 }

Listagem 18.9: Tela produto.xhtml


1 <html xmlns="http ://www.w3.org /1999/ xhtml"
2 xmlns:h="http ://java.sun.com/jsf/html"
3 xmlns:f="http ://java.sun.com/jsf/core"
4 xmlns:p="http :// primefaces.org/ui">
5

6 <h:head>
7

8 </h:head>
9

10 <h:body>
11 <h:form>
12 <p:panel header="Manter Produtos">
13 <h:panelGrid columns="2">
14 <h:outputText value="Descrição:" />
15 <p:inputText value="#{ produtoControl.produto.descricao}"></p:inputText>
16 <h:outputText value="Quantidade:" />
17 <p:inputText value="#{ produtoControl.produto.quantidade}"></p:inputText>
18 <h:outputText value="Valor:" />
19 <p:inputText value="#{ produtoControl.produto.valor}"></p:inputText>
20

21 <p:commandButton ajax="false"
22 actionListener="#{ produtoControl.confirmar}" value="Confirmar"></p:commandButton>
23

206 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

24 <p:commandButton ajax="false"
25 actionListener="#{ produtoControl.listar}" value="Listar"></p:commandButton>
26

27 </h:panelGrid>
28

29 <p:dataTable value="#{ produtoControl.produtos}" var="prod"


30 editable="true">
31

32 <f:facet name="header">
33 <h:outputText value="Produtos" />
34 </f:facet>
35 <p:ajax event="rowEdit" listener="#{ produtoControl.gravar}"></p:ajax>
36

37 <p:column headerText="Nome" sortBy="#{prod.descricao}"


38 filterBy="#{prod.descricao}">
39 <p:cellEditor>
40 <f:facet name="output">
41 <h:outputText value="#{prod.descricao}" />
42 </f:facet>
43 <f:facet name="input">
44 <p:inputText value="#{prod.descricao}" />
45 </f:facet>
46 </p:cellEditor>
47 </p:column>
48

49 <p:column>
50 <p:commandButton ajax="false" value="Selecionar">
51 <f:setPropertyActionListener target="#{ produtoControl.produto}"
52 value="#{prod}"></f:setPropertyActionListener>
53 </p:commandButton>
54 </p:column>
55

56 <p:column>
57 <p:rowEditor></p:rowEditor>
58 </p:column>
59

60 </p:dataTable>
61 </p:panel>
62 </h:form>
63

64 </h:body>
65 </html>

Finalmente, os arquivos de configuração do projeto estão nas Listagens 18.10 e 18.11.

Listagem 18.10: web.xml


1 <?xml version="1.0" encoding="UTF -8"?>
2 <web-app xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"
3 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/
javaee/web -app _ 2 _ 5.xsd"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/
javaee/web -app _ 3 _ 0.xsd"

http://solutioin.com 207
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

5 version="3.0">
6 <display-name>capitulo18</display-name>
7

8 <context-param>
9 <param-name>primefaces.THEME</param-name>
10 <param-value>blitzer</param-value>
11 </context-param>
12

13 <context-param>
14 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
15 <param-value>.xhtml</param-value>
16 </context-param>
17 <context-param>
18 <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
19 <param-value>*.xhtml</param-value>
20 </context-param>
21 <filter>
22 <filter-name>PrimeFaces FileUpload Filter</filter-name>
23 <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
24 </filter>
25 <filter-mapping>
26 <filter-name>PrimeFaces FileUpload Filter</filter-name>
27 <servlet-name>Faces Servlet</servlet-name>
28 </filter-mapping>
29

30 <servlet>
31 <servlet-name>Resource Servlet</servlet-name>
32 <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
33 </servlet>
34 <servlet-mapping>
35 <servlet-name>Resource Servlet</servlet-name>
36 <url-pattern>/primefaces_resource/*</url-pattern>
37 </servlet-mapping>
38

39 <servlet>
40 <servlet-name>Faces Servlet</servlet-name>
41 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
42 <load-on-startup>1</load-on-startup>
43 </servlet>
44 <servlet-mapping>
45 <servlet-name>Faces Servlet</servlet-name>
46 <url-pattern>/faces/*</url-pattern>
47 </servlet-mapping>
48 </web-app>

Listagem 18.11: faces-config.xml


1 <?xml version="1.0" encoding="UTF -8"?>
2 <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xi="http://www.w3.org /2001/ XInclude"
4 xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance" xsi:schemaLocation="http://java
.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web -facesconfig _ 2 _ 0.xsd"
>

208 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

5 <managed-bean>
6 <managed-bean-name>exemploControl</managed-bean-name>
7 <managed-bean-class>aulajsf.ExemploControl</managed-bean-class>
8 <managed-bean-scope>session</managed-bean-scope>
9 </managed-bean>
10 <managed-bean>
11 <managed-bean-name>clienteControl</managed-bean-name>
12 <managed-bean-class>aulajsf.ClienteControl</managed-bean-class>
13 <managed-bean-scope>session</managed-bean-scope>
14 </managed-bean>
15 <managed-bean>
16 <managed-bean-name>produtoControl</managed-bean-name>
17 <managed-bean-class>aulajsf.ProdutoControl</managed-bean-class>
18 <managed-bean-scope>session</managed-bean-scope>
19 </managed-bean>
20 <managed-bean>
21 <managed-bean-name>produtoListControl</managed-bean-name>
22 <managed-bean-class>aulajsf.ProdutoListControl</managed-bean-class>
23 <managed-bean-scope>session</managed-bean-scope>
24 </managed-bean>
25 </faces-config>

Na Listagem 18.12 é apresentado o código do arquivo persistence.xml, necessário para o


funcionamento da JPA.

Listagem 18.12: persistence.xml


1 <?xml version="1.0" encoding="UTF -8"?>
2 <persistence version="1.0"
3 xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org /2001/
XMLSchema -instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns
/persistence/persistence _ 1 _ 0.xsd" >
5 <persistence-unit name="aulajpa">
6 <properties>
7 <property name="hibernate.hbm2ddl.auto" value="update" />
8 <property name="hibernate.show _ sql" value="true" />
9 <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"
/>
10 <property name="hibernate.connection.url" value="jdbc:postgresql: // localhost/
treinamento" />
11 <property name="hibernate.connection.driver _ class" value="org.postgresql.Driver" />
12 <property name="hibernate.connection.username" value="postgres" />
13 <property name="hibernate.connection.password" value="123456" />
14 </properties>
15 </persistence-unit>
16 </persistence>

Dica:
Não esqueça de adicionar as dependências da JPA nas libs do projeto
de JSF.

http://solutioin.com 209
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

18.8. Conversores
Inicialmente vamos verificar a necessidade de utilizar conversores JSF. Imagine uma tela de
uma aplicação web onde o usuário entra com uma informação no formato String. Suponha
que esta informação deva ser convertida em um valor numérico como uma idade ou um
salário. Esta conversão deve ser feita de forma automática para que, no Managed Bean a
variável já possa ser declarada como inteira ou ponto flutuante. Um outro exemplo pode
acontecer com datas. Nestes casos utilizamos conversores.
Por exemplo, para converter números, utize:

<h:inputText id="salary" value="#{PessoaControl.salario}">


<f:convertNumber pattern="###,##0.00"/>
</h:inputText>

Para converter datas, utilize:

<h:inputText id="date" value="#{PessoaControl.dataNascimento}">


<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:inputText>

18.8.1 Conversores personalizados


Em muitas situações é necessário converter objetos de classes do modelo da aplicação
para serem utilizados em telas JSF. Por exemplo: Uma classe Produto deve ser convertida
para poder ser utilizada em algum componente JSF. Neste caso, utiliza-se os conversores
personalizados.

Listagem 18.13: Classe ProdutoControl


1 package aulajsf;
2

3 import java.util.ArrayList;
4 import java.util.List;
5

6 import javax.faces.event.ActionEvent;
7

9 public class ProdutoListControl {


10

11 private ProdutoDao produtoDao = new ProdutoDao();


12

13 private List<Produto> produtos = new ArrayList<Produto>();


14

15 private Produto produto;


16

17 public List<Produto> listarPorDescricao(String descricao){


18 return produtoDao.listar(descricao);
19 }
20

210 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

21 public void adicionar(ActionEvent evt){


22 produtos.add(produto);
23 }
24

25 public List<Produto> getProdutos() {


26 return produtos;
27 }
28

29 public Produto getProduto() {


30 return produto;
31 }
32

33 public void setProduto(Produto produto) {


34 this.produto = produto;
35 }
36

37 }

Listagem 18.14: Classe ProdutoControl


1 package aulajsf;
2

3 import java.util.HashMap;
4 import java.util.Map;
5

6 import javax.faces.component.UIComponent;
7 import javax.faces.context.FacesContext;
8 import javax.faces.convert.Converter;
9 import javax.faces.convert.FacesConverter;
10

11

12 @FacesConverter("produtoConverter")
13 public class ProdutoConverter implements Converter{
14

15 private static Map<String, Produto> mapa = new HashMap<String, Produto>();


16

17 @Override
18 public Object getAsObject(FacesContext ctx, UIComponent comp, String value) {
19 return mapa.get(value);
20 }
21

22 @Override
23 public String getAsString(FacesContext ctx, UIComponent comp, Object value) {
24 if(value instanceof Produto){
25 Produto p = (Produto) value;
26 mapa.put(String.valueOf(p.getId()), p);
27 return String.valueOf(p.getId());
28 }else{
29 return "";
30 }
31 }
32

33 }

http://solutioin.com 211
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

Listagem 18.15: Tela produto.xhtml


1 <html xmlns="http ://www.w3.org /1999/ xhtml"
2 xmlns:h="http ://java.sun.com/jsf/html"
3 xmlns:f="http ://java.sun.com/jsf/core"
4 xmlns:p="http :// primefaces.org/ui">
5

6 <h:head>
7

8 </h:head>
9

10 <h:body>
11 <h:form enctype="multipart/form -data">
12 <p:panel header="Manter Produtos">
13 <p:autoComplete value="#{ produtoListControl.produto}" id="produto" completeMethod="
#{ produtoListControl.listarPorDescricao}"
14 var="p" itemLabel="#{p.descricao}" itemValue="#{p}" converter
="produtoConverter" forceSelection="true"/>
15 <p:commandButton value="Adicionar" actionListener="#{ produtoListControl.adicionar}"
update="produtos"></p:commandButton>
16

17 <p:dataTable value="#{ produtoListControl.produtos}" var="prod" id="produtos">


18 <f:facet name="header">
19 <h:outputText value="Produtos" />
20 </f:facet>
21

22 <p:column>
23 <h:outputText value="#{prod.descricao}"></h:outputText>
24 </p:column>
25

26 <p:column>
27 <h:outputText value="#{prod.valor}"></h:outputText>
28 </p:column>
29

30 </p:dataTable>
31 </p:panel>
32 </h:form>
33

34 </h:body>
35 </html>

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

212 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 introdução ao javaserver faces

18.9. Exercícios
1. Descreva o framework JavaServer Faces

2. Quais os procedimentos para adicionar o JavaServer Faces em um aplicativo

3. O que é um Managed Bean

4. Quais são as tags básicas do JSF

5. O que é uma expressão de ligação?

http://solutioin.com 213
Francisco Calaça, Otávio Calaça
PA D R Õ E S D E P R O J E T O
19
Um Padrão de Projeto de Software, também muito conhecido pelo seu termo original em
inglês, Design Pattern, descreve uma solução geral reutilizável para um problema recor-
rente no desenvolvimento de sistemas de software orientados a objetos. Não é um código
final, é uma descrição ou modelo de como resolver o problema do qual trata, que pode
ser usada em muitas situações diferentes. Os Padrões de Projeto normalmente definem as
relações e interações entre as classes ou objetos, sem especificar os detalhes das classes ou
objetos envolvidos, ou seja, estão num nível de generalidade mais alto.
Um padrão de projeto define :

• seu nome,

• o problema,

• a solução,

• quando aplicar esta solução e

• suas consequências.

Os padrões de projeto visam facilitar a reutilização de soluções de projeto e estabelecem


um vocabulário comum para ser utilizado no projeto, facilitando comunicação, documen-
tação e aprendizado dos sistemas de software.

Alguns dos códigos aqui descritos e mais informações sobre este


assunto pode ser obtido em: http://solutioin.com/java
Acesse e verifique!

19.1. Padrões GoF


Gof vem do inglês
Os padrões "GoF" são organizados em 3 grupos:

• Padrões de criação : relacionados à criação de objetos

• Padrões estruturais : tratam das associações entre classes e objetos.

• Padrões comportamentais : tratam das interações e divisões de responsabilidades


entre as classes ou objetos.

215
Versão 1.1 padrões de projeto

Padrões de criação:
• Abstract Factory

• Builder

• Factory Method

• Prototype

• Singleton
Padrões estruturais
• Adapter

• Bridge

• Composite

• Decorator

• Facade

• Flyweight

• Proxy
Padrões comportamentais
• Chain of Responsibility

• Command

• Interpreter

• Iterator

• Mediator

• Memento

• Observer

• State

• Strategy

• Template Method

• Visitor

19.2. Abstract Factory


Abstract Factory é um padrão de projeto de software (também conhecido como design
pattern em inglês). Este padrão permite a criação de famílias de objetos relacionados ou
dependentes, através de uma única interface e sem que a classe concreta seja especificada.

216 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 padrões de projeto

19.2.1 Utilização
O padrão Abstract Factory pode ser utilizado na implementação de um toolkit que disponi-
bilize controles que funcionem em diferentes interfaces gráficas, tal como Motif, GTK+
(GNOME) ou Qt (KDE). Estas GUIs possuem diferentes padrões de controles visuais e,
para facilitar a construção de aplicativos que interajam facilmente com diferentes interfaces
gráficas, é interessante que se defina interfaces comuns para acesso aos controles, inde-
pendentemente da GUI utilizada. Este problema pode ser resolvido através de uma classe
abstrata que declara uma interface genérica para criação dos controles visuais e de uma
classe abstrata para criação de cada tipo de controle. O comportamento específico, de cada
um dos padrões tecnológicos contemplados, é implementado através de uma classe conc-
reta. O aplicativo, ou "cliente", interage com o toolkit através das classes abstratas sem ter
conhecimento da implementação das classes concretas. Um exemplo bem simplista seria
um projeto com interface para Mobile e para Desktop, uma boa opção para reaproveitar os
mesmos controles de interface seria criar pacotes com classes abstratas e os pacotes com
as classes concretas implementando apenas as diferenças. Esse padrão também se aplica
na padronização de ambientes, por exemplo, tamanhos de botões, fontes, cores de fundo,
largura de bordas. Com isso e havendo uma política que exija que os desenvolvedores
usem essas classes em vez das nativas da linguagem, ajudará a padronizar a aparência e
comportamento das aplicações.

19.3. Factory Method


Factory Method, na ciência da computação, é um padrão de projeto de software (design
pattern, em inglês) que define uma classe para criação de um objeto, mas permite que as
subclasses escolham qual classes instanciar. O factory method permite delegar a instanci-
ação para as subclasses.

19.3.1 Utilização
Este padrão é muito utilizado em frameworks para definir e manter relacionamentos en-
tre objetos. O framework Spring, dependendo da configuração, pode utilizar um Factory
Method para criar os seus beans. Este padrão pode ser utilizado na construção de um
framework que suporta aplicações que apresentam múltiplos documentos ao usuário. Nor-
malmente este tipo de aplicação manipula um número variável de formatos de documento
e, por isso, este framework deve ser flexível o bastante para suportar qualquer formato.
Uma solução para este problema poderia disponibilizar, no framework, o código para al-
guns dos formatos mais utilizados. Mas, na prática, esta solução seria uma implementação
pouco flexível, e até mesmo incompleta, já que é custoso implementar os mais variados
formatos. O padrão Factory Method propõe uma solução que deixa para o cliente (a imple-
mentação da aplicação) a tarefa de suportar os formatos necessários e para o framework
o papel de definição de uma abstração que oferece uma interface única para criação de
documentos. Este framework seria baseado em duas classes abstratas, que representam

http://solutioin.com 217
Francisco Calaça, Otávio Calaça
Versão 1.1 padrões de projeto

a Aplicação e o Documento. O cliente do framework fornece um par de classes concretas,


uma aplicação e o respectivo documento, para cada um dos formatos de Documento supor-
tados pela Aplicação. Se for necessário apresentar um documento que suporte desenho, por
exemplo, o cliente deve disponibilizar as classes AplicacaoDesenho e DocumentoDesenho
(supondo que o sufixo "Desenho" indique classes que suportam esta funcionalidade).
O objetivo do Factory Method está em diversas classes que implementam a mesma op-
eração, retornarem o mesmo tipo abstrato, mas internamente instanciam diferentes classes
que o implementam. Com o Factory Method o criador do objeto faz uma escolha de qual
classe instanciar para o cliente. Para ser um Factory Method o método precisa retornar uma
interface ou uma classe abstrata e, dependendo das necessidades do cliente, criar um objeto
determinado como retorno. Um exemplo clássico do Factory Method são os iteradores em
Java.

19.3.2 Command
Encapsular uma solicitação como um objeto, desta forma permitindo que clientes parametrizem
diferentes solicitações, enfileirem ou façam o registro (log) de solicitações e suportem oper-
ações que podem ser desfeitas.

19.3.3 Problema
Algumas vezes é necessário emitir solicitações para objetos nada sabendo sobre a operação
que está sendo solicitada ou sobre o receptor da mesma.
Utilizar quando:

• Parametrizar objetos por uma ação a ser executada. Você pode expressar tal parametriza-
ção numa linguagem procedural através de uma função callback, ou seja, uma função
que é registrada em algum lugar para ser chamada em um momento mais adiante.
Os Commands são uma substituição orientada a objetos para callbacks;

• Especificar, enfileirar e executar solicitações em tempos diferentes. Um objeto Com-


mand pode ter um tempo de vida independente da solicitação original. Se o receptor
de uma solicitação pode ser representado de uma maneira independente do espaço
de endereçamento, então você pode transferir um objeto Command para a solicitação
para um processo diferente e lá atender a solicitação;

• Suportar desfazer operações. A operação Execute, de Command, pode armazenar es-


tados para reverter seus efeitos no próprio comando. A interface do Command deve
ter acrescentada uma operação Unexecute, que o reverte.efeitos de uma chamada an-
terior de Execute. Os comandos executados são armazenados em uma lista histórica.
O nível ilimitado de desfazer e refazer operações é obtido percorrendo esta lista para
trás e para frente, chamando operações Unexecute e Execute, respectivamente.

218 http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.1 padrões de projeto

19.3.4 Aplicação
A chave deste padrão è uma classe abstrata Command, a qual declara uma interface para
execução de operações. Na sua forma mais simples, esta interface inclui uma operação
abstrata Execute. As subclasses concretas de Command especificam um par receptor-ação
através do armazenamento do receptor como uma variável de instância e pela implemen-
tação de Execute para invocar a solicitação. O receptor tem o conhecimento necessário para
poder executar a solicitação.

19.4. Data Access Object (DAO)


Este não é um padrão de projeto GoF. Objeto de acesso a dados (ou simplesmente DAO,
acrônimo de Data Access Object), é um padrão para persistência de dados que permite
separar regras de negócio das regras de acesso a banco de dados. Numa aplicação que
utilize a arquitetura MVC, todas as funcionalidades de bancos de dados, tais como obter as
conexões, mapear objetos Java para tipos de dados SQL ou executar comandos SQL, devem
ser feitas por classes de DAO.

19.4.1 Vantagens
A vantagem de usar objetos de acesso a dados é a separação simples e rigorosa entre duas
partes importantes de uma aplicação que não devem e não podem conhecer quase que
nada uma da outra, e que podem evoluir frequentemente e independentemente. Alterar
a lógica de negócio podem esperar apenas a implementação de uma interface, enquanto
que modificações na lógica de persistência não alteram a lógica de negocio, desde que a
interface entre elas não seja modificada.

• Pode ser usada em uma vasta porcentagem de aplicações;

• Esconde todos os detalhes relativos a armazenamento de dados do resto da aplicação;

• Atua como um intermediário entre a aplicação e o banco de dados;

• Mitiga ou resolve problemas de comunicação entre a base de dados e a aplicação,


evitando estados inconsistentes de dados.

No contexto específico da linguagem de programação Java, um objeto de acesso a da-


dos como padrão de projeto de software pode ser implementado de várias maneiras. Pode
variar desde uma simples interface que separa partes de acesso a dados da lógica de negó-
cio de uma aplicação até frameworks e produtos comerciais específicos. Os paradigmas
para programação usando DAOs demandam alguma proficiência. O uso de tecnologias
como Java persistence technologies e JDO garantem a implementação do padrão de projeto
até certo ponto. Tecnologias como Enterprise JavaBeans trazem para a aplicação servidores
montados e que podem ser usados em aplicações que usem um servidor de aplicação JEE.

http://solutioin.com 219
Francisco Calaça, Otávio Calaça
Versão 1.1 padrões de projeto

Produtos comerciais como o TopLink estão disponíveis, baseados em mapeamento objeto-


relacional (ORM). Produtos ORM populares em código aberto incluem Doctrine, Hibernate,
iBATIS e Apache OpenJPA.

19.5. MVC
Model-view-controller (MVC) é um modelo de desenvolvimento de Software, atualmente
considerado uma "arquitetura padrão" utilizada na Engenharia de Software. O modelo
isola a "lógica" (A lógica da aplicação) da interface do usuário (Inserir e exibir dados),
permitindo desenvolver, editar e testar separadamente cada parte.

19.5.1 Componentes
O modelo (model) é usado para definir e gerenciar o domínio da informação e notificar ob-
servadores sobre mudanças nos dados. Ele é uma representação detalhada da informação
que a aplicação opera. A lógica de negócio adiciona valor semântico aos dados, e quando
há mudança de estado o modelo notifica seus observadores. Por exemplo, aluno, professor
e turma fazem parte do domínio de um sistema acadêmico. Operações como calcular a
média final do aluno ou o índice de faltas da turma fazem parte da lógica de domínio. A
forma como o dado é armazenado ou acessado não é de interesse do MVC, assume-se que
é de responsabilidade do modelo.
A visão (view) apresenta o modelo num formato adequado ao utilizador, na saída de da-
dos, e diferentes visões podem existir para um mesmo modelo, para diferentes propósitos.
O controlador (controller) recebe a entrada de dados e inicia a resposta ao utilizador
ao invocar objetos do modelo, e por fim uma visão baseada na entrada. Ele também é
responsável pela validação e filtragem da entrada de dados.
Um caso prático é uma aplicação web em que a visão é um documento HTML (ou
derivado) gerado pela aplicação. O controlador recebe uma entrada GET ou POST após
um estímulo do utilizador e decide como processá-la, invocando objetos do domínio para
tratar a lógica de negócio, e por fim invocando uma visão para apresentar a saída.

19.5.2 Justificativa
Com o aumento da complexidade das aplicações desenvolvidas,sempre visando a progra-
mação orientada a objeto nao devemos esquecer que torna-se relevante a separação entre os
dados e a apresentação das aplicações. Desta forma, alterações feitas no layout não afetam
a manipulação de dados, e estes poderão ser reorganizados sem alterar o layout.
Esse padrão resolve este problema através da separação das tarefas de acesso aos dados
e lógica de negócio, lógica de apresentação e de interação com o utilizador, introduzindo
um componente entre os dois, o controlador.

220 http://solutioin.com
Francisco Calaça, Otávio Calaça
M O N TA G E M D O A M B I E N T E D E
A
TRABALHO

A.1. Obtenção e instalação do JDK


O JDK deve ser obtido do site da Oracle1 . Quando você acessar este site, notará a primeira
grande confusão enfrentada pelos iniciantes. O que baixar JDK ou JRE ? No nosso caso,
devemos baixar o Java SE 7 JDK, ou seja, clique no download do JDK.
Para instalar o JDK basta executar o instalador adequado obtido no site. Note que existem
opções de instalador para linux, windows e solaris para as arquiteturas 32 e 64 bits.
A diferença entre JDK e JRE é que o JDK contém, além da máquina virtual Java, várias fer-
ramentas para o desenvolvimento de um software Java. Já o JRE contém apenas a máquina
virtual.

A.2. O que é a Máquina virtual Java


Todo software Java necessita de uma máquina virtual para executá-lo. É ela quem acessa
o hardware da máquina. Em java, todo o código escrito deve ser compilado. Este arquivo
compilado é chamado de bytecode e é executado pela máquina virtual.
Hoje existem máquinas virtuais JIT que recompilam o bytecode para código nativo (que
pode ser executado diretamente no computador) tornando a execução do software mais
rápida. Este trabalho feito pela JVM é transparente, ou seja, não há a necessidade de se
preocupar como e quando será feito isto.

A.3. Obtenção e instalação do eclipse


O Eclipse pode ser obtido no seu site: http://www.eclipse.org/downloads/. Neste livro
será utilizado o “Eclipse IDE for Java EE Developers”.
Após o término do download, basta descompactar o arquivo. Para iniciar o Eclipse basta
executar o aplicativo eclipse(Linux) ou eclipse.exe(Windows) situado dentro do diretório
eclipse descompactado.

1 http://www.oracle.com/technetwork/java/javase/downloads/index.html

221

Você também pode gostar