Apostila - Solutio In

Propaganda
J AVA
francisco calaça
otávio calaça
Guia para iniciantes
2013 – Versão 1.2-beta
LICENÇA
Esta apostila é disponibilizada sob os termos da licença Creative Commons - AttributionNonCommercial-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 previstas 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 [email protected] 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
• Deuslirio Junior
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
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
22
3.9.1 if . . . else
22
3.9.2 Operador condicional ou ternário
24
3.9.3 switch
25
3.10 Estruturas de Repetição
26
3.10.1 for
26
3.10.2 while
27
3.10.3 do . . . while
28
3.11 Exercícios
28
4 introdução à orientação a objetos
31
4.1 O conceitos Classe e Objeto
31
4.2 Elementos de uma classe
32
10
vii
Versão 1.2-beta
4.2.1 Atributos
32
4.2.2 Métodos
33
4.2.3 Métodos construtores
34
4.2.4 Padrões de nomenclatura
35
4.3 Atributos e métodos static
36
4.3.1 Import static
37
4.4 Tipos Wrapper
38
4.4.1 Auto-boxing e Auto-unboxing
38
4.5 Regras de escopo
39
4.6 Sobrecarga de métodos
40
4.7 Exercícios
41
5 arrays
43
5.1 O que são arrays
43
5.2 Declaração e inicialização de arrays
44
5.3 Método main
46
5.4 Laço for aprimorado
48
5.5 Passagem de parâmetros no Java
48
5.6 Arrays multidimensionais
51
5.7 Lista de parâmetros com comprimento variável
51
5.8 Exercícios
52
6 um pouco mais de orientação a objetos
53
6.1 Coletor de lixo
53
6.2 A palavra-chave this
54
6.3 Variáveis do tipo final
56
6.4 Encapsulamento
56
6.5 Enumerações
59
6.6 Pacotes
59
6.6.1 Como usar tipos dentro de outros pacotes
61
6.7 Herança
62
6.7.1 Um exemplo de Herança
62
6.7.2 Sobrescrita de métodos
64
6.7.3 A palavra-chave super
64
6.8 Alguns Modificadores de acesso
64
6.8.1 private
64
6.8.2 pacote
64
6.8.3 protected
65
6.8.4 public
65
6.9 Classe object
65
6.9.1 método equals()
65
6.9.2 método toString()
66
6.10 Polimorfismo
67
6.10.1 Abstração
67
6.10.2 Exemplo de Polimorfismo
68
6.11 Conversão e casting
71
6.11.1 A palavra-chave instanceof
72
6.12 Métodos e classe do tipo final
72
viii
conteúdo
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
7
8
9
10
11
conteúdo
6.13 Interfaces
73
6.13.1 Interfaces em Java
73
6.14 Exercícios
75
tratamento de exceções
77
7.1 O que são exceções
77
7.2 Como tratar exceções
77
7.2.1 O bloco try
77
7.2.2 O bloco catch
78
7.3 Exceções checadas e exceções não checadas
80
7.4 Como declarar novos tipos de exceções
80
7.5 Como lançar exceções
81
7.6 Hierarquia das exceções
82
7.7 Exercícios
83
fluxo de dados
85
8.1 A classe File
85
8.2 Como escrever em arquivos
85
8.3 Como ler arquivos
86
8.4 Um editor de texto simples
87
8.5 Serialização de objetos
89
8.6 Um trocador de mensagens simples
90
8.7 Exercícios
93
genéricos e coleções
95
9.1 o que são genéricos
95
9.2 Introdução a coleções
97
9.3 Listas
97
9.4 Conjuntos
99
9.5 Mapas
99
9.5.1 Properties 101
9.6 Pilhas 103
9.7 Filas 104
9.8 Ordenação de Listas 104
9.9 Exercícios 106
uml: unified modeling language
109
10.1 Diagrama de Classe 109
10.1.1 Classe 109
10.1.2 Associações de Classe 110
10.2 Diagrama de Caso de Uso 112
10.2.1 Caso de Uso 112
10.2.2 Ator 113
10.2.3 Descrição do Caso de Uso 113
10.3 Demais diagramas
113
threads
115
11.1 Processos e Threads 115
11.1.1 Processos
115
11.1.2 Threads 115
11.2 Criação de Threads 116
http://solutioin.com
Francisco Calaça, Otávio Calaça
ix
Versão 1.2-beta
12
13
14
15
x
11.3 A classe Executors 117
11.4 Métodos sleep e yield 118
11.5 Sincronização
118
11.6 O verificador de primos 121
11.7 Exercícios 123
strings e datas
125
12.1 As classes Date e Calendar
125
12.2 Formatação de Datas 126
12.3 A classe String
127
12.4 A classe StringBuffer 127
12.5 Saída formatada
128
12.5.1 Caracteres de conversão 128
12.6 Exercícios 130
jdbc
133
13.1 Conexão com banco de dados 133
13.2 A linguagem SQL 135
13.2.1 SELECT 135
13.2.2 Cláusula WHERE 135
13.2.3 O Operador LIKE 135
13.2.4 INSERT 136
13.2.5 UPDATE 136
13.2.6 DELETE 136
13.3 Como executar instruções SQL e obter registros
13.3.1 PreparedStatement 138
13.4 Execução em Lote
138
13.5 Tabela de Clientes 140
13.6 Exercícios 143
java persistence api com hibernate
145
14.1 Mapeamento objeto relacional 145
14.2 Configurações iniciais 145
14.3 A criação do primeiro exemplo 146
14.4 O arquivo persistence.xml 148
14.5 O EntityManager 150
14.6 A inclusão de clientes com JPA 151
14.6.1 Persistindo entidades 151
14.6.2 Localizando entidades 152
14.6.3 Removendo entidades 152
14.6.4 Mesclando entidades 152
14.7 Relacionamento entre classes 152
14.8 Formas de obtenção de id’s 155
14.9 JPQL - A linguagem consulta da Jpa 156
14.9.1 Passagem de parâmetros 156
14.10Exercícios 157
aplicativos web
159
15.1 XML 159
15.2 HTML
160
conteúdo
136
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
15.2.1 A estrutura básica de um documento HTML
15.2.2 Outras tags HTML
161
15.3 JavaScript 162
15.4 CSS
163
15.5 Aplicativos Web com Java 165
15.5.1 Instalação do Tomcat 165
15.6 Exercícios 166
16 servlets
167
16.1 Estrutura de uma aplicação web Java 167
16.2 Construindo o primeiro Servlet 167
16.3 Como fazer no eclipse
169
16.4 Atendendo requisições com o método get 170
16.5 Atendendo requisições com o método post 176
16.6 Redirect
177
16.7 Forward 179
16.8 Escopo de objetos web 180
16.8.1 Request
180
16.8.2 Session 181
16.8.3 Application 181
16.9 Como distribuir uma aplicação web 181
16.10Exercícios 182
17 java server pages
183
17.1 Elementos do Jsp 183
17.1.1 Scriptlet 183
17.1.2 Expressões
184
17.1.3 Declarações 185
17.2 Diretivas 185
17.2.1 Diretiva include 185
17.2.2 Diretiva Page
186
17.3 Ações do JSP
188
17.4 Biblioteca de tags JSTL 188
17.4.1 EL - Expressão de Linguagem 189
17.5 MVC - Model View Control 190
17.5.1 O cadastro de clientes 190
17.6 Exercícios 192
18 introdução ao javaserver faces
193
18.1 Fazendo JavaServer Faces funcionar 193
18.2 Managed bean 193
18.3 Tags básicas 197
18.3.1 Tags JSF para renderização de HTML 197
18.3.2 Tags Core do JSF 197
18.3.3 Exemplo de uso das Tags 197
18.4 Expressões de Ligação - EL 199
18.4.1 Ligações com atributos 200
18.4.2 Ligações com métodos 200
18.5 Configurar o Primefaces 201
http://solutioin.com
Francisco Calaça, Otávio Calaça
conteúdo
160
xi
Versão 1.2-beta
18.6 Cadastro de Clientes 202
18.7 Cadastro de Produtos (com JPA) 205
18.8 Conversores
212
18.8.1 Conversores personalizados 212
18.9 Exercícios 215
19 padrões de projeto
217
19.1 Padrões GoF
217
19.2 Abstract Factory 218
19.2.1 Utilização 219
19.3 Factory Method 219
19.3.1 Utilização 219
19.3.2 Command 220
19.3.3 Problema 220
19.3.4 Aplicação 221
19.4 Data Access Object (DAO) 221
19.4.1 Vantagens 221
19.5 MVC 222
19.5.1 Componentes
222
19.5.2 Justificativa 222
a montagem do ambiente de trabalho
223
a.1 Obtenção e instalação do JDK
223
a.2 O que é a Máquina virtual Java 223
a.3 Obtenção e instalação do eclipse 223
b erros comuns enfrentados por iniciantes
b.1 Exceções que costumam serem vistas 225
b.1.1 ClassNotFoundException 225
b.1.2 NoSuchMethodError 225
b.1.3 LazyInitializationException 225
b.1.4 NoClassDefFoundError 225
b.1.5 NullPointerException
225
b.1.6 ClassCastException 225
b.2 Erros comuns do HTTP
225
xii
conteúdo
225
http://solutioin.com
Francisco Calaça, Otávio Calaça
1
INTRODUÇÃO
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 computaçã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 consistia em desenhar linhas na areia com rochas.
Os ábacos ainda são usadas como instrumento de cálculo hoje.
1.1.
Algoritmos
O matemático indiano Brahmagupta foi o primeiro a descrever o sistema de numeração
hindu-arábico, no século VII. Nesta época, aparecem os primeiros relatos de utilização
do número 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 todos 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 permitia 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.2-beta
1.3.
introdução
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 mulheres, 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 criptografia.
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 informaçõ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.2-beta
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
Francisco Calaça, Otávio Calaça
3
2
P R E PA R A Ç Ã O D O A M B I E N T E D E
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 conté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 prosseguimento 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. Exemplo: 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.2-beta
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 programa 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
2
3
4
5
public class PrimeiroPrograma {
public static void main(String[] args) {
System.out.println("Veja como é fácil");
}
}
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
4
5
6
7
public class SegundoPrograma {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Olá , como vai ?");
}
}
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.2-beta
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
4
5
6
7
8
public class TerceiroPrograma {
public static void main(String[] args) {
String texto = JOptionPane.showInputDialog("Digite um texto:");
System.out.println("Texto digitado: " + texto);
}
}
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
Francisco Calaça, Otávio Calaça
7
3
L Ó G I C A D E P R O G R A M A Ç Ã O E M J AVA
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 programa 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ângulo. 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.2-beta
lógica de programação em java
3.2. Para entender os programas criados a partir 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(), fazerAlgo(), 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 Objetos. Exemplo: iPod, GameCube, OpenOffice.org, CamelCase, dataNascimento, enderecoEntregaMercadoria,
ItemPedido.
10
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
3
4
5
6
7
8
/*
* Comentário
* de
* bloco
*/
9
10
11
12
13
14
15
/**
* Exemplo de comentário
* de Javadoc.
*
*/
3.3.
Strings
Strings são cadeias de caracteres. Em java são representadas pela classe String e são expressas 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
Francisco Calaça, Otávio Calaça
11
Versão 1.2-beta
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
public static void main(String[] args) {
System.out.println("Como colocar \"aspas\" na String.");
System.out.println("Exemplo\n\tde\n\t\ttabulação");
System.out.println("c:\\ diretorio \\ arquivo");
}
4
5
6
7
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 excessiva 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.2-beta
Caracter
lógica de programação em java
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
3
4
public class ExemploSaidaFormatada {
5
public static void main(String[] args) {
String nome = JOptionPane.showInputDialog("Nome:");
String resultado = JOptionPane.showInputDialog("Resultado:");
System.out.printf("O aluno %s foi %s\n", nome, resultado);
System.out.printf("\nFormatação numérica :%.2f", 12.356);
}
6
7
8
9
10
11
12
13
}
3.5.
Conceito de Variável
Para resolver problemas em programas de computador é necessário manipular vários dados, 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 conter 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
Francisco Calaça, Otávio Calaça
13
Versão 1.2-beta
3.6.
lógica de programação em java
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 chamados 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:
X
2 http://docs.oracle.com/javase/specs/
14
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
15
Versão 1.2-beta
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 apenas 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 armazenamento 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 problema comum, ao permitirem processamento bilíngue (geralmente usando 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.2-beta
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
public static void main(String[] args) {
int numero = 300;
byte menor = (byte) numero;
System.out.printf("\nNumero:%d \nApós truncamento :%d", numero, menor);
}
3
4
5
6
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 vários 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
Francisco Calaça, Otávio Calaça
17
Versão 1.2-beta
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.2-beta
Operador
lógica de programação em java
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 aritmética. Desta forma são criados mais operadores de atribuição. Estes operadores estão
listados na Tabela 3.7.
Uma dica, para entender melhor 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
Francisco Calaça, Otávio Calaça
19
Versão 1.2-beta
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 variá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, cujos operadores estão ilustrados na Figura 3.9:
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.2-beta
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 EXCLUSIVO só é verdadeiro se os dois operandos forem diferentes.
Operador
Operação
||
OU curto-circuito
&&
E curto-circuito
|
OU lógico
&
E lógico
ˆ
OU exclusivo
!
Não lógico
Tabela 3.9: Tabela de operadores lógicos
A tabela verdade do Operador E pode ser vista na figura 3.11, do Operador OU na figura
3.10 e a tabela do Operador OU EXCLUSIVO na figura 3.12.
Observe na Figura 3.9 que existem dois tipos de operadores para a operação OU: | (OU
simples) e || (OU curto-circuito) e dois tipos de operadores para a operação E: & (simples)
e && (E curto-circuito).
Basicamente o que diferem estes dois tipos de operadores são o seguinte. OU e E curtocircuito (|| 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. Neste caso a resposta já é retornada, daí o
nome curto circuito. Exemplo:
V || ? = V
F && ? = F
Note, no exemplo, que na operação de OU, independente do valor do segundo operando,
a resposta será sempre verdadeira se o primeiro operando também for. Na operação de E, a
resposta será sempre falsa se o primeiro operando também for. Como você pode perceber,
não é necessário analisar o segundo operando para retornar as respostas nestes casos.
Já os operadores OU e E lógico (| e &) são utilizados em operações lógicas bit a bit. Por
exemplo:
410 = 1002
310 = 0112
410 |310 ⇒ 1002 |0112
Desta forma,
410 |310 = 7, pois
1002 |0112 = 1112
http://solutioin.com
Francisco Calaça, Otávio Calaça
21
Versão 1.2-beta
lógica de programação em java
Entrada 1
Entrada 2
Saída
V
V
V
V
F
V
F
V
V
F
F
F
Tabela 3.10: 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.11: 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 estrutura de desvio do fluxo de controle que executa diferentes instruções dependendo se a
seleção (ou condição) é verdadeira ou falsa, em que a expressão é processada e transformada 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 verdadeiro, é 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 é:
Entrada 1
Entrada 2
Saída
V
V
F
V
F
V
F
V
V
F
F
F
Tabela 3.12: Tabela verdade da operação OU EXCLUSIVO
22
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
lógica de programação em java
if(teste){
//executa somente se o teste for verdadeiro
}else{
//executa somente se o teste for falso
}
Figura 3.4: Fluxo de execução do if
Listagem 3.5: Exemplo de uso do if . . . else
1
import javax.swing.JOptionPane;
2
3
4
5
6
7
8
public class ExemploIf {
public static void main(String[] args) {
//Obtenção dos dados do usuário
String notaString = JOptionPane.showInputDialog("Digite a nota:");
//Conversão em int
int nota = Integer.parseInt(notaString);
9
if (nota >= 5) {
JOptionPane.showMessageDialog(null, "Aprovado");
} else {
JOptionPane.showMessageDialog(null, "Reprovado");
}
10
11
12
13
14
}
15
16
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
23
Versão 1.2-beta
lógica de programação em java
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" ));
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
4
5
6
7
8
9
10
11
public class ExemploCondicional {
public static void main(String[] args) {
String notaString = JOptionPane.showInputDialog("Digite a nota:");
int nota = Integer.parseInt(notaString);
String resultado = nota >= 5 ? "aprovado" : "reprovado";
String msg = "O aluno foi " + resultado;
JOptionPane.showMessageDialog(null, msg);
}
}
Listagem 3.7: Outro exemplo de uso do operador condicional.
1
import javax.swing.JOptionPane;
2
3
4
5
6
public class ImprimeMaior {
public static void main(String[] args) {
String primeiroNumero = JOptionPane.showInputDialog("Digite um número:");
String segundoNumero = JOptionPane.showInputDialog("Digite um número:");
7
int n1 = Integer.parseInt(primeiroNumero);
int n2 = Integer.parseInt(segundoNumero);
8
9
10
int maior = n1 > n2 ? n1 : n2;
11
12
JOptionPane.showMessageDialog(null, "O maior numero é: " + maior);
13
}
14
24
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
15
lógica de programação em java
}
3.9.3 switch
Diferente das instruções if e if . . . else, a instrução switch permite um maior número de
possibilidades 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.
Sua sintaxe é:
switch(tipo){
case a:
//instrucao;
case b:
//instrucao;
default:
//instrucao;
}
Na Listagem 3.8 está o código de exemplo da instrução switch.
É 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
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ExemploSwitch {
public static void main(String[] args) {
String numeroString =
JOptionPane.showInputDialog("Digite o número de um mês (1 a 12):");
int num = new Integer(numeroString);
String msg;
switch (num) {
case 1:
msg = "Janeiro";
break;
case 2:
msg = "Fevereiro";
break;
case 3:
msg = "Março";
break;
case 4:
msg = "Abril";
break;
case 5:
msg = "Maio";
break;
http://solutioin.com
Francisco Calaça, Otávio Calaça
25
Versão 1.2-beta
case 6:
msg = "Junho";
break;
case 7:
msg = "Julho";
break;
case 8:
msg = "Agosto";
break;
case 9:
msg = "Setembro";
break;
case 10:
msg = "Outubro";
break;
case 11:
msg = "Novembro";
break;
case 12:
msg = "Dezembro";
break;
default:
msg = "Número incorreto";
}
JOptionPane.showMessageDialog(null, msg);
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
}
50
51
lógica de programação em java
}
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)
}
26
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
lógica de programação em java
É 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
2
3
4
5
6
7
public class ExemploFor {
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.printf("\nlinha: %d", i);
}
}
}
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 expressã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
4
5
public class ExemploWhile {
public static void main(String[] args) {
int status = 0;
6
7
8
int qtd = 0;
double soma = 0;
9
10
11
12
while (status != 1) {
String numStr1 = JOptionPane.showInputDialog("Digite um inteiro");
int n1 = Integer.parseInt(numStr1);
13
http://solutioin.com
Francisco Calaça, Otávio Calaça
27
Versão 1.2-beta
lógica de programação em java
soma += n1;
qtd++;
14
15
16
String msg = "Digite 1 para sair ou qualquer outro número para continuar";
String statusStr = JOptionPane.showInputDialog(msg);
17
18
19
status = Integer.parseInt(statusStr);
20
21
}
22
23
double media = soma / qtd;
JOptionPane.showMessageDialog(null, "Média: " + media);
24
25
26
}
27
28
}
3.10.3
do . . . while
A linguagem Java provê a instrução do . . . while que pode ser vista abaixo:
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 “Voto 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. . .
28
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
lógica de programação em java
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!
http://solutioin.com
Francisco Calaça, Otávio Calaça
29
4
I N T R O D U Ç Ã O À O R I E N TA Ç Ã O A
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 encontradas 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”.
31
Versão 1.2-beta
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
2
3
4
public class Carro {
double velocidade;
String cor;
}
Listagem 4.2: Classe que cria um objeto do tipo Carro
1
2
3
public class CarroTeste {
public static void main(String[] args) {
Carro obj = new Carro();
32
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução à orientação a objetos
obj.cor = "Branco";
obj.velocidade = 80;
4
5
6
System.out.printf("Cor: %s - Velocidade :%s\n", obj.cor, obj.velocidade);
7
}
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 alterar 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
Francisco Calaça, Otávio Calaça
33
Versão 1.2-beta
introdução à orientação a objetos
Listagem 4.3: Carro com atributos e métodos
1
public class Carro {
2
double velocidade;
String cor;
3
4
5
void mudarVelocidade(double v) {
velocidade = v;
System.out.printf("\n\nMudando a velocidade para %f Km/h", velocidade)
;
}
6
7
8
9
10
void pararCarro() {
System.out.printf("\nVelocidade atual: %f Km/h", velocidade);
System.out.printf("\nParando veículo. Velocidade 0 Km/h. Cor: %s", cor
);
}
11
12
13
14
15
}
Listagem 4.4: Classe que cria um objeto do tipo Carro
1
2
3
4
5
6
public class CarroTesteMetodo {
public static void main(String[] args) {
Carro meuCarro = new Carro();
meuCarro.cor = "Branco";
meuCarro.mudarVelocidade(80);
meuCarro.pararCarro();
7
Carro carroDaEsposa = new Carro();
carroDaEsposa.cor = "Vermelho";
carroDaEsposa.mudarVelocidade(60);
carroDaEsposa.pararCarro();
8
9
10
11
}
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.
34
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
2
3
public class Motocicleta {
String cor;
double potencia;
4
public Motocicleta(String c, double p) {
cor = c;
potencia = p;
System.out.printf("\n\nFabricando uma Motocicleta."
+ "\nCor: %s, Potência: %f cilindradas", cor, potencia);
}
5
6
7
8
9
10
11
}
Listagem 4.6: Criação de motocicletas
1
2
3
4
5
6
7
public class MotocicletaTeste {
public static void main(String[] args) {
Motocicleta moto1 = new Motocicleta("Azul", 125);
Motocicleta moto2 = new Motocicleta("Vermelho", 250);
Motocicleta moto3 = new Motocicleta("Prata", 400);
}
}
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
Francisco Calaça, Otávio Calaça
35
Versão 1.2-beta
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 Programming 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
static int quantidadeInstancias;
4
5
public ObjetoTeste() {
quantidadeInstancias ++;
}
6
7
8
9
10
}
Listagem 4.8: Demonstração da palavra chave static
1
2
public class ExemploStatic {
3
public static void main(String[] args) {
ObjetoTeste obj1 = new ObjetoTeste();
ObjetoTeste obj2 = new ObjetoTeste();
ObjetoTeste obj3 = new ObjetoTeste();
4
5
6
7
8
System.out.printf("\nQuantidade de instâncias do Objeto" +
"Teste:%d" , ObjetoTeste.quantidadeInstancias);
9
10
}
11
12
36
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
13
introdução à orientação a objetos
}
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
4
5
6
7
8
9
public class ExemploSemImportStatic {
public static void main(String[] args) {
String numeroTexto = JOptionPane.showInputDialog("Digite um número:");
int numero = new Integer(numeroTexto);
double raizQuadrada = Math.sqrt(numero);
double cubo = Math.pow(numero, 3);
double seno = Math.sin(numero);
10
JOptionPane.showMessageDialog(null,
JOptionPane.showMessageDialog(null,
JOptionPane.showMessageDialog(null,
JOptionPane.showMessageDialog(null,
11
12
13
14
"Raiz Quadrada:" + raizQuadrada);
"Cubo:" + cubo);
"Seno:" + seno);
}
15
16
"Numero:" + numero);
}
Listagem 4.10: Código com import static
1
2
3
import static javax.swing.JOptionPane.*;
import static java.lang.Math.*;
4
5
6
7
8
9
10
11
public class ExemploImportStatic {
public static void main(String[] args) {
String numeroTexto = showInputDialog("Digite um número:");
int numero = new Integer(numeroTexto);
double raizQuadrada = sqrt(numero);
double cubo = pow(numero, 3);
double seno = sin(numero);
http://solutioin.com
Francisco Calaça, Otávio Calaça
37
Versão 1.2-beta
introdução à orientação a objetos
12
showMessageDialog(null,
showMessageDialog(null,
showMessageDialog(null,
showMessageDialog(null,
13
14
15
16
"Numero:" + numero);
"Raiz Quadrada:" + raizQuadrada);
"Cubo:" + cubo);
"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, conversã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;
38
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
2
3
4
5
6
7
public class ExemploAutoBoxing {
public static void main(String[] args) {
/*
* Exemplo de auto boxing. Observe o número 16, tipo int e primitivo, foi
* automaticamente convertido para o tipo Wrapper Integer.
*/
Integer idade = 16;
8
/*
* Exemplo de auto unboxing. Observe a utilização da classe Integer para
* conversão da String 56 em tipo int.
*/
int quantidade = new Integer("56");
9
10
11
12
13
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 variá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
2
3
4
5
6
7
8
public class ExemploEscopo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int numero = i;
System.out.println("linha " + i);
}
}
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
39
Versão 1.2-beta
4.6.
introdução à orientação a objetos
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 informados.
Listagem 4.13: Exemplo de sobrecarga de métodos
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ExemploSobrecarga {
static void metodoQualquer(int i){
System.out.printf("\nEste método recebe um INT: %d", i);
}
static void metodoQualquer(double d){
System.out.printf("\nEste método recebe um DOUBLE: %f", d);
}
static void metodoQualquer(String texto){
System.out.printf("\nEste método recebe um BYTE: %s", texto);
}
static void metodoQualquer(){
System.out.printf("\nEste método não recebe parâmetros");
}
14
public static void main(String[] args) {
metodoQualquer(1);
metodoQualquer(1.0);
metodoQualquer("teste");
metodoQualquer();
}
15
16
17
18
19
20
21
}
40
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
41
5
A R R AY S
Arrays são estruturas de dados que permitem o armazenamento de objetos o que facilita 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.
43
Versão 1.2-beta
arrays
Figura 5.1: Um array pode ser comparado a um porta ovos, cada elemento do array pode ser comparado 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 elementos 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
44
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 elementos 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
2
3
4
5
6
public class DeclaracaoArray {
public static void main(String[] args) {
//Criando um array de tipo int
int [] numeros = new int[10];
//Criando um array de String
String [] textos = new String[10];
7
8
9
System.out.println("\nArray de tipo int");
for (int i = 0; i < numeros.length; i++) {
http://solutioin.com
Francisco Calaça, Otávio Calaça
45
Versão 1.2-beta
arrays
System.out.printf("Posição [%d] = %d\n", i, numeros[i]);
10
}
11
12
System.out.println("\nArray de tipo String");
for (int i = 0; i < textos.length; i++) {
System.out.printf("Posição [%d] = %s\n", i, textos[i]);
}
13
14
15
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
2
3
4
5
6
7
8
public class ParametrosPrograma {
public static void main(String[] args) {
System.out.println("Os parâmetros digitados foram:");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
46
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
47
Versão 1.2-beta
5.4.
arrays
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
2
3
public class ForAprimorado {
public static void main(String[] args) {
String [] transportes = {"Terrestre", "Aquático", "Aéreo"};
4
for (String meioTransporte : transportes) {
System.out.printf("\nTransporte: %s", meioTransporte);
}
5
6
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.
48
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
arrays
Observe, na classe da listagem 5.5, a existência de dois métodos chamados metodoQualquer. 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
3
public class Pessoa {
String nome;
http://solutioin.com
Francisco Calaça, Otávio Calaça
49
Versão 1.2-beta
public Pessoa(String n) {
nome = n;
}
4
5
6
7
arrays
}
Listagem 5.5: Exemplo de passagem de parâmetros no Java
1
2
3
4
public class PassagemParametros {
static void metodoQualquer(int a) {
a++;
}
5
static void metodoQualquer(Pessoa p) {
p.nome = p.nome + "[NOME ALTERADO]";
}
6
7
8
9
public static void main(String[] args) {
System.out.println("Passagem tipo primitivo:");
int valor = 4;
System.out.printf("\nValor antes: %d", valor);
metodoQualquer(4);
System.out.printf("\nValor depois: %d", valor);
10
11
12
13
14
15
16
Pessoa pessoa = new Pessoa("Maria");
System.out.printf("\n\nValor antes: %s", pessoa.nome);
metodoQualquer(pessoa);
System.out.printf("\nValor depois: %s", pessoa.nome);
17
18
19
20
}
21
22
}
Listagem 5.6: Passagem de um array como parâmetro
1
2
3
4
5
6
public class PassagemArray {
static void alteraArray(int[] array) {
for (int i = 0; i < array.length; i++) {
array[i] += 10;
}
}
7
public static void main(String[] args) {
int[] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println("\n\nAntes:");
for (int n : numeros) {
System.out.printf(" %d ", n);
}
alteraArray(numeros);
System.out.println("\n\nDepois:");
for (int n : numeros) {
System.out.printf(" %d ", n);
}
}
8
9
10
11
12
13
14
15
16
17
18
19
20
}
50
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
5.6.
arrays
Arrays multidimensionais
É possível, mas não aconselhado, utilizar arrays multidimensionais no Java. Basta acrescentar 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 variável
Mais uma funcionalidade acrescentada no Java 5 foi a Lista de parâmetros com comprimento variável: vararg. A declaração é feita utilizando o tipo, reticências e nome da variá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
Francisco Calaça, Otávio Calaça
51
Versão 1.2-beta
arrays
Listagem 5.7: Exemplo de utilização de vararg
1
2
3
4
5
6
7
8
public class ExemploVararg {
public static double calcularMedia(double... notas) {
double soma = 0;
for(double n : notas){
soma += n;
}
return soma / notas.length;
}
9
public static void main(String[] args) {
double media = calcularMedia(5, 6, 5, 8);
System.out.printf("\nA média é: %f", media);
}
10
11
12
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.
52
http://solutioin.com
Francisco Calaça, Otávio Calaça
6
U M P O U C O M A I S D E O R I E N TA Ç Ã O A
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 demandam 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
53
Versão 1.2-beta
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
int numero;
3
4
public ObjetoColetado(int n) {
numero = n;
System.out.printf("\n++ Construindo o objeto: %d", numero);
}
5
6
7
8
9
protected void finalize() throws Throwable {
System.out.printf("\n-- Finalizando o objeto: %d", numero);
}
10
11
12
13
14
}
Listagem 6.2: Demonstração do coletor de lixo
1
2
public class ExemploColetorLixo {
3
public static void main(String[] args) {
for (int i = 0; i < 5000; i++) {
new ObjetoColetado(i);
}
}
4
5
6
7
8
9
10
}
6.2.
A palavra-chave this
A palavra chave this pode ser utilizada de duas formas:
• como método
54
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
55
Versão 1.2-beta
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.
56
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 determinadas 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
Francisco Calaça, Otávio Calaça
57
Versão 1.2-beta
um pouco mais de orientação a objetos
Figura 6.2: Exemplo do encapsulamento no eclipse: Invocando o assistente para criação do encapsulamento
Figura 6.3: Exemplo do encapsulamento no eclipse: Escolha dos campos que serão encapsulados
58
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 corresponde 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 gerenciamento de algumas classes.
http://solutioin.com
Francisco Calaça, Otávio Calaça
59
Versão 1.2-beta
um pouco mais de orientação a objetos
Os tipos (classes, enumerações, interfaces) que fazem parte da plataforma java sao membros 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 funcionalidades 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
60
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 necessidade do import.
Listagem 6.3: Exemplo de uso de pacotes
1
2
import java.io.*;
import java.util.Date;
3
4
public class ExemploPacote {
5
public static void main(String[] args) {
/*
* A classe Date foi importada através da declaração:
* import java.util.Date;
* contida no cabeçalho da classe
*/
Date hoje = new Date();
System.out.println(hoje);
6
7
8
9
10
11
12
13
14
/*
* Note a referência direta à List, sem a necessidade
* de realizar um import.
*/
java.util.List lista = new java.util.ArrayList();
15
16
17
18
19
20
/*
* Esta classe foi importada do pacote java.io, através
* da declaração:
* import java.io.*;
*/
File arquivo = new File("c:\\ arquivo.txt");
21
22
23
24
25
26
}
27
28
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
61
Versão 1.2-beta
6.7.
um pouco mais de orientação a objetos
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 explicitamente, 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 herdados 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 imprimirDados é utilizado para imprimir os dados referentes à classe.
Listagem 6.4: Classe Pessoa
1
2
public class PessoaFisica {
3
private String nome;
private String telefone;
4
5
6
7
8
public PessoaFisica(String nome, String telefone) {
this.nome = nome;
this.telefone = telefone;
}
9
10
11
12
13
public void imprimirDados(){
System.out.printf("\nNome: %s - Telefone :%s", nome, telefone);
}
14
15
16
17
public String getNome() {
return nome;
}
18
19
20
62
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
21
22
23
24
25
26
27
28
29
30
um pouco mais de orientação a objetos
}
Listagem 6.5: Classe Aluno - filha de Pessoa
1
2
public class Aluno extends PessoaFisica{
3
private double nota;
4
5
public Aluno(String nome, String telefone, double nota) {
super(nome, telefone);
this.nota = nota;
}
6
7
8
9
10
public void imprimirDados() {
super.imprimirDados();
System.out.printf(" Nota: %.2f", nota);
}
11
12
13
14
15
public double getNota() {
return nota;
}
16
17
18
19
public void setNota(double nota) {
this.nota = nota;
}
20
21
22
23
}
Listagem 6.6: Exemplo da utilização da herança com as classes Pessoa e Aluno
1
2
public class ExemploHeranca {
3
public static void main(String[] args) {
PessoaFisica pessoa = new PessoaFisica("Maria", "3231 -2323");
Aluno aluno = new Aluno("Claudia", "3132 -5656", 8.5);
4
5
6
7
pessoa.imprimirDados();
aluno.imprimirDados();
8
9
}
10
11
12
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
63
Versão 1.2-beta
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 é informado nenhum modificador de acesso, o elemento pode apenas ser acessado de uma classe
que esta no mesmo pacote.
64
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 acessibilidade 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 superclasse. 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. Entretanto,
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
Francisco Calaça, Otávio Calaça
65
Versão 1.2-beta
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
public static void main(String[] args) {
String s1 = new String("texto");
String s2 = new String("texto");
3
4
5
6
System.out.printf("s1 = %s\n", s1);
System.out.printf("s2 = %s\n", s2);
7
8
9
if (s1 == s2) {
System.out.println("s1 igual a s2 com ==");
} else {
System.out.println("s1 diferente de s2 com ==");
}
10
11
12
13
14
15
if (s1.equals(s2)) {
System.out.println("s1 igual a s2 com equals");
} else {
System.out.println("s1 diferente de s2 com equals");
}
16
17
18
19
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
66
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
2
um pouco mais de orientação a objetos
public class ExemploToString {
3
public String toString() {
return "Exemplo da implementação do toString";
}
4
5
6
7
public static void main(String[] args) {
ExemploToString exemplo = new ExemploToString();
System.out.println(exemplo);
}
8
9
10
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, pulando 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
vírgula: ;.
http://solutioin.com
Francisco Calaça, Otávio Calaça
é colocado ponto-
67
Versão 1.2-beta
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 empresa.
O código da listagem 6.9 apresenta a classe Empregado. Observe que esta classe é abstrata (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 EmpregadoAssalariado é 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 també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 empregados 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
68
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
public Empregado(String nome, String telefone) {
super(nome, telefone);
}
4
5
6
7
public String toString() {
return String.format("Nome:%s Telefone :%s
getTelefone(), calcularSalario());
}
8
9
10
11
Salario :%.2f" , getNome(),
12
public abstract double calcularSalario();
13
14
15
}
Listagem 6.10: Código da classe EmpregadoAssalariado
1
2
public class EmpregadoAssalariado extends Empregado{
3
private double salario;
4
5
public EmpregadoAssalariado(String nome, String telefone, double salario) {
super(nome, telefone);
this.salario = salario;
}
6
7
8
9
10
public double calcularSalario() {
return salario;
}
11
12
13
14
public double getSalario() {
return salario;
}
15
16
17
18
public void setSalario(double salario) {
this.salario = salario;
}
19
20
21
22
}
Listagem 6.11: Código da classe EmpregadoComissionado
1
http://solutioin.com
Francisco Calaça, Otávio Calaça
69
Versão 1.2-beta
2
um pouco mais de orientação a objetos
public class EmpregadoComissionado extends Empregado{
3
private double vendasBrutas;
private double comissaoVendas;
public EmpregadoComissionado(String nome, String telefone,
double vendasBrutas, double comissaoVendas) {
super(nome, telefone);
this.vendasBrutas = vendasBrutas;
this.comissaoVendas = comissaoVendas;
}
4
5
6
7
8
9
10
11
12
public double calcularSalario() {
return vendasBrutas * comissaoVendas;
}
13
14
15
16
public double getVendasBrutas() {
return vendasBrutas;
}
17
18
19
20
public void setVendasBrutas(double vendasBrutas) {
this.vendasBrutas = vendasBrutas;
}
21
22
23
24
public double getComissaoVendas() {
return comissaoVendas;
}
25
26
27
28
public void setComissaoVendas(double comissaoVendas) {
this.comissaoVendas = comissaoVendas;
}
29
30
31
32
}
Listagem 6.12: Código da classe EmpregadoHorista
1
2
public class EmpregadoHorista extends Empregado{
3
private int qtdHoras;
private double valorHora;
public EmpregadoHorista(String nome, String telefone, int qtdHoras,
double valorHora) {
super(nome, telefone);
4
5
6
7
8
9
this.qtdHoras = qtdHoras;
this.valorHora = valorHora;
10
11
}
12
13
public double calcularSalario() {
return qtdHoras * valorHora;
}
14
15
16
17
public int getQtdHoras() {
return qtdHoras;
18
19
70
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
um pouco mais de orientação a objetos
}
20
21
public void setQtdHoras(int qtdHoras) {
this.qtdHoras = qtdHoras;
}
22
23
24
25
public double getValorHora() {
return valorHora;
}
26
27
28
29
public void setValorHora(double valorHora) {
this.valorHora = valorHora;
}
30
31
32
33
}
Listagem 6.13: Código da classe FolhaPagamento
1
2
public class FolhaPagamento {
3
public static void main(String[] args) {
Empregado [] empregados = new Empregado[3];
empregados[0] = new EmpregadoAssalariado("Maria", "231 -1234", 1500);
empregados[1] = new EmpregadoComissionado("Antonio", "241 -9876", 5000, 0.25);
empregados[2] = new EmpregadoHorista("Jose", "241 -9876", 40, 50);
4
5
6
7
8
9
for (int i = 0; i < empregados.length; i++) {
System.out.println(empregados[i]);
}
10
11
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, apenas 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
Francisco Calaça, Otávio Calaça
71
Versão 1.2-beta
6.11.1
um pouco mais de orientação a objetos
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
public static void main(String[] args) {
Empregado [] empregados = new Empregado[3];
empregados[0] = new EmpregadoAssalariado("Maria", "231 -1234", 1500);
empregados[1] = new EmpregadoComissionado("Antonio", "241 -9876", 5000, 0.25);
empregados[2] = new EmpregadoHorista("Jose", "241 -9876", 40, 50);
4
5
6
7
8
9
for (int i = 0; i < empregados.length; i++) {
System.out.println(empregados[i]);
if(empregados[i] instanceof EmpregadoComissionado){
EmpregadoComissionado empComiss = (EmpregadoComissionado) empregados[i];
System.out.printf("\nEmpregado comissionado , comissão: %d",
empComiss.getComissaoVendas());
}
System.out.println();
}
10
11
12
13
14
15
16
17
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.
72
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
6.13.
um pouco mais de orientação a objetos
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 programadores concordem com um contrato que diz como determinados componentes de software se comunicarão. Cada grupo precisa estar habilitado a escrever código sem o conhecimento 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 palavrachave 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 newInstance 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
2
3
public interface Animal {
4
5
6
void alimentar();
void locomover();
7
http://solutioin.com
Francisco Calaça, Otávio Calaça
73
Versão 1.2-beta
8
um pouco mais de orientação a objetos
}
Listagem 6.16: Classe Aguia para o exemplo de interfaces
1
2
3
public class Aguia implements Animal{
4
public void alimentar() {
System.out.println("A águia caça a sua presa em voo e a devora!");
}
5
6
7
8
public void locomover() {
System.out.println("A águia se locomove voando!");
}
9
10
11
12
@Override
public String toString() {
return "Aguia";
}
13
14
15
16
17
}
Listagem 6.17: Classe Tigre para o exemplo de interfaces
1
2
3
public class Tigre implements Animal{
4
public void alimentar() {
System.out.println("O tigre caça a sua presa e a devora!");
}
5
6
7
8
public void locomover() {
System.out.println("O tigre se locomove correndo!");
}
9
10
11
12
@Override
public String toString() {
return "Tigre";
}
13
14
15
16
17
18
}
Listagem 6.18: Exemplo da aplicação de interfaces
1
2
3
4
public class Zoo {
5
public static void main(String[] args) {
Animal [] animais = new Animal[2];
animais[0] = new Aguia();
6
7
8
74
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
um pouco mais de orientação a objetos
animais[1] = new Tigre();
for (Animal a : animais) {
System.out.println(a);
a.alimentar();
a.locomover();
}
9
10
11
12
13
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
Francisco Calaça, Otávio Calaça
75
Versão 1.2-beta
um pouco mais de orientação a objetos
17. Explique a utilidade do operador instanceof.
18. O que são interfaces?
76
http://solutioin.com
Francisco Calaça, Otávio Calaça
7
T R ATA M E N T O D E E X C E Ç Õ E S
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 escrito 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.
77
Versão 1.2-beta
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.
78
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
public static void main(String[] args) {
String numeradorString = JOptionPane.showInputDialog("Digite o númerador:");
String denominadorString = JOptionPane.showInputDialog("Digite o denominador:");
7
8
9
10
int numerador = new Integer(numeradorString);
int denominador = new Integer(denominadorString);
11
12
13
int quociente = numerador / denominador;
int resto = numerador % denominador;
14
15
16
String texto = String.format("Quociente :%d, Resto:%d", quociente,
resto);
17
18
19
JOptionPane.showMessageDialog(null, texto);
20
}
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
8
9
public static void main(String[] args) {
String numeradorString = JOptionPane.showInputDialog("Digite o númerador:");
String denominadorString = JOptionPane.showInputDialog("Digite o denominador:");
10
11
12
13
try {
int numerador = new Integer(numeradorString);
int denominador = new Integer(denominadorString);
14
15
16
int quociente = numerador / denominador;
int resto = numerador % denominador;
17
18
19
String texto = String.format("Quociente :%d, Resto:%d",
quociente, resto);
20
21
22
23
24
25
26
JOptionPane.showMessageDialog(null, texto);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Informe apenas números inteiros.");
} catch (ArithmeticException e) {
JOptionPane.showMessageDialog(null, "O denominador não pode ser ZERO.");
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
79
Versão 1.2-beta
}
27
28
tratamento de exceções
}
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 - obrigatoriedade 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 apresenta 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
80
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
3
tratamento de exceções
public class AutenticacaoException extends Exception{
4
public AutenticacaoException(String mensagem) {
super(mensagem);
}
5
6
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 mensagem 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
8
9
10
11
12
13
public static void autenticar(String login, String senha) throws
AutenticacaoException{
/*
* Verifica se o usuário digitou um login.
*/
if(login.length() == 0){
throw new AutenticacaoException("Login vazio");
}
14
/*
* Verifica o login e a senha do usuário.
* Esta verificação normalmente é feita com dados vindos de um Banco de Dados
* ou LDAP. Colocamos o usuario e a senha no código para facilitar
* o entendimento.
*/
if(!"java".equals(login) || !"123".equals(senha)){
throw new AutenticacaoException("Usuário ou senha inválidos");
}
15
16
17
18
19
20
21
22
23
24
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
81
Versão 1.2-beta
tratamento de exceções
25
public static void main(String[] args) {
String login = JOptionPane.showInputDialog("Digite o Login:");
String senha = JOptionPane.showInputDialog("Digite a Senha:");
try {
autenticar(login, senha);
JOptionPane.showMessageDialog(null, "Autenticado");
} catch (AutenticacaoException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
26
27
28
29
30
31
32
33
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 Exception 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
82
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
83
8
FLUXO DE DADOS
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, DataOutputStream, 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
4
5
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
85
Versão 1.2-beta
fluxo de dados
6
7
8
public class ExemploEscrita {
9
public static void main(String[] args) {
File arquivo = new File("c:\\ arquivo.txt");
try {
Formatter fluxo = new Formatter(arquivo);
fluxo.format("Exemplo de escrita do capitulo 10");
fluxo.close();
System.out.println("Arquivo criado ...");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
10
11
12
13
14
15
16
17
18
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 escrita 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
4
5
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
6
7
public class ExemploLeitura {
8
public static void main(String[] args) {
File arquivo = new File("c:\\ arquivo.txt");
System.out.println("Lendo arquivo :\n");
try {
Scanner fluxo = new Scanner(arquivo);
while(fluxo.hasNext()){
System.out.println(fluxo.nextLine());
}
fluxo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
9
10
11
12
13
14
15
16
17
18
19
20
86
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 apresentados 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
Francisco Calaça, Otávio Calaça
87
Versão 1.2-beta
1
2
3
4
5
6
7
8
9
10
fluxo de dados
package capitulo8;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.Scanner;
import java.util.StringTokenizer;
11
12
13
14
15
16
17
import
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFileChooser;
javax.swing.JFrame;
javax.swing.JOptionPane;
javax.swing.JScrollPane;
javax.swing.JTextArea;
18
19
20
21
22
public class EditorTexto extends JFrame implements ActionListener{
JButton botaoAbrir = new JButton("Abrir");
JButton botaoSalvar = new JButton("Salvar");
JTextArea areaTexto = new JTextArea();
23
24
25
public EditorTexto(){
Container c = getContentPane();
26
c.setLayout(new BorderLayout());
c.add(botaoAbrir, BorderLayout.NORTH);
c.add(botaoSalvar, BorderLayout.SOUTH);
c.add(new JScrollPane(areaTexto), BorderLayout.CENTER);
27
28
29
30
31
botaoAbrir.addActionListener(this);
botaoSalvar.addActionListener(this);
32
33
34
setTitle("Editor de Texto");
setSize(800,600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
35
36
37
38
39
}
40
41
42
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser();
43
try {
if(e.getSource() == botaoAbrir){
jfc.showOpenDialog(this);
File file = jfc.getSelectedFile();
abrirArquivo(file);
}else if(e.getSource() == botaoSalvar){
jfc.showSaveDialog(this);
File file = jfc.getSelectedFile();
salvarArquivo(file);
44
45
46
47
48
49
50
51
52
88
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
fluxo de dados
}
}catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(null, "Arquivo não encontrado!");
}
53
54
55
56
}
57
58
private void salvarArquivo(File file) throws FileNotFoundException{
Formatter saida = new Formatter(file);
StringTokenizer token = new StringTokenizer(areaTexto.getText(), "\n");
while(token.hasMoreElements()){
saida.format("%s%n", token.nextElement());
}
saida.close();
}
59
60
61
62
63
64
65
66
67
private void abrirArquivo(File file) throws FileNotFoundException{
String texto = "";
Scanner scan = new Scanner(file);
while(scan.hasNext()){
texto += scan.nextLine() + "\n";
}
areaTexto.setText(texto);
scan.close();
}
68
69
70
71
72
73
74
75
76
77
public static void main(String[] args) {
new EditorTexto();
}
78
79
80
81
}
8.5.
Serialização de objetos
Até agora os fluxos apresentados foram apenas de String. É possível também trafegar objetos 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
Francisco Calaça, Otávio Calaça
89
Versão 1.2-beta
8.6.
fluxo de dados
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
private static final long serialVersionUID = 1;
7
8
private String remetente;
private String descricao;
9
10
90
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
fluxo de dados
11
public String getDescricao() {
return descricao;
}
12
13
14
15
public void setDescricao(String descricao) {
this.descricao = descricao;
}
16
17
18
19
public String getRemetente() {
return remetente;
}
20
21
22
23
public void setRemetente(String remetente) {
this.remetente = remetente;
}
24
25
26
27
public String toString() {
return String.format("%-30s-%s", remetente, descricao);
}
28
29
30
31
}
Listagem 8.5: Classe que envia mensagens
1
package capitulo8;
2
3
4
5
6
import
import
import
import
java.io.IOException;
java.io.ObjectOutputStream;
java.net.Socket;
java.net.UnknownHostException;
7
8
import javax.swing.JOptionPane;
9
10
11
12
13
14
15
16
17
public class Enviador {
public static void main(String[] args) {
String resposta;
do {
resposta = JOptionPane.showInputDialog("Mensagem:");
Mensagem mens = new Mensagem();
mens.setRemetente("Seu Nome");
mens.setDescricao(resposta);
18
19
20
21
22
23
24
25
26
27
28
try {
Socket socket = new Socket("127.0.0.1", 12345);
ObjectOutputStream oos = new ObjectOutputStream(socket
.getOutputStream());
oos.writeObject(mens);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
29
http://solutioin.com
Francisco Calaça, Otávio Calaça
91
Versão 1.2-beta
} while (!resposta.equals("sair"));
30
}
31
32
fluxo de dados
}
Listagem 8.6: Receptor de mensagens
1
package capitulo8;
2
3
4
5
6
import
import
import
import
java.io.ObjectInput;
java.io.ObjectInputStream;
java.net.ServerSocket;
java.net.Socket;
7
8
public class Receptor {
9
public static void main(String[] args) {
ServerSocket server = null;
while (true) {
try {
server = new ServerSocket(12345);
Socket socket = server.accept();
10
11
12
13
14
15
16
ObjectInput ois = new ObjectInputStream(socket.getInputStream());
Mensagem mens = (Mensagem) ois.readObject();
System.out.println(mens);
17
18
19
20
ois.close();
socket.close();
server.close();
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
21
22
23
24
25
26
27
28
29
30
31
32
33
}
34
}
35
36
37
}
92
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
8.7.
fluxo de dados
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
Francisco Calaça, Otávio Calaça
93
9
GENÉRICOS E COLEÇÕES
Em um capítulo anterior foi abordado os Arrays. Um dos problemas dos arrays é a impossibilidade 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 ClassCastExceptions.
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.
95
Versão 1.2-beta
genéricos e coleções
Listagem 9.1: Classe Caixa
1
2
package capitulo9;
public class Caixa {
3
private Object objeto;
4
5
public Object getObjeto() {
return objeto;
}
6
7
8
9
public void setObjeto(Object objeto) {
this.objeto = objeto;
}
10
11
12
13
14
}
Listagem 9.2: Classe CaixaDemo1
1
2
3
package capitulo9;
public class CaixaDemo1 {
public static void main(String[] args) {
4
Caixa caixaDeInteiros = new Caixa();
5
6
caixaDeInteiros.setObjeto(10);
Integer someInteger = (Integer) caixaDeInteiros.getObjeto();
System.out.println(someInteger);
7
8
9
}
10
11
}
Listagem 9.3: Classe CaixaDemo2
1
2
3
package capitulo9;
public class CaixaDemo2 {
public static void main(String[] args) {
4
Caixa caixaDeInteiros = new Caixa();
5
6
/*
* note que estamos adicionando String na caixa
* propositalmente para provocar um erro de conversão
*/
7
8
9
10
11
caixaDeInteiros.setObjeto("10");
12
13
Integer someInteger = (Integer) caixaDeInteiros.getObjeto();
System.out.println(someInteger);
14
15
}
16
17
}
Listagem 9.4: Classe CaixaGenerica
96
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
1
2
genéricos e coleções
package capitulo9;
public class CaixaGenerica <E>{
3
private E objeto;
4
5
public E getObjeto() {
return objeto;
}
6
7
8
9
public void setObjeto(E objeto) {
this.objeto = objeto;
}
10
11
12
13
14
}
Listagem 9.5: Classe CaixaGenericaDemo
1
2
3
package capitulo9;
public class CaixaGenericaDemo {
public static void main(String[] args) {
4
CaixaGenerica<Integer> caixaDeInteiros = new CaixaGenerica<Integer>();
5
6
caixaDeInteiros.setObjeto(10);
Integer someInteger = caixaDeInteiros.getObjeto();
System.out.println(someInteger);
7
8
9
}
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
Francisco Calaça, Otávio Calaça
97
Versão 1.2-beta
genéricos e coleções
• Podem ser ordenadas
Para exemplificar, compare com as listas do mundo real. Pense em uma lista de compras 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
2
3
4
package capitulo9;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
5
6
7
8
9
10
11
12
13
14
15
16
public class ExemploLista {
public static void main(String[] args) {
List<String> cores = new ArrayList<String>();
cores.add("Azul");
cores.add("Vermelho");
cores.add("Preto");
cores.add("Cinza");
cores.add("Laranja");
cores.add("Amarelo");
cores.add("Verde");
cores.add("Azul");
17
for(String c : cores){
System.out.printf("Cor: %s\n",c);
}
18
19
20
21
Collections.sort(cores);
System.out.println("Cores após ordenação");
for(String c : cores){
System.out.printf("Cor: %s\n",c);
}
22
23
24
25
26
27
}
28
29
}
98
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
9.4.
genéricos e coleções
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
2
3
package capitulo9;
import java.util.HashSet;
import java.util.Set;
4
5
6
7
8
9
10
11
12
13
public class ExemploConjunto {
public static void main(String[] args) {
Set<String> cores = new HashSet<String>();
cores.add("Azul");
cores.add("Vermelho");
cores.add("Preto");
cores.add("Amarelo");
cores.add("Verde");
cores.add("Azul");//Repetido propositalmente
14
for(String c : cores){
System.out.printf("\nCor: %s",c);
}
15
16
17
}
18
19
}
9.5.
Mapas
Os mapas apresentam as seguintes características:
• Associam chaves a valores
http://solutioin.com
Francisco Calaça, Otávio Calaça
99
Versão 1.2-beta
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
2
3
package capitulo9;
import java.util.HashMap;
import java.util.Map;
4
5
import javax.swing.JOptionPane;
6
7
8
9
public class ExemploMapa {
public static void main(String[] args) {
Map<String, String> vegetacoes = new HashMap<String, String>();
10
vegetacoes.put("cerrado", "centro -oeste");
vegetacoes.put("floresta tropical", "norte");
vegetacoes.put("caatinga", "nordeste");
vegetacoes.put("mata atlântica", "costa brasileira");
11
12
13
14
15
String escolha = JOptionPane.showInputDialog("Digite uma vegetação:"
+ vegetacoes.keySet());
JOptionPane.showMessageDialog(null, vegetacoes.get(escolha));
16
17
18
}
19
20
}
A Listagem 9.9 apresenta um exemplo um pouco mais complexo de mapa. Neste exemplo é 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
2
3
4
5
6
package capitulo9;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
7
8
100
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
9
genéricos e coleções
public class ExemploMapaContagem {
10
public static void main(String[] args) {
11
12
List<String> lista = new ArrayList<String>();
lista.add("Cerveja");
lista.add("Carvão");
lista.add("Picanha");
lista.add("Cerveja");
lista.add("Cerveja");
lista.add("Cerveja");
lista.add("Cerveja");
lista.add("Cerveja");
lista.add("Costela");
lista.add("Costela");
lista.add("Pão com alho");
lista.add("Pão com alho");
lista.add("Pão com alho");
lista.add("Pão com alho");
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Map<String, Integer> mapaContagem = new HashMap<String, Integer>();
for (String s : lista) {
Integer qtd = mapaContagem.get(s);
if(qtd == null){
qtd = 0;
}
qtd++;
mapaContagem.put(s, qtd);
}
29
30
31
32
33
34
35
36
37
38
for(Entry<String, Integer> e : mapaContagem.entrySet()){
System.out.printf("%s: %d\n", e.getKey(), e.getValue());
}
39
40
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
Francisco Calaça, Otávio Calaça
101
Versão 1.2-beta
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
2
3
4
5
package capitulo9;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ExemploPropertiesEscrita {
public static void main(String[] args) {
Properties prop = new Properties();
prop.put("descricao", "Supermercado da Esquina");
prop.put("endereco", "Rua 2");
prop.put("telefone", "3131 -2363");
try {
FileOutputStream fos = new FileOutputStream("c:\\ prop.properties");
prop.store(fos, "Propriedades do Sistema");
fos.close();
System.out.println("Propriedades salvas");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Listagem 9.11: Exemplo de leitura de arquivos properties
1
2
3
4
5
package capitulo9;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
6
7
import javax.swing.JOptionPane;
8
9
10
11
12
13
public class ExemploPropertiesLeitura {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("c:\\ prop.properties");
Properties prop = new Properties();
102
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
prop.load(fis);
fis.close();
String nomeProp = JOptionPane.showInputDialog("Qual propriedade " +
"deseja ver? (descricao , endereco , telefone)" );
JOptionPane.showMessageDialog(null, prop.getProperty(nomeProp));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
14
15
16
17
18
19
20
21
22
23
}
24
25
genéricos e coleções
}
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
public static void main(String[] args) {
Stack<String> alunos = new Stack<String>();
alunos.push("Maria");
alunos.push("Antonio");
alunos.push("Joaquim");
alunos.push("Carlos");
7
8
9
10
11
12
13
while(!alunos.empty()){
System.out.println(alunos.pop());
}
14
15
16
}
17
18
19
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
103
Versão 1.2-beta
9.7.
genéricos e coleções
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
4
import java.util.LinkedList;
import java.util.Queue;
5
6
public class ExemploFila {
7
public static void main(String[] args) {
Queue<String> alunos = new LinkedList<String>();
alunos.offer("Maria");
alunos.offer("Antonio");
alunos.offer("Joaquim");
alunos.offer("Carlos");
8
9
10
11
12
13
14
while(!alunos.isEmpty()){
System.out.println(alunos.poll());
}
15
16
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();
104
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
private String nome;
5
6
private int idade;
7
8
public Aluno(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
9
10
11
12
13
public String toString(){
return String.format("Aluno: %-10s - %3d", nome, idade);
}
14
15
16
17
public String getNome() {
return nome;
}
18
19
20
21
public void setNome(String nome) {
this.nome = nome;
}
22
23
24
25
public int getIdade() {
return idade;
}
26
27
28
29
public void setIdade(int idade) {
this.idade = idade;
}
30
31
32
33
}
Listagem 9.15: Comparador por idade
1
2
package capitulo9;
import java.util.Comparator;
3
4
public class ComparadorIdade implements Comparator<Aluno>{
5
public int compare(Aluno a1, Aluno a2) {
return a1.getIdade() - a2.getIdade();
}
6
7
8
9
10
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
105
Versão 1.2-beta
genéricos e coleções
Listagem 9.16: Exemplo de ordenacao
1
package capitulo9;
2
3
4
5
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
6
7
8
public class ExemploOrdenacao {
9
public static void main(String[] args) {
List<Aluno> alunos = new ArrayList<Aluno>();
for(int i = 0; i < 15; i++){
int idade = (int)(Math.random() * 5) + 10;
String nome = "Aluno nr. " + i;
Aluno a = new Aluno(nome, idade);
alunos.add(a);
}
10
11
12
13
14
15
16
17
18
System.out.println("Lista original:");
19
20
for(Aluno a : alunos){
System.out.println(a);
}
21
22
23
24
System.out.println("\nLista ordenada por idade:");
25
26
Collections.sort(alunos, new ComparadorIdade());
for(Aluno a : alunos){
System.out.println(a);
}
27
28
29
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.
106
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
107
10
UML: UNIFIED MODELING LANGUAGE
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 software, 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
109
Versão 1.2-beta
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 també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 també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
110
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 descrevem 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 descreve como a classe que possui a regra do todo, é composta (tem) de outras classes, que
http://solutioin.com
Francisco Calaça, Otávio Calaça
111
Versão 1.2-beta
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 representar 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).
112
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 semelhante 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 exemplo 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 suporte 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
Francisco Calaça, Otávio Calaça
113
Versão 1.2-beta
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 relacionamentos. Os Diagramas de Entidade-Associação mostram os dados e as relações e as
restrições entre os dados.
114
http://solutioin.com
Francisco Calaça, Otávio Calaça
11
THREADS
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álculos 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. Esteja 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 execuçã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 é composta 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.
115
Versão 1.2-beta
11.2.
threads
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
public PrimeiraThread(String nome) {
super(nome);
}
5
6
7
8
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.printf("\n Thread: %s (executando) - %5d", getName(), i++);
}
}
9
10
11
12
13
14
}
Listagem 11.2: Execução da Thread que estendeu a classe thread
1
package capitulo11;
2
3
4
5
6
7
8
9
10
public class ExemploThread {
public static void main(String[] args) {
PrimeiraThread thread1 = new PrimeiraThread(" **** ");
PrimeiraThread thread2 = new PrimeiraThread("####");
thread1.start();
thread2.start();
}
}
116
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
threads
Listagem 11.3: Thread criada implementando Runnable
1
package capitulo11;
2
3
public class SegundaThread implements Runnable {
4
private String nome;
5
6
public SegundaThread(String nome) {
this.nome = nome;
}
7
8
9
10
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.printf("\n Thread: %s (executando) - %5d", nome, i++);
}
}
11
12
13
14
15
16
}
Listagem 11.4: Execução da Thread que implementou Runnable
1
package capitulo11;
2
3
4
5
6
public class ExemploThread2 {
public static void main(String[] args) {
SegundaThread st1 = new SegundaThread(" **** ");
SegundaThread st2 = new SegundaThread("####");
7
Thread thread1 = new Thread(st1);
Thread thread2 = new Thread(st2);
8
9
10
thread1.start();
thread2.start();
11
12
}
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
Francisco Calaça, Otávio Calaça
117
Versão 1.2-beta
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
6
7
8
9
public class ExemploThread3 {
public static void main(String[] args) {
SegundaThread t1 = new SegundaThread(" **** ");
SegundaThread t2 = new SegundaThread("####");
SegundaThread t3 = new SegundaThread("$$$$");
10
ExecutorService threads = Executors.newFixedThreadPool(2);
threads.execute(t1);
threads.execute(t2);
threads.execute(t3);
threads.shutdown();
11
12
13
14
15
}
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 especí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 gerenciadas 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 é compartilhado entre as threads es1 e es2. Uma dessas threads é instanciada com true a outra com
118
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
threads
Figura 11.1: Método Thread.sleep
Figura 11.2: Método Thread.yield
http://solutioin.com
Francisco Calaça, Otávio Calaça
119
Versão 1.2-beta
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 synchronized no método fará com que este não possa ser executado por duas threads simultaneamente.
Listagem 11.6: Objeto Troca que está compartilhado entre a threads
1
package capitulo11;
2
3
4
public class Troca {
private int a;
5
private int b;
6
7
public void trocar(boolean bol) throws InterruptedException {
if (bol) {
a = 5;
b = 7;
} else {
a = 11;
b = 13;
}
Thread.sleep(500);
8
9
10
11
12
13
14
15
16
17
if (bol) {
System.out.printf("%d = 5 e %d = 7 \n", a, b);
} else {
System.out.printf("%d = 11 e %d = 13 \n", a, b);
}
18
19
20
21
22
}
23
24
}
Listagem 11.7: Thread que acessará o objeto Troca
1
package capitulo11;
2
3
4
5
public class Operador implements Runnable {
private boolean bol;
private Troca obj;
6
7
8
9
public Operador(Troca obj, boolean bol) {
this.bol = bol;
this.obj = obj;
120
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
threads
}
10
11
public void run() {
while (true) {
try {
obj.trocar(bol);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
12
13
14
15
16
17
18
19
20
21
}
Listagem 11.8: Exemplo de threads não sincronizadas
1
package capitulo11;
2
3
4
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
5
6
7
public class ExemploSinc {
8
public static void main(String[] args) {
Troca obj = new Troca();
Operador es1 = new Operador(obj, true);
Operador es2 = new Operador(obj, false);
9
10
11
12
13
ExecutorService t1 = Executors.newFixedThreadPool(2);
t1.execute(es1);
t1.execute(es2);
t1.shutdown();
14
15
16
17
}
18
19
}
11.6.
O verificador de primos
Para exemplificar melhor o uso de threads as listagens 11.9 e 11.10 apresentam um Verificador 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
Francisco Calaça, Otávio Calaça
121
Versão 1.2-beta
threads
6
public VerificadorPrimo(long numero) {
this.numero = numero;
}
7
8
9
10
public void run() {
boolean primo = true;
for (int i = 2; i < numero; i++) {
if ((numero % i) == 0) {
primo = false;
}
}
11
12
13
14
15
16
17
18
if (primo) {
System.out.printf("\nO número: %d é primo", numero);
} else {
System.out.printf("\nO número: %d não é primo", numero);
}
19
20
21
22
23
}
24
25
}
Listagem 11.10: Verificador de números primos
1
package capitulo11;
2
3
import javax.swing.JOptionPane;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestePrimo {
public static void main(String[] args) {
String resposta;
do {
resposta =
JOptionPane.showInputDialog("Digite um número");
try {
long numero = new Long(resposta);
VerificadorPrimo vf = new VerificadorPrimo(numero);
vf.start();
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null,
"número invalido" );
}
19
} while (!resposta.equals("sair"));
20
}
21
22
}
122
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
123
12
S T R I N G S E D ATA S
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
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
int diaAno = calendar.get(Calendar.DAY_OF_YEAR);
int ano = calendar.get(Calendar.YEAR);
7
8
9
10
11
System.out.printf("\nEstamos no %d dia do ano de %d", diaAno, ano);
12
}
13
14
15
}
125
Versão 1.2-beta
12.2.
strings e datas
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 implementa 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
4
5
6
import
import
import
import
java.text.DateFormat;
java.text.ParseException;
java.text.SimpleDateFormat;
java.util.Date;
7
8
import javax.swing.JOptionPane;
9
10
public class ExemploFormatacaoData {
11
public static void main(String[] args) {
DateFormat formatadorEntrada = new SimpleDateFormat(
"dd/MM/yyyy" );
DateFormat formatadorSaida = new SimpleDateFormat(
12
13
14
15
"’Data Informada:’ dd ’de’ MMMM ’de’ yyyy - ’(’EEEE ’)’" );
16
17
String dataTexto = JOptionPane
.showInputDialog("Digite uma data:");
try {
Date data = formatadorEntrada.parse(dataTexto);
String dataFormatada = formatadorSaida.format(data);
JOptionPane.showMessageDialog(null, "Data digitada: "
+ dataFormatada);
} catch (ParseException e) {
e.printStackTrace();
}
18
19
20
21
22
23
24
25
26
27
28
}
29
30
31
}
126
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
12.3.
strings e datas
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
8
public static long concatenarComString() {
long t1 = System.currentTimeMillis();
9
String texto = "";
for (int i = 0; i < quantidade; i++) {
texto += "a";
}
10
11
12
13
14
long t2 = System.currentTimeMillis();
return t2 - t1;
15
16
17
}
18
19
20
public static long concatenarComStringBuffer() {
long t1 = System.currentTimeMillis();
21
StringBuffer texto = new StringBuffer("");
for (int i = 0; i < quantidade; i++) {
texto.append("a");
}
22
23
24
25
26
long t2 = System.currentTimeMillis();
return t2 - t1;
27
28
29
}
30
http://solutioin.com
Francisco Calaça, Otávio Calaça
127
Versão 1.2-beta
strings e datas
public static void main(String[] args) {
long tempoStringBuffer = concatenarComStringBuffer();
System.out.printf("Tempo com StringBuffer: %d ms \n", tempoStringBuffer);
31
32
33
34
long tempoString = concatenarComString();
System.out.printf("Tempo com String: %d ms \n", tempoString);
35
36
}
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 linguagens 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.
128
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
%s
Utilizado com Strings
%d
Utilizado com números inteiros decimais
%o
Utilizado com números inteiros octais
%x
Utilizado com números inteiros hexadecimais (utilize “%X” para que as letras
aparecam maiúsculas)
%f
Utilizado com números com ponto flutuante
%t
Utilizado com datas. Deve ser combinado com os formatadores da tabela ??
para produzir um resultado.
strings e datas
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
Francisco Calaça, Otávio Calaça
129
Versão 1.2-beta
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
public static void main(String[] args) {
7
8
/*
* Exemplo de formatação de números inteiros
*/
System.out.println("Formatação de inteiros");
int inteiro = 123;
System.out.printf("%10s %10s %10s", "DECIMAL", "OCTAL", "HEXADECIMAL");
System.out.printf("\n%1$10d %1$10o %1$10X", inteiro);
9
10
11
12
13
14
15
16
/*
* Exemplo de formatação de ponto flutuante
*/
System.out.println("\n\nFormatação de ponto flutuantes");
double flutuante = 1.2345;
System.out.printf("%.3f", flutuante);
17
18
19
20
21
22
23
/*
* Formatação de Datas e Horas
*/
System.out.println("\n\nFormatação de datas e horas");
Date hoje = new Date();
System.out.printf("Hora atual: %1$tH:%1$tM:%1$tS", hoje);
System.out.printf("\nData formatada: %1$tF", hoje);
System.out.printf("\nData atual: %1$td/%1$tm/%1$tY", hoje);
24
25
26
27
28
29
30
31
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 formato yyyy-mm-dd utilizando a classe SimpleDateFormat.
130
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
strings e datas
3. Descreva a classe String.
4. Qual a diferença entre String e StringBuffer?
http://solutioin.com
Francisco Calaça, Otávio Calaça
131
13
JDBC
Um Sistema Gerenciador de Banco de Dados (SGBD) é o conjunto de programas de computador 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 complexas 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 informaçõ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");
133
Versão 1.2-beta
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
6
7
8
9
public class Conexao {
private static String
private static String
private static String
private static String
driver = "org.postgresql.Driver";
url = "jdbc:postgresql :// localhost/treinamento";
usuario = "postgres";
senha = "123456";
10
public static Connection getConexao() {
try {
Class.forName(driver);
return DriverManager.getConnection(url, usuario, senha);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
11
12
13
14
15
16
17
18
19
20
21
22
23
}
Figura 13.1: Configuração do CLASSPATH para o Driver JDBC
134
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
13.2.
jdbc
A linguagem SQL
SQL é um linguagem de consulta a registros em um Banco de dados Relacional. As instruçõ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 _ substituirá apenas com um caracter.
http://solutioin.com
Francisco Calaça, Otávio Calaça
135
Versão 1.2-beta
13.2.4
jdbc
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.
136
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 possibilita 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 respectivo 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
8
9
10
11
public static void main(String[] args) {
Connection con = Conexao.getConexao();
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from cliente");
12
13
14
15
16
17
18
19
while (rs.next()) {
System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
rs.getString("nome"), rs.getString("cpfCnpj"),
rs.getString("endereco"),
rs.getString("municipio"),
rs.getString("uf"));
}
20
21
22
23
con.close();
} catch (SQLException e) {
e.printStackTrace();
http://solutioin.com
Francisco Calaça, Otávio Calaça
137
Versão 1.2-beta
}
24
}
25
26
jdbc
}
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ápida 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
4
5
6
import
import
import
import
java.sql.Connection;
java.sql.PreparedStatement;
java.sql.SQLException;
java.sql.Statement;
7
8
public class ExemploExecucaoBatch {
9
10
public static Connection con = Conexao.getConexao();
11
12
13
14
15
16
17
18
19
static void limparTabela(){
try {
Statement stmt = con.createStatement();
stmt.execute("delete from cliente");
} catch (SQLException e) {
e.printStackTrace();
}
}
20
21
22
23
24
public static long executarSemBatch(){
limparTabela();
long t1 = System.currentTimeMillis();
try {
138
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
jdbc
PreparedStatement pstmt = con.prepareStatement("insert into cliente "
+ "(nome , cpfCnpj , endereco , municipio , uf) "
+ "values (?, ?, ?, ?, ?)");
for(int i = 0; i < 50000; i++){
pstmt.setString(1, "nome");
pstmt.setString(2, "cpfCnpj");
pstmt.setString(3, "endereco");
pstmt.setString(4, "municipio");
pstmt.setString(5, "uf");
pstmt.execute();
}
} catch (SQLException e) {
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
return t2 - t1;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
}
41
42
public static long executarComBatch(){
limparTabela();
long t1 = System.currentTimeMillis();
try {
PreparedStatement pstmt = con.prepareStatement("insert into cliente "
+ "(nome , cpfCnpj , endereco , municipio , uf) "
+ "values (?, ?, ?, ?, ?)");
for(int i = 0; i < 50000; i++){
pstmt.setString(1, "nome");
pstmt.setString(2, "cpfCnpj");
pstmt.setString(3, "endereco");
pstmt.setString(4, "municipio");
pstmt.setString(5, "uf");
pstmt.addBatch();
}
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
return t2 - t1;
}
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public static void main(String[] args) {
long t1 = executarComBatch();
System.out.printf("Com Batch: %d (ms)\n", t1);
67
68
69
70
long t2 = executarSemBatch();
System.out.printf("Sem Batch: %d (ms)\n", t2);
71
72
}
73
74
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
139
Versão 1.2-beta
13.5.
jdbc
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
18
19
public int getId() {
return id;
}
20
21
22
23
public void setId(int id) {
this.id = id;
}
24
25
26
27
public String getNome() {
return nome;
}
28
29
30
31
public void setNome(String nome) {
this.nome = nome;
}
32
33
34
35
public String getCpfCnpj() {
return cpfCnpj;
}
36
37
38
39
public void setCpfCnpj(String cpfCnpj) {
this.cpfCnpj = cpfCnpj;
}
40
41
42
43
public String getEndereco() {
return endereco;
}
44
45
public void setEndereco(String endereco) {
140
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
jdbc
this.endereco = endereco;
46
}
47
48
public String getMunicipio() {
return municipio;
}
49
50
51
52
public void setMunicipio(String municipio) {
this.municipio = municipio;
}
53
54
55
56
public String getUf() {
return uf;
}
57
58
59
60
public void setUf(String uf) {
this.uf = uf;
}
61
62
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
4
5
6
7
8
9
import
import
import
import
import
import
import
java.sql.Connection;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
java.util.ArrayList;
java.util.List;
10
11
public class ClienteDao {
12
13
14
15
16
17
18
19
20
21
22
private Cliente mapear(ResultSet rs) throws SQLException{
Cliente cliente = new Cliente();
cliente.setId(rs.getInt("id"));
cliente.setNome(rs.getString("nome"));
cliente.setCpfCnpj(rs.getString("cpfCnpj"));
cliente.setEndereco(rs.getString("endereco"));
cliente.setMunicipio(rs.getString("municipio"));
cliente.setUf(rs.getString("uf"));
return cliente;
}
23
24
25
26
public void incluir(Cliente cliente) {
Connection con = Conexao.getConexao();
try {
http://solutioin.com
Francisco Calaça, Otávio Calaça
141
Versão 1.2-beta
try {
PreparedStatement pstmt = con.prepareStatement("insert into cliente " +
"(nome , cpfcnpj , endereco , municipio , uf) values (?, ?, ?, ?, ?)" );
pstmt.setString(1, cliente.getNome());
pstmt.setString(2, cliente.getCpfCnpj());
pstmt.setString(3, cliente.getEndereco());
pstmt.setString(4, cliente.getMunicipio());
pstmt.setString(5, cliente.getUf());
pstmt.execute();
} finally {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
jdbc
}
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public List<Cliente> listar() {
Connection con = Conexao.getConexao();
List<Cliente> resultado = new ArrayList<Cliente>();
try {
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from cliente");
while (rs.next()) {
Cliente cliente = mapear(rs);
resultado.add(cliente);
}
} finally {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return resultado;
}
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public void excluir(int id){
Connection con = Conexao.getConexao();
try {
try {
PreparedStatement pstmt = con.prepareStatement("delete from cliente where
id = ?" );
pstmt.setInt(1, id);
pstmt.execute();
} finally {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
142
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
public static void main(String[] args) {
Cliente cliente = new Cliente();
cliente.setNome(JOptionPane.showInputDialog("Nome:"));
cliente.setCpfCnpj(JOptionPane.showInputDialog("Cpf/Cnpj:"));
cliente.setEndereco(JOptionPane.showInputDialog("Endereço:"));
cliente.setMunicipio(JOptionPane.showInputDialog("Município:"));
cliente.setUf(JOptionPane.showInputDialog("UF:"));
9
10
11
12
13
14
15
16
ClienteDao cdao = new ClienteDao();
cdao.incluir(cliente);
17
18
19
List<Cliente> clientes = cdao.listar();
for(Cliente c : clientes){
System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
c.getNome(),
c.getCpfCnpj(),
c.getEndereco(),
c.getMunicipio(),
c.getUf());
}
20
21
22
23
24
25
26
27
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
Francisco Calaça, Otávio Calaça
143
Versão 1.2-beta
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.
144
http://solutioin.com
Francisco Calaça, Otávio Calaça
14
J AVA P E R S I S T E N C E A P I C O M
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 disponibiliza é 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 configuraçõ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
145
Versão 1.2-beta
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
4
5
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
6
7
8
@Entity
public class Cliente {
9
146
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
10
11
12
java persistence api com hibernate
@Id
@GeneratedValue
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
25
26
public int getId() {
return id;
}
27
28
29
30
public void setId(int id) {
this.id = id;
}
31
32
33
34
public String getNome() {
return nome;
}
35
36
37
38
public void setNome(String nome) {
this.nome = nome;
}
39
40
41
42
public String getCpfCnpj() {
return cpfCnpj;
}
43
44
45
46
public void setCpfCnpj(String cpfCnpj) {
this.cpfCnpj = cpfCnpj;
}
47
48
49
50
public String getEndereco() {
return endereco;
}
51
52
53
54
public void setEndereco(String endereco) {
this.endereco = endereco;
}
55
56
57
58
public String getMunicipio() {
return municipio;
}
59
60
61
public void setMunicipio(String municipio) {
this.municipio = municipio;
http://solutioin.com
Francisco Calaça, Otávio Calaça
147
Versão 1.2-beta
java persistence api com hibernate
}
62
63
public String getUf() {
return uf;
}
64
65
66
67
public void setUf(String uf) {
this.uf = uf;
}
68
69
70
71
}
14.4.
O arquivo persistence.xml
O arquivo persistence.xml é o “coração” da JPA. É nele que serão definidas as configuraçõ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 configuraçõ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 entidades
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
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF -8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns
/persistence/persistence _ 1 _ 0.xsd" >
<persistence-unit name="aulajpa">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show _ sql" value="true"/>
10
148
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
11
12
13
14
15
16
17
18
java persistence api com hibernate
<property name="hibernate.dialect" value="org.hibernate.dialect.
PostgreSQLDialect" />
<property name="hibernate.connection.driver _ class" value="org.postgresql.
Driver" />
<property name="hibernate.connection.url" value="jdbc:postgresql: //
localhost/treinamento" />
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="123456"/>
</properties>
</persistence-unit>
</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
Francisco Calaça, Otávio Calaça
149
Versão 1.2-beta
14.5.
java persistence api com hibernate
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ância 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
6
7
8
import
import
import
import
javax.persistence.EntityManager;
javax.persistence.EntityManagerFactory;
javax.persistence.Persistence;
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
17
18
19
20
public void incluir(Cliente cliente) {
em.getTransaction().begin();
em.persist(cliente);
em.getTransaction().commit();
}
21
22
23
24
25
public List<Cliente> listar() {
Query query = em.createNativeQuery("select * from cliente", Cliente.class);
return query.getResultList();
}
26
27
28
29
30
31
32
public void excluir(int id){
em.getTransaction().begin();
Cliente c = em.find(Cliente.class, id);
em.remove(c);
em.getTransaction().commit();
}
150
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
public static void main(String[] args) {
Cliente cliente = new Cliente();
cliente.setNome(JOptionPane.showInputDialog("Nome:"));
cliente.setCpfCnpj(JOptionPane.showInputDialog("Cpf/Cnpj:"));
cliente.setEndereco(JOptionPane.showInputDialog("Endereço:"));
cliente.setMunicipio(JOptionPane.showInputDialog("Município:"));
cliente.setUf(JOptionPane.showInputDialog("UF:"));
9
10
11
12
13
14
15
16
ClienteDaoJpa cdao = new ClienteDaoJpa();
cdao.incluir(cliente);
17
18
19
List<Cliente> clientes = cdao.listar();
for(Cliente c : clientes){
System.out.printf("%-30s%-30s%-30s%-30s%-30s\n",
c.getNome(),
c.getCpfCnpj(),
c.getEndereco(),
c.getMunicipio(),
c.getUf());
}
20
21
22
23
24
25
26
27
28
}
29
30
}
14.6.1 Persistindo entidades
Persistir uma entidade é o ato de inseri-la em um banco de dados. Você persiste entidades que ainda não foram criadas no banco de dados. Para isso utilize o método persiste(entidade) do EntityManager.
http://solutioin.com
Francisco Calaça, Otávio Calaça
151
Versão 1.2-beta
14.6.2
java persistence api com hibernate
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). Somente 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;
152
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
4
java persistence api com hibernate
import static javax.persistence.FetchType.EAGER;
5
6
7
import java.util.ArrayList;
import java.util.List;
8
9
10
11
12
13
import
import
import
import
import
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.Id;
javax.persistence.JoinColumn;
javax.persistence.OneToMany;
14
15
16
@Entity
public class Curso {
17
@Id
@GeneratedValue
private int id;
18
19
20
21
private String nome;
22
23
@JoinColumn(name="curso _ id")
@OneToMany(cascade=ALL, fetch = EAGER)
private List<Disciplina> disciplinas = new ArrayList<Disciplina>();
24
25
26
27
public String toString() {
StringBuffer sb = new StringBuffer(nome);
sb.append("\n");
for(Disciplina disciplina : disciplinas){
sb.append("
" );
sb.append(disciplina);
sb.append("\n");
}
return sb.toString();
}
28
29
30
31
32
33
34
35
36
37
38
public int getId() {
return id;
}
39
40
41
42
public String getNome() {
return nome;
}
43
44
45
46
public void setNome(String nome) {
this.nome = nome;
}
47
48
49
50
public List<Disciplina> getDisciplinas() {
return disciplinas;
}
51
52
53
54
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
153
Versão 1.2-beta
java persistence api com hibernate
Listagem 14.6: Classe Disciplina do exemplo de relacionamento @OneToMany
1
package capitulo14;
2
3
4
5
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
6
7
8
@Entity
public class Disciplina {
9
@Id
@GeneratedValue
private int id;
10
11
12
13
private String nome;
14
15
private int cargaHoraria;
16
17
public String toString() {
return String.format("%s - %s", nome, cargaHoraria);
}
18
19
20
21
public int getId() {
return id;
}
22
23
24
25
public String getNome() {
return nome;
}
26
27
28
29
public void setNome(String nome) {
this.nome = nome;
}
30
31
32
33
public int getCargaHoraria() {
return cargaHoraria;
}
34
35
36
37
public void setCargaHoraria(int cargaHoraria) {
this.cargaHoraria = cargaHoraria;
}
38
39
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) {
154
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
java persistence api com hibernate
Disciplina disciplina1 = new Disciplina();
disciplina1.setNome("Matematica");
8
9
10
Disciplina disciplina2 = new Disciplina();
disciplina2.setNome("Portugues");
11
12
13
Disciplina disciplina3 = new Disciplina();
disciplina3.setNome("Fisica");
14
15
16
Curso curso = new Curso();
curso.setNome("Nucleo comum");
curso.getDisciplinas().add(disciplina1);
curso.getDisciplinas().add(disciplina2);
curso.getDisciplinas().add(disciplina3);
17
18
19
20
21
22
CursoDaoJpa cursoDaoJpa = new CursoDaoJpa();
cursoDaoJpa.incluir(curso);
23
24
25
List<Curso> cursos = cursoDaoJpa.listar();
for(Curso c : cursos){
System.out.println(c);
}
26
27
28
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
Francisco Calaça, Otávio Calaça
155
Versão 1.2-beta
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 objetos 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!
156
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
14.10.
java persistence api com hibernate
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
Francisco Calaça, Otávio Calaça
157
15
A P L I C AT I V O S W E B
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 execuçã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 Consortium - 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 esquematizaçõ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.
159
Versão 1.2-beta
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 rapidamente 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
2
3
4
5
6
<dados>
<pessoa nome="Manoel">
<endereco rua="Rua 2" numero="30" />
<endereco rua="Av Goias" numero="2" />
</pessoa>
</dados>
15.2.
HTML
HTML (acrônimo para a expressão inglesa HyperText Markup Language, que significa Linguagem 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>
160
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
<table>
aplicativos web
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 documento 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
Francisco Calaça, Otávio Calaça
161
Versão 1.2-beta
15.3.
aplicativos web
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 linguagens de script).
Sua união com o CSS é conhecida como DHTML. Usando o Javascript, é possível modificar 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 ECMA262, também conhecido como ECMAScript. Este padrão é seguido, por exemplo, pela linguagem 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, escrevendoo 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
2
3
4
<html>
<head>
<title>Exemplo de JavaScript</title>
</head>
5
6
7
<script type="text/javascript">
var qtdVezes = 0;
162
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
8
9
10
11
12
aplicativos web
function clicar(comp){
qtdVezes++;
complemento = qtdVezes > 1 ? "es" : "";
comp.value = qtdVezes + " vez" + complemento;
}
13
14
15
16
17
18
19
20
function formatarData(comp){
data = comp.value;
data = data.substring(0,2) + "/" + data.substring(2,4) + "/" +
data.substring(4,8);
comp.value = data;
}
</script>
21
22
23
24
25
26
27
28
<body>
Clique no botão:
<input type="button" value="Clique" onclick="javascript:clicar(this)"/>
<br/>
Data:<input type="text" onblur="javascript:formatarData(this)"/>
</body>
</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 Consortium", 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 fabricantes, 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
Francisco Calaça, Otávio Calaça
163
Versão 1.2-beta
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<html>
<head>
<link href="estilo.css" type="text/css" rel="stylesheet"/>
<title>Primeira página HTML</title>
</head>
<body>
<h1>Tabela de Cursos</h1>
<table>
<tr>
<th>Curso</th>
<th>Carga Horária</th>
<th>Instrutor</th>
</tr>
<tr>
<td>Java</td>
<td>80 Horas</td>
<td>Francisco</td>
</tr>
<tr>
<td>Delphi</td>
<td>160 Horas</td>
<td>Danilo</td>
</tr>
<tr>
<td>Linux</td>
<td>160 Horas</td>
<td>Diogo</td>
</tr>
</table>
</body>
</html>
Listagem 15.4: estilo.css - exemplo de css
1
h1{
164
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
font-family: verdana;
font-size: 25pt;
color: #00aa22;
font-weight: bold;
2
3
4
5
6
aplicativos web
}
7
8
th{
font-family: verdana;
font-size: 15pt;
color: #0022aa;
9
10
11
12
13
}
td{
font-family: verdana;
font-size: 12pt;
color: #00aa22;
background-color: #ccccff;
14
15
16
17
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/MeusAplicativos).
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
Francisco Calaça, Otávio Calaça
165
Versão 1.2-beta
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?
166
http://solutioin.com
Francisco Calaça, Otávio Calaça
16
S E RV L E T S
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 desenvolvedor 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, utilizando 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 estender 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 implantaçã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
167
Versão 1.2-beta
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. Compile 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 common/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 instalado 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
4
import java.io.IOException;
import java.io.PrintWriter;
5
6
7
8
9
10
import
import
import
import
import
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
11
12
13
@WebServlet("/PrimeiroServlet")
public class PrimeiroServlet extends HttpServlet {
14
15
16
17
18
19
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<HTML >");
out.println("<HEAD ><TITLE >Primeiro Servlet </TITLE ></HEAD >");
168
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
servlets
out.println("<BODY >");
out.println("<H1>PRIMEIRO SERVLET FUNCIONANDO ...</H1>");
out.println("</BODY >");
out.println("</HTML >");
out.close();
20
21
22
23
24
}
25
26
27
}
Listagem 16.2: O descritor de implantação web.xml
1
2
<web-app>
<display-name>Exemplo de servlet</display-name>
3
4
5
6
7
<servlet>
<servlet-name>primeiro</servlet-name>
<servlet-class>capitulo16.PrimeiroServlet</servlet-class>
</servlet>
8
9
10
11
12
13
<servlet-mapping>
<servlet-name>primeiro</servlet-name>
<url-pattern>/prim</url-pattern>
</servlet-mapping>
</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
Francisco Calaça, Otávio Calaça
169
Versão 1.2-beta
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">
170
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
servlets
Figura 16.4: Novo projeto Web no eclipse
http://solutioin.com
Francisco Calaça, Otávio Calaça
171
Versão 1.2-beta
servlets
Figura 16.5: Novo projeto Web no eclipse
Figura 16.6: Novo projeto Web no eclipse
172
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
servlets
Figura 16.7: Novo projeto Web no eclipse
Figura 16.8: Configuração do nome do projeto
http://solutioin.com
Francisco Calaça, Otávio Calaça
173
Versão 1.2-beta
servlets
Figura 16.9: Configuração dos frameworks web
Figura 16.10: Configuração do diretório dos fontes e dos arquivos web
174
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
4
import java.io.IOException;
import java.io.PrintWriter;
5
6
7
8
9
10
11
import
import
import
import
import
import
javax.servlet.RequestDispatcher;
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
12
13
14
@WebServlet("/ExemploGet")
public class ExemploGet extends HttpServlet {
15
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String nome = request.getParameter("nome");
String nascimento = request.getParameter("nascimento");
16
17
18
19
20
21
out.println("<html >");
out.println("<body >");
out.printf("%s nasceu em %s", nome, nascimento);
out.println("</body >");
out.println("</html >");
out.close();
22
23
24
25
26
27
}
28
29
}
Listagem 16.4: Página Html que enviará as informações através do método get
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<title>Exemplo Get</title>
</head>
<body>
<form action="ExemploGet" method="get">
Nome: <input type="text" name="nome" /><br/>
Data de nascimento: <input type="text" name="nascimento" /><br/>
<input type="submit" value="Enviar"/>
</form>
</body>
</html>
http://solutioin.com
Francisco Calaça, Otávio Calaça
175
Versão 1.2-beta
16.5.
servlets
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
4
import java.io.IOException;
import java.io.PrintWriter;
5
6
7
8
9
10
11
import
import
import
import
import
import
javax.servlet.RequestDispatcher;
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
12
13
14
@WebServlet("/ExemploPost")
public class ExemploPost extends HttpServlet {
15
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
16
17
18
19
String nome = request.getParameter("nome");
String endereco = request.getParameter("endereco");
String salario = request.getParameter("salario");
20
21
22
23
out.println("<html >");
out.println("<body");
out.printf("Nome: %s <br/>", nome);
out.printf("Endereco: %s <br/>", endereco);
out.printf("Salario: %s <br/>", salario);
out.println("</body >");
out.println("</html >");
out.close();
24
25
26
27
28
29
30
31
}
32
33
}
Listagem 16.6: Página Html que enviará as informações através do método post
1
2
3
<html>
<head>
<title>Exemplo método post</title>
176
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
4
5
6
7
8
9
10
11
12
13
14
15
servlets
</head>
<body>
<form action="ExemploPost" method="POST">
<pre>
Nome:
<input type="text" name="nome" />
Endereco: <input type="text" name="endereco" />
Salario: <input type="text" name="salario" />
<input type="submit" />
</pre>
</form>
</body>
</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, automaticamente 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
2
3
4
5
6
7
8
9
<html>
<head>
<title>Exemplo Redirect</title>
</head>
<body>
<form action="ExemploRedirect" method="post">
Salário: <input type="text" name="salario"/>
<input type="submit" value="Enviar"/>
</form>
http://solutioin.com
Francisco Calaça, Otávio Calaça
177
Versão 1.2-beta
10
11
servlets
</body>
</html>
Listagem 16.8: Servlet do exemplo de Redirect
1
package capitulo16;
2
3
import java.io.IOException;
4
5
6
7
8
9
10
import
import
import
import
import
import
javax.servlet.RequestDispatcher;
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
11
12
13
@WebServlet("/ExemploRedirect")
public class ExemploRedirect extends HttpServlet {
14
protected void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
double salario = Double.parseDouble(request.getParameter("salario"));
String pagina;
if(salario >= 5000){
pagina = "aprovado.html";
}else{
pagina = "reprovado.html";
}
15
16
17
18
19
20
21
22
23
response.sendRedirect(pagina);
24
}
25
26
}
Listagem 16.9: Tela que apresenta o resultado: aprovado
1
2
3
4
5
6
7
8
<html>
<head>
<title>Aprovado</title>
</head>
<body>
<h1 style="color: green;">LIMITE APROVADO</h1>
</body>
</html>
Listagem 16.10: Tela que apresenta o resultado: reprovado
1
2
3
4
5
6
7
<html>
<head>
<title>Rerovado</title>
</head>
<body>
<h1 style="color: red;">LIMITE REPROVADO</h1>
</body>
178
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
8
servlets
</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
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<title>Exemplo Forward</title>
</head>
<body>
<form action="ExemploForward" method="post">
Salário: <input type="text" name="salario"/>
<input type="submit" value="Enviar"/>
</form>
</body>
</html>
Listagem 16.12: Servlet do exemplo de Forward
1
package capitulo16;
2
3
import java.io.IOException;
4
5
6
7
8
9
10
import
import
import
import
import
import
javax.servlet.RequestDispatcher;
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
11
12
13
@WebServlet("/ExemploForward")
public class ExemploForward extends HttpServlet{
14
http://solutioin.com
Francisco Calaça, Otávio Calaça
179
Versão 1.2-beta
servlets
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
double salario = Double.parseDouble(request.getParameter("salario"));
String pagina;
if(salario >= 5000){
pagina = "aprovado.html";
}else{
pagina = "reprovado.html";
}
15
16
17
18
19
20
21
22
23
RequestDispatcher rd = request.getRequestDispatcher(pagina);
rd.forward(request, response);
24
25
}
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 desaparecem.
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 requisiçã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.
180
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
181
Versão 1.2-beta
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 ?
182
http://solutioin.com
Francisco Calaça, Otávio Calaça
17
J AVA S E RV E R PA G E S
JavaServer Pages - JSP - é uma tecnologia que simplifica o processo de desenvolvimento
de aplicações web. Com JSP, os desenvolvedores podem rapidamente incorporar elementos 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 elaboraçã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 trabalhar 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”
<%
183
Versão 1.2-beta
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
2
3
4
5
6
<html>
<head>
<title>Exemplo de JSP</title>
</head>
<body>
<%for(int i = 0; i < 15; i++){ %>
7
8
Linha: <%=i %> <br/>
9
10
<%} %>
11
12
13
</body>
</html>
184
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
2
3
4
<a
<a
<a
<a
href="index.jsp">Início</a>
href="exemploJsp.jsp">Primeiro Exemplo</a>
href="clientes.jsp">Lista de Clientes</a>
href="clientes -jstl.jsp">Lista de Clientes com JSTL</a>
Listagem 17.3: Arquivo index.jsp
1
<html>
<head>
2
<title>Página inicial</title>
3
</head>
<body>
4
5
<%@include file="menu.jsp" %>
6
7
<h1>Página inicial</h1>
8
</body>
9
10
</html>
http://solutioin.com
Francisco Calaça, Otávio Calaça
185
Versão 1.2-beta
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”, “text/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" %>
186
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 exatamente 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 previsto durante o processamento de uma página JSP no container. Exemplo:
<%@ page errorPage="/apostila/exemplos/erro.jsp" %>
http://solutioin.com
Francisco Calaça, Otávio Calaça
187
Versão 1.2-beta
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 determinado 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"/>
188
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
Francisco Calaça, Otávio Calaça
189
Versão 1.2-beta
17.5.
java server pages
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 Controller.
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 é aniversá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
6
7
8
9
10
import
import
import
import
import
import
javax.servlet.RequestDispatcher;
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
11
12
13
import capitulo13.Cliente;
import capitulo13.ClienteDao;
190
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
java server pages
14
15
16
@WebServlet("/ClienteControl")
public class ClienteControl extends HttpServlet {
17
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String acao = request.getParameter("acao");
ClienteDao clienteDao = new ClienteDao();
if(acao == null){
request.setAttribute("lista", clienteDao.listar());
RequestDispatcher rd = request .getRequestDispatcher("cliente.jsp");
rd.forward(request, response);
}else if(acao.equals("excluir")){
int id = Integer.parseInt(request.getParameter("id"));
clienteDao.excluir(id);
response.sendRedirect("ClienteControl");
}else if(acao.equals("confirmar")){
Cliente cliente = new Cliente();
cliente.setNome(request.getParameter("nome"));
cliente.setCpfCnpj(request.getParameter("cpfCnpj"));
cliente.setEndereco(request.getParameter("endereco"));
cliente.setMunicipio(request.getParameter("municipio"));
cliente.setUf(request.getParameter("uf"));
clienteDao.incluir(cliente);
response.sendRedirect("ClienteControl");
}
}
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
41
42
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
4
5
6
7
<html>
<head>
<title>Cadastro de Clientes</title>
</head>
<body>
8
9
<%@ include file="menu.jsp" %>
10
11
12
13
14
15
16
<form action="ClienteControl">
<pre>
<input type="hidden"
Nome:
<input type="text"
CPF/CNPJ:
<input type="text"
Endereço:
<input type="text"
http://solutioin.com
Francisco Calaça, Otávio Calaça
name="acao" value="confirmar"/>
name="nome"/>
name="cpfCnpj"/>
name="endereco"/>
191
Versão 1.2-beta
17
18
19
20
21
java server pages
Município: <input type="text" name="municipio"/>
UF:
<input type="text" name="uf"/>
<input type="submit" value="Confirmar"/>
</pre>
</form>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<table border="1" rules="all">
<c:forEach items="${lista}" var="cliente">
<tr>
<td>${cliente.id}</td>
<td>${cliente.nome}</td>
<td>${cliente.cpfCnpj}</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>
37
38
39
40
</body>
</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.
192
http://solutioin.com
Francisco Calaça, Otávio Calaça
18
I N T R O D U Ç Ã O A O J AVA S E RV E R F A C E S
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, escolha: 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:
193
Versão 1.2-beta
introdução ao javaserver faces
Figura 18.1: Escolha JavaServer Faces v2.0 Project
194
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução ao javaserver faces
Figura 18.2: Escolha Disable Library Configuration
http://solutioin.com
Francisco Calaça, Otávio Calaça
195
Versão 1.2-beta
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
private String entrada;
7
8
private String saida;
9
10
public void executar(ActionEvent evt){
saida = String.format(" * %s - %s * ", entrada, entrada.toUpperCase());
}
11
12
13
14
public String getEntrada() {
return entrada;
}
15
16
17
18
196
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução ao javaserver faces
public void setEntrada(String entrada) {
this.entrada = entrada;
}
19
20
21
22
public String getSaida() {
return saida;
}
23
24
25
26
public void setSaida(String saida) {
this.saida = saida;
}
27
28
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 relacionadas 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
Francisco Calaça, Otávio Calaça
197
Versão 1.2-beta
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.
198
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
2
3
<html xmlns="http://www.w3.org /1999/ xhtml"
xmlns:h="http :// java.sun.com/jsf/html"
xmlns:f="http ://java.sun.com/jsf/core">
4
5
<h:head>
6
7
</h:head>
8
9
10
11
12
13
14
15
16
17
<h:body>
<h:form>
<h:inputText value="#{ exemploControl.entrada}" />
<h:commandButton ajax="false"
actionListener="#{ exemploControl.executar}" value="Executar" />
<h:outputText value="#{ exemploControl.saida}" />
</h:form>
</h:body>
</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 (ManagedBean). A expressão
#{exemploControl.executar}
http://solutioin.com
Francisco Calaça, Otávio Calaça
199
Versão 1.2-beta
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:
200
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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
2
3
4
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>blitzer</param-value>
</context-param>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
<param-value>*.xhtml</param-value>
</context-param>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
22
23
24
25
26
27
28
29
30
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/*</url-pattern>
</servlet-mapping>
http://solutioin.com
Francisco Calaça, Otávio Calaça
201
Versão 1.2-beta
18.6.
introdução ao javaserver faces
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
4
import java.util.ArrayList;
import java.util.List;
5
6
7
8
import javax.faces.component.UIParameter;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
9
10
import org.primefaces.event.RowEditEvent;
11
12
13
import capitulo13.Cliente;
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
24
25
26
27
28
29
30
31
public void confirmar(ActionEvent evt){
if(cliente.getId() == 0){
clienteDao.incluir(cliente);
}else{
clienteDao.alterar(cliente);
}
cliente = new Cliente();
listar(evt);
}
202
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução ao javaserver faces
32
public void gravar(RowEditEvent event){
Cliente c = (Cliente) event.getObject();
clienteDao.alterar(c);
}
33
34
35
36
37
public List<SelectItem> getUfs(){
List<SelectItem> result = new ArrayList<SelectItem>();
for(EnumUf uf : EnumUf.values()){
result.add(new SelectItem(uf.toString(), uf.getDescricao()));
}
return result;
}
38
39
40
41
42
43
44
45
public void excluirCliente(ActionEvent evt){
UIParameter param = (UIParameter) evt.getComponent().findComponent("cliExcluir");
Cliente c = (Cliente) param.getValue();
clienteDao.excluir(c.getId());
listar(evt);
}
46
47
48
49
50
51
52
public void listar(ActionEvent evt){
clientes = clienteDao.listar();
}
53
54
55
56
public Cliente getCliente() {
return cliente;
}
57
58
59
60
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
61
62
63
64
public List<Cliente> getClientes() {
return clientes;
}
65
66
67
68
69
70
71
}
Listagem 18.5: Arquivo cliente.xhtml
1
2
3
4
<html xmlns="http://www.w3.org /1999/ xhtml"
xmlns:h="http :// java.sun.com/jsf/html"
xmlns:f="http ://java.sun.com/jsf/core"
xmlns:p="http :// primefaces.org/ui">
5
6
<h:head>
7
8
</h:head>
9
10
<h:body>
http://solutioin.com
Francisco Calaça, Otávio Calaça
203
Versão 1.2-beta
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
introdução ao javaserver faces
<h:form>
<p:panel header="Manter Clientes">
<h:panelGrid columns="2">
<h:outputText value="Nome:" />
<p:inputText value="#{ clienteControl.cliente.nome}"></p:inputText>
<h:outputText value="CPF/CNPJ:" />
<p:inputText value="#{ clienteControl.cliente.cpfcnpj}"></p:inputText>
<h:outputText value="Endereço:" />
<p:inputText value="#{ clienteControl.cliente.endereco}"></p:inputText>
<h:outputText value=" M u n i c à p i o :" />
<p:inputText value="#{ clienteControl.cliente.municipio}"></p:inputText>
<h:outputText value="UF:" />
<p:inputText value="#{ clienteControl.cliente.uf}"></p:inputText>
<p:commandButton ajax="false"
actionListener="#{ clienteControl.confirmar}" value="Confirmar"></p:commandButton>
<p:commandButton ajax="false"
actionListener="#{ clienteControl.listar}" value="Listar"></p:commandButton>
</h:panelGrid>
29
30
31
32
33
34
35
<p:dataTable value="#{ clienteControl.clientes}" var="cli"
editable="true">
<f:facet name="header">
<h:outputText value="Clientes" />
</f:facet>
<p:ajax event="rowEdit" listener="#{ clienteControl.gravar}"></p:ajax>
36
<p:column headerText="Nome" sortBy="#{cli.nome}"
filterBy="#{cli.nome}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cli.nome}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cli.nome}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Cpf/Cnpj" sortBy="#{cli.cpfcnpj}">
<h:outputText value="#{cli.cpfcnpj}" />
</p:column>
<p:column>
<p:tooltip for="editar" hideEffect="explode"
value="Clique aqui para editar #{cli.nome}" />
<p:rowEditor id="editar" />
</p:column>
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<p:column headerText="UF" sortBy="#{cli.uf}" filterBy="#{cli.uf}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cli.uf}" />
</f:facet>
<f:facet name="input">
57
58
59
60
61
62
204
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
63
64
65
66
67
68
69
introdução ao javaserver faces
<p:selectOneMenu value="#{cli.uf}">
<f:selectItem itemLabel="Selecione" />
<f:selectItems value="#{ clienteControl.ufs}"></f:selectItems>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
70
71
72
73
74
75
76
77
78
79
<p:column>
<p:commandButton actionListener="#{ clienteControl.excluirCliente}"
icon="ui-icon -trash">
<f:param id="cliExcluir" value="#{cli}"></f:param>
</p:commandButton>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
80
81
82
</h:body>
</html>
18.7.
Cadastro de Produtos (com JPA)
Listagem 18.6: Classe Produto
1
package aulajsf;
2
3
4
5
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
6
7
8
@Entity
public class Produto {
9
10
11
12
@Id
@GeneratedValue
private int id;
13
14
private String descricao;
15
16
private double valor;
17
18
private int quantidade;
19
20
21
22
public int getId() {
return id;
}
23
24
25
public void setId(int id) {
this.id = id;
http://solutioin.com
Francisco Calaça, Otávio Calaça
205
Versão 1.2-beta
introdução ao javaserver faces
}
26
27
public String getDescricao() {
return descricao;
}
28
29
30
31
public void setDescricao(String descricao) {
this.descricao = descricao;
}
32
33
34
35
public double getValor() {
return valor;
}
36
37
38
39
public void setValor(double valor) {
this.valor = valor;
}
40
41
42
43
public int getQuantidade() {
return quantidade;
}
44
45
46
47
public void setQuantidade(int quantidade) {
this.quantidade = quantidade;
}
48
49
50
51
52
}
Listagem 18.7: Classe ProdutoDao
1
package aulajsf;
2
3
import java.util.List;
4
5
6
7
8
import
import
import
import
javax.persistence.EntityManager;
javax.persistence.EntityManagerFactory;
javax.persistence.Persistence;
javax.persistence.Query;
9
10
public class ProdutoDao {
11
12
13
private static EntityManagerFactory emf =
Persistence.createEntityManagerFactory("aulajpa");
14
15
private EntityManager em = emf.createEntityManager();
16
17
18
19
20
21
public void incluir(Produto p){
em.getTransaction().begin();
em.persist(p);
em.getTransaction().commit();
}
22
23
public void alterar(Produto p){
206
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução ao javaserver faces
em.getTransaction().begin();
em.merge(p);
em.getTransaction().commit();
24
25
26
}
27
28
public Produto consultar(int id){
return em.find(Produto.class, id);
}
29
30
31
32
public void excluir(int id){
em.getTransaction().begin();
Produto p = consultar(id);
em.remove(p);
em.getTransaction().commit();
}
33
34
35
36
37
38
39
public List<Produto> listar(){
Query query = em.createQuery("select p from Produto p");
List<Produto> prods = query.getResultList();
return prods;
}
40
41
42
43
44
45
public List<Produto> listar(String descricao){
Query query = em.createQuery("select p from Produto p where upper(p.descricao)
like upper(: descricao)" );
query.setParameter("descricao", "%"+descricao+"%");
List<Produto> prods = query.getResultList();
return prods;
}
46
47
48
49
50
51
52
53
}
Listagem 18.8: Classe ProdutoControl
1
package aulajsf;
2
3
4
import java.util.ArrayList;
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
19
public void confirmar(ActionEvent evt){
produtoDao.alterar(produto);
http://solutioin.com
Francisco Calaça, Otávio Calaça
207
Versão 1.2-beta
introdução ao javaserver faces
listar(evt);
produto = new Produto();
20
21
}
22
23
public void listar(ActionEvent evt){
produtos = produtoDao.listar();
}
24
25
26
27
public void gravar(RowEditEvent e){
Produto p = (Produto) e.getObject();
produtoDao.alterar(p);
28
29
30
31
}
32
33
public Produto getProduto() {
return produto;
}
34
35
36
37
public void setProduto(Produto produto) {
this.produto = produto;
}
38
39
40
41
public List<Produto> getProdutos() {
return produtos;
}
42
43
44
45
46
}
Listagem 18.9: Tela produto.xhtml
1
2
3
4
<html xmlns="http ://www.w3.org /1999/ xhtml"
xmlns:h="http ://java.sun.com/jsf/html"
xmlns:f="http ://java.sun.com/jsf/core"
xmlns:p="http :// primefaces.org/ui">
5
6
<h:head>
7
8
</h:head>
9
10
11
12
13
14
15
16
17
18
19
<h:body>
<h:form>
<p:panel header="Manter Produtos">
<h:panelGrid columns="2">
<h:outputText value="Descrição:" />
<p:inputText value="#{ produtoControl.produto.descricao}"></p:inputText>
<h:outputText value="Quantidade:" />
<p:inputText value="#{ produtoControl.produto.quantidade}"></p:inputText>
<h:outputText value="Valor:" />
<p:inputText value="#{ produtoControl.produto.valor}"></p:inputText>
20
<p:commandButton ajax="false"
actionListener="#{ produtoControl.confirmar}" value="Confirmar"></p:commandButton>
21
22
23
208
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
24
25
introdução ao javaserver faces
<p:commandButton ajax="false"
actionListener="#{ produtoControl.listar}" value="Listar"></p:commandButton>
26
27
</h:panelGrid>
28
29
30
<p:dataTable value="#{ produtoControl.produtos}" var="prod"
editable="true">
31
32
33
34
35
<f:facet name="header">
<h:outputText value="Produtos" />
</f:facet>
<p:ajax event="rowEdit" listener="#{ produtoControl.gravar}"></p:ajax>
36
37
38
39
40
41
42
43
44
45
46
47
<p:column headerText="Nome" sortBy="#{prod.descricao}"
filterBy="#{prod.descricao}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{prod.descricao}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{prod.descricao}" />
</f:facet>
</p:cellEditor>
</p:column>
48
49
50
51
52
53
54
<p:column>
<p:commandButton ajax="false" value="Selecionar">
<f:setPropertyActionListener target="#{ produtoControl.produto}"
value="#{prod}"></f:setPropertyActionListener>
</p:commandButton>
</p:column>
55
56
57
58
<p:column>
<p:rowEditor></p:rowEditor>
</p:column>
59
60
61
62
</p:dataTable>
</p:panel>
</h:form>
63
64
65
</h:body>
</html>
Finalmente, os arquivos de configuração do projeto estão nas Listagens 18.10 e 18.11.
Listagem 18.10: web.xml
1
2
3
<?xml version="1.0" encoding="UTF -8"?>
<web-app xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"
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
Francisco Calaça, Otávio Calaça
209
Versão 1.2-beta
5
6
introdução ao javaserver faces
version="3.0">
<display-name>capitulo18</display-name>
7
8
9
10
11
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>blitzer</param-value>
</context-param>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
<param-value>*.xhtml</param-value>
</context-param>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
29
30
31
32
33
34
35
36
37
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/*</url-pattern>
</servlet-mapping>
38
39
40
41
42
43
44
45
46
47
48
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
</web-app>
Listagem 18.11: faces-config.xml
1
2
3
4
<?xml version="1.0" encoding="UTF -8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org /2001/ XInclude"
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"
>
210
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
introdução ao javaserver faces
<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>
<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>
<managed-bean>
<managed-bean-name>produtoControl</managed-bean-name>
<managed-bean-class>aulajsf.ProdutoControl</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>produtoListControl</managed-bean-name>
<managed-bean-class>aulajsf.ProdutoListControl</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</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
2
3
<?xml version="1.0" encoding="UTF -8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org /2001/
XMLSchema -instance"
4
5
6
7
8
9
10
11
12
13
14
15
16
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns
/persistence/persistence _ 1 _ 0.xsd" >
<persistence-unit name="aulajpa">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show _ sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"
/>
<property name="hibernate.connection.url" value="jdbc:postgresql: // localhost/
treinamento" />
<property name="hibernate.connection.driver _ class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="123456" />
</properties>
</persistence-unit>
</persistence>
Dica:
Não esqueça de adicionar as dependências da JPA nas libs do projeto
de JSF.
http://solutioin.com
Francisco Calaça, Otávio Calaça
211
Versão 1.2-beta
18.8.
introdução ao javaserver faces
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
4
import java.util.ArrayList;
import java.util.List;
5
6
import javax.faces.event.ActionEvent;
7
8
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
18
19
public List<Produto> listarPorDescricao(String descricao){
return produtoDao.listar(descricao);
}
20
212
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
introdução ao javaserver faces
public void adicionar(ActionEvent evt){
produtos.add(produto);
}
21
22
23
24
public List<Produto> getProdutos() {
return produtos;
}
25
26
27
28
public Produto getProduto() {
return produto;
}
29
30
31
32
public void setProduto(Produto produto) {
this.produto = produto;
}
33
34
35
36
37
}
Listagem 18.14: Classe ProdutoControl
1
package aulajsf;
2
3
4
import java.util.HashMap;
import java.util.Map;
5
6
7
8
9
import
import
import
import
javax.faces.component.UIComponent;
javax.faces.context.FacesContext;
javax.faces.convert.Converter;
javax.faces.convert.FacesConverter;
10
11
12
13
@FacesConverter("produtoConverter")
public class ProdutoConverter implements Converter{
14
private static Map<String, Produto> mapa = new HashMap<String, Produto>();
15
16
@Override
public Object getAsObject(FacesContext ctx, UIComponent comp, String value) {
return mapa.get(value);
}
17
18
19
20
21
@Override
public String getAsString(FacesContext ctx, UIComponent comp, Object value) {
if(value instanceof Produto){
Produto p = (Produto) value;
mapa.put(String.valueOf(p.getId()), p);
return String.valueOf(p.getId());
}else{
return "";
}
}
22
23
24
25
26
27
28
29
30
31
32
33
}
http://solutioin.com
Francisco Calaça, Otávio Calaça
213
Versão 1.2-beta
introdução ao javaserver faces
Listagem 18.15: Tela produto.xhtml
1
2
3
4
<html xmlns="http ://www.w3.org /1999/ xhtml"
xmlns:h="http ://java.sun.com/jsf/html"
xmlns:f="http ://java.sun.com/jsf/core"
xmlns:p="http :// primefaces.org/ui">
5
6
<h:head>
7
8
</h:head>
9
10
11
12
13
<h:body>
<h:form enctype="multipart/form -data">
<p:panel header="Manter Produtos">
<p:autoComplete value="#{ produtoListControl.produto}" id="produto" completeMethod="
#{ produtoListControl.listarPorDescricao}"
14
15
var="p" itemLabel="#{p.descricao}" itemValue="#{p}" converter
="produtoConverter" forceSelection="true"/>
<p:commandButton value="Adicionar" actionListener="#{ produtoListControl.adicionar}"
update="produtos"></p:commandButton>
16
17
18
19
20
<p:dataTable value="#{ produtoListControl.produtos}" var="prod" id="produtos">
<f:facet name="header">
<h:outputText value="Produtos" />
</f:facet>
21
<p:column>
<h:outputText value="#{prod.descricao}"></h:outputText>
</p:column>
22
23
24
25
<p:column>
<h:outputText value="#{prod.valor}"></h:outputText>
</p:column>
26
27
28
29
30
31
32
</p:dataTable>
</p:panel>
</h:form>
33
34
35
</h:body>
</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!
214
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
18.9.
introdução ao javaserver faces
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
Francisco Calaça, Otávio Calaça
215
19
PA D R Õ E S D E P R O J E T O
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 recorrente 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, documentaçã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.
217
Versão 1.2-beta
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.
218
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
padrões de projeto
19.2.1 Utilização
O padrão Abstract Factory pode ser utilizado na implementação de um toolkit que disponibilize 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, independentemente 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 concreta. 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 instanciação para as subclasses.
19.3.1 Utilização
Este padrão é muito utilizado em frameworks para definir e manter relacionamentos entre 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. Normalmente 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 alguns 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 implementaçã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
Francisco Calaça, Otávio Calaça
219
Versão 1.2-beta
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 suportados 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 operaçã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 operaçõ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 Command 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 estados 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 anterior 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.
220
http://solutioin.com
Francisco Calaça, Otávio Calaça
Versão 1.2-beta
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 implementaçã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 dados 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
Francisco Calaça, Otávio Calaça
221
Versão 1.2-beta
padrões de projeto
Produtos comerciais como o TopLink estão disponíveis, baseados em mapeamento objetorelacional (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 observadores 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 dados, 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 programaçã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.
222
http://solutioin.com
Francisco Calaça, Otávio Calaça
A
M O N TA G E M D O A M B I E N T E D E
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 ferramentas 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
223
B
E R R O S C O M U N S E N F R E N TA D O S P O R
INICIANTES
B.1.
Exceções que costumam serem vistas
B.1.1 ClassNotFoundException
B.1.2 NoSuchMethodError
B.1.3 LazyInitializationException
B.1.4 NoClassDefFoundError
B.1.5 NullPointerException
B.1.6 ClassCastException
B.2.
Erros comuns do HTTP
225
Download