Você está na página 1de 200

PROGRAMAÇÃO II

Professor Dr. Edson A. Oliveira Junior


Professor Me. André Abdala Noel

GRADUAÇÃO

Unicesumar
Reitor
Wilson de Matos Silva
Vice-Reitor
Wilson de Matos Silva Filho
Pró-Reitor Executivo de EAD
William Victor Kendrick de Matos Silva
Pró-Reitor de Ensino de EAD
Janes Fidélis Tomelin
Presidente da Mantenedora
Cláudio Ferdinandi

NEAD - Núcleo de Educação a Distância


Diretoria Executiva
Chrystiano Mincoff
James Prestes
Tiago Stachon
Diretoria de Graduação e Pós-graduação
Kátia Coelho
Diretoria de Permanência
Leonardo Spaine
Diretoria de Design Educacional
Débora Leite
Head de Produção de Conteúdos
Celso Luiz Braga de Souza Filho
Head de Curadoria e Inovação
Tania Cristiane Yoshie Fukushima
Gerência de Produção de Conteúdo
Diogo Ribeiro Garcia
Gerência de Projetos Especiais
Daniel Fuverki Hey
Gerência de Processos Acadêmicos
Taessa Penha Shiraishi Vieira
Supervisão de Produção de Conteúdo
Nádila Toledo
Coordenador de Conteúdo
Danillo Xavier Saes
Designer Educacional
Camila Zaguini Silva
Lilian Vespa da Silva
Nádila de Almeida Toledo
Rossana Costa Giani
Projeto Gráfico
Jaime de Marchi Junior
José Jhonny Coelho
C397 CENTRO UNIVERSITÁRIO DE MARINGÁ. Núcleo de Educação Arte Capa
a Distância; NOEL, Andre Abdala; JUNIOR, Edson A. Oliveira. Arthur Cantareli Silva
Editoração
Programação II. André Abdala Noel; Edson A. Oliveira Junior. Robson Yuiti Saito
Maringá-Pr.: UniCesumar, 2018. Reimpresso em 2021.
200 p. Qualidade Textual
“Graduação - EaD”. Ana Paula da Silva,
Flaviana Bersan Santos
1. Programação. 2. Java. 3. EaD. I. Título. Jaquelina Kutsunugi
Keren Pardini
ISBN 978-85-459-1160-9 Maria Fernanda Canova Vasconcelos
CDD - 22 ed. 005.1 Nayara Valenciano
CIP - NBR 12899 - AACR/2 Rhaysa Ricci Correa
Viviane Favaro Notari
Ilustração
Bruno Pardinho
Ficha catalográfica elaborada pelo bibliotecário
João Vivaldo de Souza - CRB-8 - 6828
Impresso por:
Em um mundo global e dinâmico, nós trabalhamos
com princípios éticos e profissionalismo, não so-
mente para oferecer uma educação de qualidade,
mas, acima de tudo, para gerar uma conversão in-
tegral das pessoas ao conhecimento. Baseamo-nos
em 4 pilares: intelectual, profissional, emocional e
espiritual.
Iniciamos a Unicesumar em 1990, com dois cursos
de graduação e 180 alunos. Hoje, temos mais de
100 mil estudantes espalhados em todo o Brasil:
nos quatro campi presenciais (Maringá, Curitiba,
Ponta Grossa e Londrina) e em mais de 300 polos
EAD no país, com dezenas de cursos de graduação e
pós-graduação. Produzimos e revisamos 500 livros
e distribuímos mais de 500 mil exemplares por
ano. Somos reconhecidos pelo MEC como uma
instituição de excelência, com IGC 4 em 7 anos
consecutivos. Estamos entre os 10 maiores grupos
educacionais do Brasil.
A rapidez do mundo moderno exige dos educa-
dores soluções inteligentes para as necessidades
de todos. Para continuar relevante, a instituição
de educação precisa ter pelo menos três virtudes:
inovação, coragem e compromisso com a quali-
dade. Por isso, desenvolvemos, para os cursos de
Engenharia, metodologias ativas, as quais visam
reunir o melhor do ensino presencial e a distância.
Tudo isso para honrarmos a nossa missão que é
promover a educação de qualidade nas diferentes
áreas do conhecimento, formando profissionais
cidadãos que contribuam para o desenvolvimento
de uma sociedade justa e solidária.
Vamos juntos!
Seja bem-vindo(a), caro(a) acadêmico(a)! Você está
iniciando um processo de transformação, pois quando
investimos em nossa formação, seja ela pessoal ou
profissional, nos transformamos e, consequentemente,
transformamos também a sociedade na qual estamos
inseridos. De que forma o fazemos? Criando oportu-
nidades e/ou estabelecendo mudanças capazes de
alcançar um nível de desenvolvimento compatível com
os desafios que surgem no mundo contemporâneo.
O Centro Universitário Cesumar mediante o Núcleo de
Educação a Distância, o(a) acompanhará durante todo
este processo, pois conforme Freire (1996): “Os homens
se educam juntos, na transformação do mundo”.
Os materiais produzidos oferecem linguagem dialógica
e encontram-se integrados à proposta pedagógica, con-
tribuindo no processo educacional, complementando
sua formação profissional, desenvolvendo competên-
cias e habilidades, e aplicando conceitos teóricos em
situação de realidade, de maneira a inseri-lo no mercado
de trabalho. Ou seja, estes materiais têm como principal
objetivo “provocar uma aproximação entre você e o
conteúdo”, desta forma possibilita o desenvolvimento
da autonomia em busca dos conhecimentos necessá-
rios para a sua formação pessoal e profissional.
Portanto, nossa distância nesse processo de cresci-
mento e construção do conhecimento deve ser apenas
geográfica. Utilize os diversos recursos pedagógicos
que o Centro Universitário Cesumar lhe possibilita.
Ou seja, acesse regularmente o Studeo, que é o seu
Ambiente Virtual de Aprendizagem, interaja nos fóruns
e enquetes, assista às aulas ao vivo e participe das dis-
cussões. Além disso, lembre-se que existe uma equipe
de professores e tutores que se encontra disponível para
sanar suas dúvidas e auxiliá-lo(a) em seu processo de
aprendizagem, possibilitando-lhe trilhar com tranqui-
lidade e segurança sua trajetória acadêmica.
CURRÍCULO

Professor Dr. Edson A. Oliveira Junior


Bacharel em Informática pela Universidade Estadual de Maringá (UEM), Mestre
em Ciência da Computação pela Universidade Estadual de Maringá (UEM)
e Doutor em Ciências de Computação e Matemática Computacional pelo
Instituto de Ciências Matemáticas e de Computação (ICMC) da Universidade
de São Paulo (USP). Todos esses títulos foram obtidos na área de concentração
de Engenharia de Software, em que minha especialidade é Linha de Produto
de Software e Gerenciamento de Variabilidade, além de Arquitetura de
Software, Desenvolvimento Baseado em Componentes (DBC), Frameworks e
Metamodelagem e Modelagem UML. DBC e Frameworks são temas de pesquisa
que envolvem não só a modelagem de sistemas, mas a implementação de
sistemas e suas arquiteturas. Participo de vários cursos de Pós-Graduação em
diversas instituições de ensino superior, como a própria UEM, UNIPAR, Faculdade
Integrado, UniCesumar, Faculdade Alfa, Instituto Paranaense de Ensino e
Faculdade Cidade Verde. Possuo as seguintes certificações da Tecnologia Java:
Sun Certified Java Associate, Sun Certified Java Programmer, Sun Certified Java
Developer, Sun Certified Web Component Developer e Sun Certified Business
Component Developer, todas elas certificadas pela Sun Microsystems, entre
os anos de 2003 e 2007. Ministro esta disciplina em cursos de treinamento
técnico, graduação e pós-graduação desde o ano de 2000.

Professor Me. Andre Abdala Noel


Professor e programador,mestre em Ciência da Computação pela Universidade
Estadual de Maringá, com ênfase em sistemas de computação, e bacharel em
Ciência da Computação pela Universidade Estadual de Maringá. Possui boa
experiência em programação, aplicando também na docência superior, desde
2008. Autor do site Vida de Programador, se mantém bem ativo na comunidade
de desenvolvedores.
APRESENTAÇÃO

PROGRAMAÇÃO II

SEJA BEM-VINDO(A)!
Prezado(a) acadêmico(a), é com grande satisfação que apresento a você o livro de Pro-
gramação em Java II. Este material foi elaborado com o objetivo de contribuir em sua
formação, especialmente a de desenvolvedor(a) de software. Sou o professor Edson A.
Oliveira Junior, autor deste material. Você pode ter certeza que este material foi prepara-
do com carinho especial para que você possa entender o que essa disciplina pode te tra-
zer de benefício ao longo de sua vida como desenvolvedor(a) e/ou analista de sistemas.
Inicialmente, como você já deve ter lido e exercitado todos os conceitos básicos de Java
no livro Programação em Java I, este livro abordará conceitos mais avançados de orien-
tação a objetos como sobrecarga em Java, que é diferente da sobreposição que estuda-
mos no livro I. A sobreposição permite redefir o comportamento (implementação) de
um método que foi herdado, possibilitando que a subclasse possua os dois comporta-
mentos: o herdado e o implementado. Já a sobrecarga permite que você use um mes-
mo identificador (nome) para métodos e construtores de uma mesma classe, mudando
somente a assinatura destes, além de tratamento de exceções.
A Unidade II abordará classes abstratas e interfaces. As classes abstratas podem possuir
métodos concretos (com implementação) e métodos abstratos (somente a assinatu-
ra) sem fornecer uma implementação padrão. As subclasses concretas de uma classe
concreta devem implementar os métodos concretos. Esta é uma forma de garantir que
o método será implementado de acordo com a classe a qual se destina. Já interfaces
possuem somente métodos abstratos, porém não fornecem suporte à característica de
herança.
Na Unidade III, você entenderá os elementos essenciais para se trabalhar com vários
objetos de uma mesma classe ao mesmo tempo: arrays e coleções Java. Existem vários
tipos de coleções, cada uma com um propósito e um conjunto de características pró-
prias que são usadas em diversas situações diferentes.
A Unidade IV abordará a criação de interfaces gráficas desktop por meio das API AWT
e Swing. Interfaces gráficas em Java envolvem o projeto e a construção de layouts para
que os elementos gráficos de interação (botões, caixas, campos etc.) possam ser acomo-
dados. Interfaces gráficas não podem dispensar o tratamento de exceções, caracteriza-
das por interrupções abruptas da execução de código Java, sem que o usuário possa ter
a chance de interagir com o programa. Para tanto, isolamos esses códigos permitindo
que o programa Java não seja simplemente abortado sem uma justificativa.
APRESENTAÇÃO

Por fim, na Unidade V, serão apresentados os conceitos de persistência de dados por


meio das APIs JDBC e JPA. JDBC é o método tradicional de armazenamento de dados em
um banco de dados. Já JPA permite mapear as classes Java para entidades de um banco
de dados, facilitando a persistência dos dados.
Lembre-se sempre que programar é uma “arte moderna” em que aquele que detém o
maior poder de abstração possível é aquele que melhor saberá desenvolver os seus pro-
gramas.
Ótima leitura e sucesso em sua vida de desenvolvedor de software.
Prof. Dr. Edson A. Oliveira Junior / Professor Me. André Abdala Noel
09
SUMÁRIO

UNIDADE I

SOBRECARGA E EXCEÇÕES

17 Introdução

18 Sobrecarga de Métodos

18 Exemplos de Sobrecarga

23 Conversões Implícitas

24 Construtores com Sobrecarga

27 Tratamento de Exceções

28 Captura de Exceções

30 Definindo Exceções

31 Hierarquia de Exceções

32 Declaração de Exceções e a Interface Pública

34 Considerações Finais
SUMÁRIO

UNIDADE II

CLASSES ABSTRATAS E INTERFACES

41 Introdução

41 O Que é Classe Abstrata?

43 Modelando um Projeto com Classes Abstratas

44 Implementando um Projeto com Classes Abstratas

50 Regras Sobre Classes e Métodos Abstratos

56 O Que são Interfaces?

56 Características das Interfaces

58 Modelando um Projeto com Interfaces

59 Implementando um Projeto com Interfaces

64 Comparando Interfaces e Classes Abstratas

66 Considerações Finais
11
SUMÁRIO

UNIDADE III

ARRAYS E COLEÇÕES

73 Introdução

73 Entendendo um Array

74 Declarando Arrays de Objetos e de Tipos Primitivos

76 Construindo Arrays Unidimensionais

77 Construindo Arrays Multidimensionais

79 Inicializando Arrays

83 Passando Arrays para Métodos

85 Exemplos com Arrays

92 Visão Geral das Coleções

93 A Interface List

98 A Interface Set

103 A Interface Map

106 A Interface Queue

109 Considerações Finais


SUMÁRIO

UNIDADE IV

INTRODUÇÃO À INTERFACE GRÁFICA

115 Introdução

115 O Que é a Biblioteca Swing?

116 Criando um Projeto no Netbeans Ide

117 Criando um Contêiner Jframe

118 Adicionando Componentes Swing

120 Construindo a Interface

126 Escrevendo o Código

134 Considerações Finais


13
SUMÁRIO

UNIDADE V

PERSISTÊNCIA DE DADOS COM JPA

141 Introdução

142 Jdbc – Java Database Connectivity

142 Drivers Jdbc

143 Conectando a um Sgdb com Connection

148 Executando Instruções Sql com Statement

151 Executando Instruções SQL com Preparedstatement

155 Recuperando e Utilizando Dados de um RESULTSET

158 O Jpa – Java Persistence Api

171 Considerações Finais

190 CONCLUSÃO
191 GABARITO
198 REFERÊNCIAS
199 ANOTAÇÕES
Professor Dr. Edson A. Oliveira Junior
Professor Me. André Abdala Noel

I
UNIDADE
SOBRECARGA E EXCEÇÕES

Objetivos de Aprendizagem
■■ Criar códigos com métodos que utilizam conceitos de sobreposição e
sobrecarga.

Plano de Estudo
A seguir, apresentam-se os tópicos que você estudará nesta unidade:
■■ Sobrecarga de métodos
■■ Exemplos de Sobrecarga
■■ Conversões implícitas
■■ Construtores com sobrecarga
■■ Tratamento de exceções
■■ Captura de Exceções
■■ Definindo Exceções
■■ Hierarquia de Exceções
■■ Declaração de Exceções e Interface Pública
17

INTRODUÇÃO

Caro(a) aluno(a), nesta etapa do nosso treinamento iremos trabalhar o conceito


de sobreposição em Java” por “sobrecarga de métodos. É um conceito simples,
porém com muitos detalhes, detalhes estes que nos farão diferenciar facilmente
uma sobreposição de uma sobrecarga. Para isto é necessário que os conceitos
de herança que já vimos esteja muito claro de agora em diante. Faremos alguns
exemplos práticos e também utilizaremos métodos da classe Object como exem-
plo de uma sobreposição ou reescrita (overriding). Trataremos algumas regras
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

específicas para entender melhor nossa utilização de sobreposição.


Também serão apresentadas técnicas básicas de tratamento de exceções.
Estas ocorrem quando algo imprevisto acontece, elas podem ser provenientes
de erros de lógica ou acesso a recursos que talvez não estejam disponíveis. O tra-
tamento de exceções ajuda a aprimorar a tolerância a falhas de um programa.

Introdução
I

SOBRECARGA DE MÉTODOS

Caro(a) aluno(a), é importante aqui, no início do nosso trabalho com a sobre-


carga, que tenhamos claro as diferenças entre sobreposição e sobrecarga. A
sobreposição, como já vimos, nada mais é do que escrever um método que já
possuímos, sendo possível pelos recursos de herança, já a sobrecarga consiste
no recurso que a linguagem Java nos oferece de escrever métodos com o mesmo
nome, fazendo-se a distinção apenas pelos parâmetros de entrada que obrigato-
riamente precisam ser diferentes.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
O recurso oferecido pela sobrecarga vai nos ajudar muito, pois podemos tra-
balhar métodos com mesmo nome, mas de várias formas diferentes sem perder o
sentido do que o método se propõe a oferecer. Como na figura anterior, imagine
a seguinte situação: seu sistema precisa fazer um cadastro de cliente, em que este
pode tanto ser uma pessoa física como uma pessoa jurídica. Se for pessoa física,
o sistema irá fazer uma validação de CPF no momento em que é preenchido o
cadastro; mas caso nosso cliente seja pessoa jurídica, o sistema irá fazer uma
validação de CNPJ. Tanto o CPF quanto o CNPJ são campos que têm a mesma
função, só que um se refere à pessoa física e a outra a jurídica. Podemos criar
dois métodos com o mesmo nome, mas que possuem parâmetros de entrada
diferente e podemos fazer a chamada do método com o mesmo nome, só que,
em um momento, passaremos um CPF para ser validado e, em outro, passare-
mos um CNPJ para ser validado.

EXEMPLOS DE SOBRECARGA

Caro(a) aluno(a), vejamos, então, alguns exemplos de sobrecarga para enten-


der melhor. Começaremos com um exemplo bem simples. Vamos criar uma
classe chamada ExemplosSobreCarga e, nela, colocar um método chamado
calculaNumeroMaior(). No primeiro momento, nosso método receberá ape-
nas dois parâmetros de entrada, que serão duas variáveis do tipo double, depois

SOBRECARGA E EXCEÇÕES
19

criaremos outro método com o mesmo nome, mas vamos passar três números
para serem verificados dentre os três quem é o maior.
Veja como ficou nossa classe ExemplosSobreCarga():
Quadro 1 - Classe com exemplo de sobrecarga

public class ExemplosSobrecarga {


//criamos aqui a variável maior que será usada na verificação do
// maior número digitado
double maior;
//método que verifica o maior entre dois números digitados
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

public double calculaNumeroMaior(double n1, double n2){


if (n1 == n2){
maior = 0;
}else if(n1 > n2){
maior = n1;
}else if(n2 > n1){
maior = n2;
}
return maior;
}

//método que verifica o maior número entre ter números


digitados
public double calculaNumeroMaior(double n1, double n2, double
n3){
if ( (n1>n2) && (n1>n3) ){
maior = n1;
}else if ( (n2>n1) && (n2>n3) ){
maior = n2;
}else if ( (n3>n1) && (n3>n2) ){
maior = n3;
}else {
maior = 0;
}
return maior;
}
}

Exemplos de Sobrecarga
I

Agora veja como ficou nossa classe TestaSobreCarga:


Quadro 2 - Classe com método main para testar sobrecarga

import javax.swing.JOptionPane;
import main.ExemplosSobrecarga;
public class TestaSobreCarga {
public static void main(String[] args) {
double n1,n2,n3,maior;
//testando o primeiro metodo
n1 = Double.parseDouble(JOptionPane.showInputDialog(

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
"Digite o primeiro numero:"));
n2 = Double.parseDouble(JOptionPane.showInputDialog(
"Digite o segundo numero:"));

ExemplosSobrecarga e1 = new ExemplosSobrecarga();


maior = e1.calculaNumeroMaior(n1, n2);
JOptionPane.showMessageDialog(null,"Maior numero
digitado: "+
maior);

//testando o primeiro segundo metodo


n1 = Double.parseDouble(JOptionPane.showInputDialog(
"Digite o primeiro numero:"));
n2 = Double.parseDouble(JOptionPane.showInputDialog(
"Digite o segundo numero:"));
n3 = Double.parseDouble(JOptionPane.showInputDialog(
"Digite o terceiro numero:"));

ExemplosSobrecarga e2 = new ExemplosSobrecarga();


maior = e2.calculaNumeroMaior(n1, n2, n3);
JOptionPane.showMessageDialog(null,"Maior numero
digitado: "+
maior);
}
}

SOBRECARGA E EXCEÇÕES
21

Executando esse nosso código, podemos ver claramente que temos a utilização
de um método que verifica o maior número, só que de duas formas diferentes:
no primeiro, passamos dois números para serem verificados; no segundo, pas-
samos três números para serem verificados. Os dois métodos contêm o mesmo
nome, mas com parâmetros de entrada diferente. Este é um exemplo bem sim-
ples de sobrecarga.
Caro(a) aluno(a), podemos também perceber que os parâmetros de entrada
podem diferenciar-se somente pelo tipo de dados que estamos passando para o
método. Como exemplo, vamos criar uma classe chamada SegundoExemplo.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Essa classe contém dois métodos chamados retornaDddMascara(); nesse método,


vamos passar primeiro um DDD do tipo int e depois um DDD do tipo string e o
método vai nos retornar somente uma string com o DDD formatado com máscara.
Veja como ficou a classe SegundoExemplo:
Quadro 3 - Classe do segundo exemplo de sobrecarga

public class SegundoExemplo {


// criamos aqui uma string que sera o ddd formatado
String dddComMascara;
//criamos aqui um metodo que retorna o ddd formatado
recebendo
//um DDD to dipo int
String retornaDddMascara(int ddd){
dddComMascara = "(" +ddd+ ")";
return dddComMascara;
}

//criamos aqui um método que retorna o ddd formatado


recebendo
//um DDD to dipo string
String retornaDddMascara(String ddd){
dddComMascara = "(" +ddd+ ")";
return dddComMascara;
}
}

Exemplos de Sobrecarga
I

Agora veja como ficou nossa classe TestaDdd:


Quadro 4 - Classe com método main para testar sobrecarga

import javax.swing.JOptionPane;
public class TestaDdd {
public static void main(String[] args) {
//criamos aqui duas variaveis para ddd uma int oura
string
int ddd;
String strDdd;

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
//vamos ler aqui a variavel ddd que é integer
ddd = Integer.parseInt(JOptionPane.showInputDialog(
"Digite o ddd de sua cidade:") );
//vamos ler aqui a variavel ddd que é string
strDdd = JOptionPane.showInputDialog("Digite o ddd de sua
cidade:");

SegundoExemplo se = new SegundoExemplo();


//vamos imprimir primeiro o ddd int com mascara
JOptionPane.showMessageDialog(null,"DDD int com mascara:
"+
se.retornaDddMascara(ddd));
//vamos imprimir agora o ddd string com mascara
JOptionPane.showMessageDialog(null,"DDD string com
mascara: "+
se.retornaDddMascara(strDdd));
}
}

Portanto, executando nosso código, vamos concluir que podemos criar méto-
dos com mesmo nome e até os nomes dos parâmetros de entrada iguais, nomes
e quantidade, tendo apenas o tipo de dados diferente. Assim como no exemplo
anterior, nós podemos usar o método retornaDddMascara(), passando tanto
um DDD do tipo int como um DDD do tipo String, o sentido de utilização do
método é o mesmo, mas em várias situações no dia a dia de nossa programa-
ção, teremos casos desse gênero, em que um mesmo método que se comporta
da mesma forma pode receber o mesmo valor de entrada só que com tipos de
dados diferentes.

SOBRECARGA E EXCEÇÕES
23

CONVERSÕES IMPLÍCITAS

Caro(a) aluno(a), também é possível usar conversões implícitas em nossos métodos


utilizados na sobrecarga, embora, dependendo da situação, nossos valores fiquem
incorretos. Veja um exemplo: criamos uma classe chamada ConversaoImplicita
e depois criamos outra classe chamada TestaConversaoImplicita, se o valor
passado no argumento for válido pela conversão implícita, o método poderá
ser utilizado sem erro de execução, mas seus valores poderão sofrer alterações,
como podemos ver no exemplo a seguir:
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Quadro 5 - Classe para exemplo de conversão Implícita usada na sobrecarga

public class ConversaoImplicita {


int retornaQuadradoNumero(int numero){
numero = numero * numero;
return numero;
}
}

Agora veja como ficou nossa classe TestaConversaoImplicita:


Quadro 6 - Classe com método main para testar conversão implícita

public class TestaConversaoImplicita {


public static void main(String[] args) {
ConversaoImplicita c1 = new ConversaoImplicita();
JOptionPane.showMessageDialog(null,"Quadrado de 3= " +
c1.retornaQuadradoNumero(3) );
JOptionPane.showMessageDialog(null,"Quadrado de 3= " +
c1.retornaQuadradoNumero(‘3’));
}
}

Conversões Implícitas
I

CONSTRUTORES COM SOBRECARGA

Caro(a) aluno(a), quando falamos de sobrecarga, abre-se um leque muito grande


de recursos que ajudam, e muito, na nossa programação do dia a dia. Um recurso
muito utilizado é usar sobrecarga com o construtor da classe. Veja, sabemos
que o construtor é o primeiro método a ser executado quando instanciamos um
objeto, ou seja, quando nós instanciamos, é executado o da classe. Vamos ver um
exemplo simples do construtor e entender por que faz-se necessário em vários
momentos usarmos sobrecarga no construtor. Vamos criar uma classe chamada

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Cliente com um construtor vazio, veja:
Quadro 7 - Classe para exemplificar construtores sem sobrecarga

public class Cliente {


//criamos aqui um constructor vazio para a classe
public Cliente() {
}
//criamos aqui atributos normais de uma classe Cliente
int codigo;
String nome;
String cpf;
String endereco;
}

Agora vejamos como fica nossa classe que instancia a classe Cliente. Vamos dar
o nome a ela de TestaCliente:
Quadro 8 - Classe com método main para testar construtores sem sobrecarga

public class TestaCliente {


public static void main(String[] args) {
//veja instanciamos um objeto do tipo cliente
//neste momento estamos executando o construtor
// que definimos como vazio
Cliente c1 = new Cliente();
}
}

SOBRECARGA E EXCEÇÕES
25

Caro(a) aluno(a), veja que quando fazemos isso, nossos atributos do objeto c1
estão nulos, ou seja, ainda sem valor; agora, imagine a seguinte situação: se nós,
já no momento em que vamos instanciar o objeto c1, precisarmos passar valo-
res para os atributos, como faríamos isto? É ai que podemos usar a sobrecarga
com os construtores, pois podemos já criar um objeto e iniciar os atributos com
valores já no momento de instanciar. Se usarmos a sobrecarga, podemos ins-
tanciar o objeto das duas formas diferentes, passando valores iniciais ou não
passando valores iniciais.
Veja como ficou nossa classe Cliente:
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Quadro 9 - Classe com construtores usando sobrecarga

public class Cliente {


//criamos aqui atributos normais de uma classe Cliente
int codigo;
String nome;
String cpf;
String endereco;
//criamos aqui um constructor vazio para a classe
public Cliente() {
}
//criamos aqui outro constructor passando valores
//de entrada para inicializar os atributos
public Cliente(int codigo, String nome, String cpf, String
endereco) {
this.codigo = codigo;
this.nome = nome;
this.cpf = cpf;
this.endereco = endereco;
}
}

Construtores com Sobrecarga


I

Agora veja como ficou nossa classe TestaCliente:


Quadro 10 - Classe com método main testando construtores com sobrecarga

import javax.swing.JOptionPane;
public class TestaCliente {
public static void main(String[] args) {
//criamos aqui os atributos a serem lidos
//referente ao cliente 1 e cliente 2
int codigo;
String nome;
String cpf;
String endereco;

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
//aqui lemos os valores dos atributos pelo usuario
//referente ao primeiro cliente
codigo = Integer.parseInt(JOptionPane.
showInputDialog(
"Digite o codigo do primeiro cliente:"));
nome = JOptionPane.showInputDialog(
"Digite o nome do primeiro cliente");
cpf = JOptionPane.showInputDialog(
"Digite o cpf do primeiro cliente");
endereco = JOptionPane.showInputDialog(
"Digite o endereço do primeiro cliente");
//criamos um objeto do tipo cliente e usamos um
//construtor vazio, passamos os valores para
//os atributos depois dele instanciado
Cliente c1 = new Cliente();
c1.codigo = codigo;
c1.nome = nome;
c1.cpf = cpf;
c1.endereco = endereco;
//aqui lemos os valores dos atributos pelo usuaio
//referente ao segundo cliente
codigo = Integer.parseInt(JOptionPane.
showInputDialog(
"Digite o codigo do segundo cliente:"));
nome = JOptionPane.showInputDialog(
"Digite o nome do segundo cliente");
cpf = JOptionPane.showInputDialog(
"Digite o cpf do segundo cliente");
endereco = JOptionPane.showInputDialog(
"Digite o endereço do segundo cliente");
//aqui então instanciamos o objeto passando para
//o construtor os valores dos atributos já neste
//momento
Cliente c2 = new Cliente(codigo,nome,cpf,endereco);
}
}

SOBRECARGA E EXCEÇÕES
27

Caro(a) aluno(a), veja que a sobrecarga em construtores é muito útil e que nos
oferece uma facilidade muito grande para a flexibilidade na utilização de passagem
de valores dos atributos. Muitas vezes, objetos de uma mesma classe necessitam
de serem utilizados de formas diferentes. Em alguns momentos, precisamos pas-
sar valor para os atributos já no momento de instanciar o objeto; já em outros,
não temos essa informação e precisamos passar valores para os atributos depois,
se criarmos somente um construtor que inicializa os atributos quando execu-
tado, ficamos sempre obrigados a passar os valores nesse momento de criação do
objeto; caso usamos a sobrecarga, temos a flexibilidade de utilizar as duas formas.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

TRATAMENTO DE EXCEÇÕES

Quando um evento excepcional ocorre em Java, diz-se que uma exceção será
lançada. O código que é responsável por fazer algo com a exceção é chamado de
manipulador de exceções; ele captura a exceção lançada.
Uma exceção é uma ocorrência que altera o fluxo normal do programa. Ela
pode ocorrer por diversos motivos, incluindo os seguintes:
■■ Um usuário encontrou dados inválidos.
■■ Um arquivo que precisa ser aberto não pode ser encontrado.
■■ A conexão de rede foi perdida no meio de comunicação, ou a JVM está
sem memória.
■■ Falhas no Hardware.
■■ Exaustão de recursos.

Com o tratamento de exceções, um programa pode continuar executando (em


vez de encerrar) depois de lidar com um problema. Isso ajuda a assegurar a
robustez dos aplicativos.

Tratamento de Exceções
I

CAPTURA DE EXCEÇÕES

A manipulação da exceção funciona pela transferência da execução de um pro-


grama para um manipulador de exceções apropriado quando uma exceção
ocorrer. Por exemplo, se você chamar um método que abra um arquivo, mas o
arquivo não puder ser aberto, a execução desse método será encerrada e o código
que foi escrito para lidar com essa situação será processado. Portando, precisa-
mos de uma maneira para informar a JVM (Java Virtual Machine) que código
executar quando uma determinada exceção ocorrer. Para fazer isso, usamos as

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
palavras-chaves try e catch.

TRY / CATCH

Esta é a forma mais usada. O Código dentro de um bloco try / catch é chamado
de código protegidos. Quando uma exceção é capturada, temos de dar trata-
mento à exceção, ou seja, temos de ter um plano de contingência para resolver
o problema que ela significa. Podemos declarar mais do que um bloco catch. Isso
é importante porque podemos ter vários tipos diferentes de exceção sendo lan-
çados e necessitar de um tratamento específico para cada um.

Figura 1 - Implementação da exceção em bloco try/catch

SOBRECARGA E EXCEÇÕES
29

No exemplo da figura anterior, as linhas 18 e 19 constituem a região protegida


que será controlada pela cláusula try. A linha 20 é o manipulador para uma exce-
ção do tipo Exception. Observe que o bloco catch aparece imediatamente após o
bloco try. Isso é um requisito. Se você tiver um ou mais blocos catch, eles devem
aparecer imediatamente após o bloco try. Além disso, todos os blocos catch pre-
cisam ficar um após o outro, sem nenhuma outra instrução ou bloco entre eles.
A ordem na qual os blocos catch forem inseridos também importa.
A execução iniciará na linha 18. Se o programa for processado até a linha
19 sem nenhuma exceção lançada, a execução será transferida para a linha 25,
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

ou seja, no nosso exemplo, fora do bloco try / catch, e continuará daí em diante.
Porém, se entre a linha 18 a 19 (o bloco try) uma exceção do tipo Exception for
lançada, a execução será imediatamente transferida para a linha 21. Em seguida,
as linhas 21 a 23 serão processadas para que todo o bloco catch seja executado e
depois o processamento passará para a linha 25 e dará seguimento ao programa.

USANDO FINALLY

O bloco Finally é usado quando precisamos executar um código mesmo se houver


uma exceção. Por exemplo, se você está escrevendo em um arquivo e acontece um
erro, o arquivo tem que ser fechado mesmo assim. Ou se você está usando uma cone-
xão a banco de dados e acontece algum problema, a conexão tem que ser fechada.

Figura 2 - Implementação da exceção em bloco try/finally

Captura de Exceções
I

DEFININDO EXCEÇÕES

Discutimos as exceções como um conceito. Sabemos que elas são lançadas quando
um problema de algum tipo ocorre e que efeito terá sobre o fluxo de seu pro-
grama. Dissemos que a exceção é uma ocorrência que altera o fluxo normal do
programa. Toda exceção é a instância de uma classe que possui a classe Exception
em sua hierarquia de herança.
Quando uma exceção é lançada, o objeto de um subtipo Exception especí-
fico é instanciado e inserido no manipulador de exceções como um argumento

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
para a cláusula catch. Veja a seguir um exemplo:

Figura 3 - Implementação da exceção em bloco try/catch

Nesse exemplo, é a instância de uma classe chamada resumidamente de


ArrayIndexOutOfBoundsException. Como ocorrência com qualquer outro
objeto, você pode chamar seus métodos.

SOBRECARGA E EXCEÇÕES
31

HIERARQUIA DE EXCEÇÕES

Todas as classes de exceções são subtipos da classe Exception. Essa classe é deri-
vada da classe Throwable (que é derivada da classe Object).
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 4 - Hierarquia de exceções em Java

Java define 2 tipos de exceções:


■■ As exceções verificadas: que herdam da classe Exception. O código do
cliente tem de lidar com as exceções verificadas lançadas pelo API, ou
em uma cláusula try /catch ou encaminhando-o para fora com a cláu-
sula throws.
■■ As Exceções não verificadas: são as RuntimeException que também
se estende de Exception. No entanto, todas as exceções que herdam de
RuntimeException recebem tratamento especial. Não há nenhuma exi-
gência para o código do cliente para lidar com eles, portanto, eles são
chamados de exceções não verificadas (unchecked).

Hierarquia de Exceções
I

Ao decidir sobre exceções verificadas versus exceções não verificadas, pergunte


a si mesmo: “quais medidas o código pode tomar quando a exceção ocorrer?”
Se o cliente conseguir tomar alguma ação alternativa para recuperar a exceção,
essa será uma exceção verificada. Se o cliente não puder fazer nada para contor-
nar a exceção, então essa é uma exceção não verificada.
Observe na imagem anterior que NullPointerException estende de
RuntimeException e, portanto, é uma exceção não verificada.
**Error: não são exceções, mas sim erros que jamais poderiam ter acontecido.
Erros indicam que alguma coisa está realmente muito errada na construção do

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
código ou no ambiente de execução. Ex.: (OutOfMemoryError) quando o pro-
grama precisa de mais memória e (StackOverflowError ) que acontece quando
a pilha estoura, por exemplo, quando um método chama a si mesmo sem nunca
retornar.

DECLARAÇÃO DE EXCEÇÕES E A INTERFACE PÚBLICA

THROWS / THROW:

Como saberemos que um método lançará uma exceção que teremos de capturar?
Da mesma forma que um método precisa especificar que tipo, quantos argu-
mentos aceitará e o que será retornado. As exceções que um método pode lançar
devem ser declaradas (a menos que sejam subclasses de RuntimeException). A
lista de exceções lançadas faz parte da interface pública de um método. A pala-
vra-chave throws é usada na forma descrita, a seguir, para listar exceções que
um método pode lançar:

SOBRECARGA E EXCEÇÕES
33

Figura 5 - Método com exceção throws

Esse método é um tipo de retorno void, que não aceita argumentos e declara
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

que lança exceções do tipo MyException1 e MyException2 (só porque o método


declara que lança uma exceção não significa que sempre o fará. Ele apenas informa
que pode fazê-lo).
O conceito é semelhante ao de return, mas enquanto return está devolvendo
um resultado de dentro do método, throws está lançando uma exceção. Nunca é
possível considerar uma exceção como o resultado de um método, o objetivo do
método é obter resultados sem lançar exceções. Veja, a seguir, um exemplo de
método utilizando o throws e o throw. Vamos explicar a diferença deles.

Figura 6 - Implementação da exceção throw e throws

A Principal diferença entre throw e throws é o uso e a funcionalidade. O throws


é usado na assinatura do método para declarar exceção possivelmente lançadas
por qualquer método; throw é usado para lançar exceção no código Java, acima
está um exemplo de ambos throw e throws.

Declaração de Exceções e a Interface Pública


I

CONSIDERAÇÕES FINAIS

Aproveitamos o exemplo do construtor para trabalharmos o conceito de sobre-


carga, que nada mais é do que ter mais de um método com o mesmo nome, só
que com assinaturas diferentes.
Percebemos que, com esse conteúdo, podemos facilitar nossa programação
e também entender um pouco mais sobre os conceitos de orientação a objetos
utilizada na linguagem Java.
Você aprendeu, também, que a linguagem Java fornece um mecanismo sofis-

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
ticado de manipulação de exceções. A manipulação de exceções permite que
você isole seu código de correção de erros em blocos separados, de modo que o
código principal não fique confuso por causa dele. Outro recurso interessante
permite que você manipule erros semelhantes com um único bloco de manipu-
lações de erros, sem a duplicação de código.
Você aprendeu que a palavra-chave try da linguagem Java é usada para espe-
cificar uma região protegida – um bloco de código no qual os problemas podem
ser detectados. O bloco finally não é obrigatório, mas se houver um terá de vir
após o bloco catch.

SOBRECARGA E EXCEÇÕES
35

1. Crie uma classe chamada ValidaImpostos e nela coloque dois métodos cha-
mados calculaImpostos, só que um método receberá um double valor e
uma String imposto, e o outro método receberá somente uma String im-
posto. O método que recebe apenas a String imposto verifica se o conteúdo
da String é “INSS” ou “IR”. Se for o primeiro, retorna “8”, se for o segundo
retorna “20”. O método que recebe um valor e mais a String imposto calcula
o valor de imposto pelo valor recebido, por exemplo, se chamar o método
calculaImpostos(100.00, ‘INSS’), o retorno será “8.00”.

2. Crie uma classe chamada Fornecedor, adicione os atributos int codigo,


string razaoSocial e coloque dois construtores, um inicializando os atri-
butos e outro vazio, depois crie uma classe TestaFornecedor nela e coloque
dois objetos do tipo Fornecedor, um usando um construtor e o outro objeto
o outro construtor.

3. Dado o código a seguir:

1. System.out.print (“Inicio”);

2. try{

3. System.out.print (“ola_mundo”);

4. throw new FileNotFoundException();

5. }

6. System.out.print (“capturar_aqui”);

7. catch (EOFException e){

8. System.out.print (“fim_da_exceção_do_arquivo”);

9. }

10. catch (FileNotFoundException e){

11. System.out.print (“arquivo_nao_encontrado”);

12. }
Sabendo-se que tanto o EOFException quanto FileNotFoundException são
subclasses de IOException e presumindo que esse bloco de código seja in-
serido em uma classe, que declaração estará mais perto da verdade com re-
lação a esse código?
a. O código não será compilado.

b. Saída do código: Inicio ola_mundo arquivo_nao_encontrado.

c. Saída do código: Inicio ola_mundo fim_da_exceção_do_arquivo.

d. Saída do código: Inicio ola_mundo capturar_aqui arquivo_nao_encon-


trado.

4. Há algo de errado com o manipulador de exceção a seguir? Será que este


código compila?

try {

} catch (Exception e) {

} catch (ArithmeticException a) {

}
MATERIAL COMPLEMENTAR

Sobrecarga e sobreposição em Java


Por javafree.org
Fonte: <http://javafree.uol.com.br/artigo/6947/Cap-5-Orientacao-a-Objetos.html>.

Sobreposição (override) em Java


Fonte: <http://www.youtube.com/watch?v=NSH8CvaJ6Qs>.

Material Complementar
Professor Dr. Edson A. Oliveira Junior

CLASSES ABSTRATAS E

II
UNIDADE
INTERFACES

Objetivos de Aprendizagem
■■ Entender o que é a classe Abstrata.
■■ Entender o que é Interface.

Plano de Estudo
A seguir, apresentam-se os tópicos que você estudará nesta unidade:
■■ O que é classe abstrata
■■ Modelando um projeto com classes abstratas
■■ Implementando um projeto com classes abstratas
■■ Regras sobre classes e métodos abstratos
■■ O que são Interfaces
■■ Modelando um Projeto com Interfaces
■■ Implementando um projeto com Interfaces
■■ Comparando Interfaces e Classes Abstratas
41

INTRODUÇÃO

Caro(a) aluno(a), nesta unidade iremos compreender o que são classes abstra-
tas e interfaces e implementar um simples sistema para cada tópico analisado.
O objetivo é elucidar as dúvidas referentes a esses dois conceitos importantes.
A finalidade de uma classe abstrata é a de funcionar como um modelo para
as subclasses. Ao contrário de interfaces, classes abstratas podem conter campos
(atributos) que não são static e final, e elas podem conter métodos não abs-
tratos implementados. Tais classes abstratas são semelhantes às interfaces, exceto
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

que elas fornecem uma implementação parcial, deixando a subclasses completar


a execução. Se uma classe abstrata contém apenas declarações de métodos abs-
tratos, deve ser declarada como uma interface e não como uma classe abstrata.
As interfaces podem ser implementadas por classes em qualquer lugar na
hierarquia de classe, quer estejam ou não relacionados uns com os outros. Em
comparação, classe abstrata é uma subclasse de classes semelhantes que têm
muito em comum (as partes implementadas da classe abstrata), mas também
tem algumas diferenças (os métodos abstratos).

O QUE É CLASSE ABSTRATA?

Uma classe abstrata é desenvolvida para representar classes e conceitos abstratos.


A classe abstrata é sempre uma superclasse que não permite que nenhum objeto
seja criado a partir dela, ou seja, não pode ser instanciada. O uso das classes abs-
tratas é dirigido para a construção de classes que constituirão um modelo, isto é,
classes abstratas servirão como especificações básicas de novas classes, que serão
implementadas por meio do mecanismo de herança. Assim, uma classe abstrata
deve ser estendida, ou seja, deve ser a classe-base de outra, mais específica, que
contenha os detalhes que não puderam ser incluídos na superclasse (abstrata).
Para formalizar que uma classe seja abstrata, usamos a palavra reservada
abstract antes da palavra reservada class. Vejamos um exemplo:

Introdução
II

Figura 7: Classe Abstrata

Métodos abstratos são declarados com o modificador abstract. Se uma classe


tiver algum método abstrato, a classe também deverá obrigatoriamente ser declarada
com o modificador abstract. Os métodos de uma classe abstrata classificados
como abstratos devem terminar sempre com ; (ponto e vírgula) e a classe que a
estender deverá implementá-los. Vejamos um exemplo de método abstrato:

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 8: Classe Abstrata

Note que esses métodos não têm uma implementação, isto é, não possuem um
corpo delimitado por chaves contendo qualquer código.
Uma classe também pode ser declarada abstrata mesmo que tenha um
método não abstrato, ou a combinação de métodos abstratos e não abstratos.
Veja exemplo abaixo:

Figura 9: Classe Abstrata

Como geralmente as classes abstratas pertencem ao nível superior de uma hierar-


quia de classes, recomenda-se que contenham tanto código quanto for possível,
deixando para suas subclasses apenas as implementações específicas dos méto-
dos abstratos.

CLASSES ABSTRATAS E INTERFACES


43

É importante lembrar que uma classe abstrata que herda de outra classe
abstrata não precisará fornecer implementação de todos os métodos abstratos
herdados.

MODELANDO UM PROJETO COM CLASSES


ABSTRATAS
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Agora que entendemos o que é classe abstrata vamos implementar um simples


sistema de locadora de Dvds e Cds utilizando os mais variados recursos que
as classes abstratas oferecem. Lembrando que o sistema a ser desenvolvido é
meramente instrutivo para que você possa compreender o funcionamento desse
componente importante da linguagem orientada a objetos.
É importante observar que o uso do conceito de classes abstratas precisa
ser modelado nas atividades de aná-
lise e design do projeto, caso contrário,
se usarmos a técnica de codificação
direta, talvez nunca apareça a necessi-
dade de usar esse conceito. O programa,
a seguir, representa a implementação do
diagrama de classe presente na figura
abaixo.
A modelagem acima demonstra uma
árvore de herança com uma classe abs-
trata (ItemAbstrato) e duas concretas
(Dvd e Cds). Observe que tanto a classe
como os métodos abstratos estão repre-
sentados com a fonte em itálico e esse
comportamento representa um padrão
nas modelagens UML.
Figura 10: Diagrama de Classe do sistema de locadora

Modelando um Projeto com Classes Abstratas


II

IMPLEMENTANDO UM PROJETO COM CLASSES


ABSTRATAS

Vamos seguir a modelagem da figura anterior e implementar um sistema sim-


ples de locadora de Dvds e Cds.

CRIANDO A CLASSE ABSTRATA ITEMABSTRATO

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Primeiramente, vamos criar um projeto no NetBeans IDE 7.3 chamado locadora-
Abstrata; desmarque o campo Criar Classe Principal. Em seguida, crie uma classe
nova com o nome ItemAbstrato e coloque como nome do pacote locadora.

Figura 11: Criando a classe ItemAbstrato

Agora que temos nossa classe, insira a palavra abstract antes de class
ItemAbstrato e também os seguintes atributos e métodos abstratos da figura
abaixo após isso gere os respectivos gets e sets dos atributos:

CLASSES ABSTRATAS E INTERFACES


45

Figura 12: Classe abstrata ItemAbstrato


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Observe que nossa classe ItemAbstrato apresenta a definição de uma classe abs-
trata que representa um item de uma locadora. Nessa classe definimos atributos
e métodos comuns a um Dvd, Cd. Como a nossa intenção é analisar o compor-
tamento de classes abstratas não será implementado aqui todos os atributos e
objetos que poderiam existir em uma locadora real, mas sim o elementar para
compreendermos quando devemos usar classes abstratas.

CRIANDO A CLASSE DVD QUE HERDARÁ A CLASSE ITEMABSTRATO

Agora vamos criar outra classe chamada Dvd que irá herdar a classe ItemAbstrato.
Para isso basta acrescentar a palavra-chave extends e logo após o nome da
classe que desejamos herdar os métodos e atributos, no caso, ItemAbstrato. Veja
a figura abaixo como ficou nossa classe:

Figura 13: Classe Dvd

Observe na figura acima que o NetBeans IDE faz uma marcação no nome da classe
Dvd indicando que devemos implementar os métodos da classe pai, ItemAbstrato,

Implementando um Projeto com Classes Abstratas


II

para isso basta posicionar o ponteiro do mouse sobre o nome da classe e pres-
sionar as teclas alt+enter para abrir o menu que implementará todos os métodos
automaticamente ou você pode utilizar o alt+insert e selecionar quais métodos
você deseja implementar. Lembrando que uma classe não é obrigada a imple-
mentar todos os métodos abstratos da classe pai.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 14: Classe Dvd

Após gerar os métodos a nossa classe Dvd ficará igual a figura abaixo:

Figura 15: Classe Dvd

Observe que foi gerado todos os métodos abstratos da classe ItemAbstrato. Caso
o NetBeans IDE gere automaticamente um código para cada método basta ignorá-
-los deletando ou apenas comentando. Note que foi gerado uma anotação acima
dos métodos: @Override. Embora não seja necessário usar esta anotação reco-
mendo que use, pois você terá a vantagem do compilador verificar algum erro
de ortografia e/ou erro na combinação dos parâmetros no método da classe pai
e também tornará seu código mais fácil de ser compreendido.
Agora é necessário implementar o código de cada método. Como o nosso
objetivo é o estudo das classes abstratas aqui, iremos simplificar o código. Veja

CLASSES ABSTRATAS E INTERFACES


47

na figura abaixo o código para cada método.


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 16: Classe Dvd

Implementando um Projeto com Classes Abstratas


II

Observe na figura acima que utilizamos todos os atributos da classe ItemAbstrato


e também implementamos mais dois novos métodos concretos na classe Dvd:
(imprimir( ) e getInstance( )). O método estático getInstance( ) retorna uma
instância da classe Dvd que será utilizada na nossa Classe Principal. Depois fala-
remos mais sobre seu funcionamento.

CRIANDO A CLASSE CD QUE HERDARÁ A CLASSE DVD

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Agora, vamos criar mais uma classe chamada Cds e vamos estender da classe
Dvd conforme pode ser visto na figura abaixo:

Figura 17: Classe Cds

Observe que dessa vez o NetBeans não destacou o nome da Classe forçando a
implementação dos métodos da classe herdada, pois a classe herdada não é uma
classe abstrata como o é a classe ItemAbstrato. Porém, assim como a classe Dvd
que herda diretamente da classe abstrata, a classe Cds passa a poder reutilizar
todos os atributos e métodos da classe ItemAbstrato e Dvd, como também defi-
nir suas particularidades e usá-las.

CLASSES ABSTRATAS E INTERFACES


49

Dessa forma, vamos implementar a classe Cds conforme a figura abaixo:


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 18: Classe Cds

Observe que estamos utilizando métodos da classe ItemAbstrato e também da


classe Dvd além de escrever métodos exclusivos da classe Cds como o método
vender( ) e getInstance( ). A classe Cds herda esses métodos, pois eles são públi-
cos e concretos.

Implementando um Projeto com Classes Abstratas


II

REGRAS SOBRE CLASSES E MÉTODOS ABSTRATOS

Alguns pontos interessantes das imagens acima exemplificam algumas das regras
de criação de classe e métodos abstratos que são:
■■ Os métodos construtores não podem ser declarados como abstratos.
Mesmo que a classe abstrata não possa ser instanciada, seus construtores
podem inicializar os campos da classe que serão usados por subclasses,
sendo imprescindível em praticamente todos os casos.
■■ Métodos declarados como abstratos não podem ser privados (private).

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
■■ Classes abstratas não podem conter métodos estáticos (static).
■■ Os campos de uma classe abstrata serão herdados pelas classes descen-
dentes e poderão ser usados por instâncias destas a não ser que sejam
declarados como private.

CRIANDO A CLASSE PROGRAMA PARA EXECUTAR NOSSO SISTEMA

Para finalizar nosso sistema, vamos criar mais uma classe com o método main
chamada Programa. E nela vamos criar um menu e um método de escolha para
que possamos chamar todos os métodos implementados em nosso exemplo. Veja
na figura abaixo o código dessa classe:

CLASSES ABSTRATAS E INTERFACES


51
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 19: Classe Programa

Explicando o código
Observe que criamos um laço de repetição com o método while( ) sendo
a condição de parada a variável opcao igual a 0. Fizemos uso também da classe
java.util.Scanner que permite a leitura de dados vindos do teclado. Com
o método switch criamos um menu de opções. Cada opção (case) recebe
uma instância da classe fazendo uso do método getInstance( ). Esse método
não cria um objeto toda vez que ele é chamado e se torna ideal para o nosso
exemplo, pois o nosso objetivo é apenas demonstrar o uso e as chamadas dos
métodos abstratos.
Agora que você já implementou o código acima execute o programa e visu-
alize os resultados na saída do NetBeans IDE.

Regras Sobre Classes e Métodos Abstratos


II

run
Digite 0 para SAIR ou a opcao abaixo desejada
1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 1
DVD Cadastrado: - Cod: 1 - Titulo: Senhor dos Aneis - Situacao: L
DVD cadastrado utilizando método abstrato herdado da classe abstrata Item
Abstrato

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Digite 0 para SAIR ou a opcao abaixo desejada:
1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 2
Dvd Emprestado: - Situacao: E - Data Emprestimo: 10/03/2013
DVD Emprestado utilizando método abstrato herdado da classe abstrata Item
Abstrato

Digite 0 para SAIR ou a opcao abaixo desejada:


1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 3
Dvd Devolvido: - Situacao: E - Data Devolucao: 10/03/2013
DVD Devolvido utilizando método abstrato herdado da classe abstrata ItemAbs-
trato

Digite 0 para SAIR ou a opcao abaixo desejada:


1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 4
CD Cadastrado: - Cod: 1 - Titulo: The Best of Joy Division - Situacao: L
Cd Cadastrado utilizando método herdado da classe abstrata ItemAbstrato

CLASSES ABSTRATAS E INTERFACES


53

Digite 0 para SAIR ou a opcao abaixo desejada:


1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 5
CD Vendido utilizando método concreto da classe Cds

Digite 0 para SAIR ou a opcao abaixo desejada:


1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs


Opcao: 6
Impressao da Lista de CDs método herdado da classe Dvds

Digite 0 para SAIR ou a opcao abaixo desejada:


1- Cadastrar DVD 2- Emprestar DVD 3- Devolver DVD
4- Cadastrar CDs 5- Vender CD 6- Imprimir CDs
Opcao: 0

CONSTRUÍDO COM SUCESSO (tempo total: 1 minuto 0 segundos)

Quadro 11: Resultado do Programa

Importante lembrar que o uso de classes abstratas é realizado com classes que tem
métodos e atributos em comum, ou pelo menos a maioria. No nosso exemplo
a mídia DVD possui muito em comum com CDs. Além dos atributos os méto-
dos podem ser utilizados para ambas as classes. O nosso programa de locadora
se limitou a cadastrar e vender os CDs, o que não impediria de colocá-los para
serem alugados assim como os Dvds.

Regras Sobre Classes e Métodos Abstratos


Item 1: Considerando o uso de métodos de fabricação estáticos ao invés de
construtores
A maneira comum de uma classe permitir que um cliente obtenha uma instância
de si próprio é fornecendo um construtor público. Há outra técnica que deve fazer
parte do kit de ferramentas de qualquer programador. A classe pode fornecer um
método de fabricação estático público, que é simplesmente um método estático
que retorna uma instância da classe. Aqui está um exemplo com a classe Boolean
(a classe primitiva encaixotada referente ao tipo primitivo boolean). Esse método
converte um valor primitivo boolean em um objeto de referência Boolean:

public static Boolean valueOf (boolean b) {


     voltar b? Boolean.TRUE: Boolean.FALSE;
}

Observe que um método de fabricação estático não é o mesmo que o padrão Fac-
tory Method de Design Patterns [Gamma95, p. 107]. O método de fabricação estáti-
co descrito neste item, não tem equivalente direto com em Design Patterns.
Uma classe pode oferecer a seus clientes métodos de fabricação estáticos ao invés
de, ou além de construtores. O Fornecimento de um método de fabricação estático
em vez de um construtor público apresenta vantagens e desvantagens.
Vantagens (citando o livro):
Uma das vantagens de métodos de fábrica estáticos é que, ao contrário de constru-
tores, eles têm nomes.
Uma segunda vantagem de métodos de fabricação estáticos é que, ao contrário
de construtores, eles não são obrigados a criar um novo objeto sempre que são
chamados.
Uma terceira vantagem de métodos de fabricação estáticos é que, diferente dos
construtores, eles podem retornar um objeto de qualquer subtipo do seu tipo de
retorno.
A quarta vantagem dos métodos de fabricação estáticos é que eles reduzem a ver-
bosidade na criação de instâncias de tipo parametrizadas.
55

Desvantagens (ainda citando o livro):


A principal desvantagem do fornecimento exclusivo de métodos de fabricação es-
táticos é que as classes, sem construtores públicos ou protegidos, não podem ter
subclasse.
Uma segunda desvantagem dos métodos de fabricação estáticos é que não é possí-
vel distingui-los imediatamente de outros métodos estáticos.
getInstance – retorna uma instância que é descrita pelos parâmetros, mas não temos
como saber se tem o mesmo valor. No caso de um singleton, getInstace não usa
parâmetros e retorna somente a instância.
Fonte: Effective Java – Segunda Edição Joshua Bloch.
II

O QUE SÃO INTERFACES?

Há uma série de situações em engenharia de software onde é importante para


diferentes grupos de programadores concordarem com um “contrato” que expõe
a forma como o software vai interagir. Cada grupo deve ser capaz de escrever o
seu código, sem qualquer conhecimento de como o código do outro grupo está
escrito. De um modo geral isso se aplica ao importante componente da orienta-
ção a objetos conhecido por interfaces.
Interface é um recurso da orientação a objeto utilizado em Java que define

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
ações que devem ser obrigatoriamente executadas, mas que cada classe pode
executar de forma diferente.
Na linguagem de programação Java, uma interface é um tipo de referên-
cia, semelhante a uma classe, que pode conter apenas constante, assinaturas de
métodos e tipos aninhados. Não há corpo de método. Interfaces não podem
ser instanciadas, elas só podem ser implementadas por classes ou prorrogado
por outras interfaces. E por que isso? Isso se deve ao fato de que muitos objetos
(classes) podem possuir a mesma ação (método), porém, podem executá-la de
maneira diferente.
Usando um exemplo bem remoto, podemos ter uma interface chamada
marinho que possui a assinatura do método nadar( ). Ou seja, toda classe
que implementar marinho deve dizer como nadar(). Portanto, se eu tenho
uma classe chamada pessoa e outra chamada peixe, ambas implementando a
interface marinho, então, nestas duas classes devemos codificar a forma como
cada um irá nadar( ).

CARACTERÍSTICAS DAS INTERFACES

Uma interface tem as seguintes características:


■■ Uma interface não pode ser instanciada, mas podem ser definidos refe-
rências do seu tipo. Vejamos um exemplo:

CLASSES ABSTRATAS E INTERFACES


57

Figura 20: Interface

Nesse exemplo não executamos o operador new, por isto temos apenas uma
referência.
■■ Todos os métodos definidos são implicitamente do tipo public ou abs-
tract. Por essa razão, ao declarar um método em uma interface, não é
necessário fornecer a palavra-chave public. Os métodos não podem
ter corpo definido, somente definimos sua assinatura.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 21: Interface

■■ Uma interface pode estender mais de uma interface. É importante lem-


brar que uma classe pode estender somente de uma outra classe.

Figura 22: Interface

■■ A classe que implementa uma interface deve obrigatoriamente implemen-


tar todos os métodos definidos na interface.
■■ Uma interface é formalmente uma classe abstrata, somente com atributos
constantes (final) e estáticos (static) e métodos sem corpo. Estes
deverão ser implementados pelas classes que irão implementar a inter-
face. É importante observar que os atributos na interface precisam ser
inicializados. Vejamos um exemplo na figura abaixo:

Características das Interfaces


II

Figura 23: Interface

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
MODELANDO UM PROJETO COM INTERFACES

Após compreendermos sobre interfaces e seu comportamento vamos imple-


mentar um simples sistema de cadastro de Blu-Rays, utilizando a interface como
principal recurso.
As interfaces são um conjunto de ope-
rações que definem os serviços de uma
classe ou de um componente. No nosso
caso as interfaces existirão apenas na
classe. Segue abaixo o diagrama de classe
do nosso projeto de cadastro de Blu-Rays.

Figura 24: Diagrama de Classe do Sistema cadastro de Blu-Ray

A figura acima mostra as características básicas para representar Interfaces. A


linha tracejada e com uma ponta de flecha vazada demonstra que a classe Bluray
implementa a interface. Outra forma de mostrar que uma classe implementa uma
interface é desenhar uma linha com um círculo em uma das extremidades com

CLASSES ABSTRATAS E INTERFACES


59

o nome dessa interface. As interfaces e seus métodos sempre são abstratos em


Java. Estranhamente, ambos não aprecem em itálico, como ocorre com as clas-
ses abstratas e os métodos abstratos em classes.

IMPLEMENTANDO UM PROJETO COM INTERFACES


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Vamos seguir a modelagem da figura anterior e implementar um sistema de ven-


das de Blu-Rays.

CRIANDO A CLASSE ITEMBLURAY

Primeiramente, vamos criar um projeto no NetBeans IDE 7.3 chamado blu-


rayInterface; desmarque o campo Criar Classe Principal. Em seguida, crie
uma classe nova com o nome ItemBluRay e coloque como nome do pacote
blurayInterface.
Na classe ItemBluRay vamos criar dois atributos e implementar os métodos
gets e sets conforme pode ser visualizado na figura abaixo:

Figura 25: Classe ItemBluRay

Implementando um Projeto com Interfaces


II

Essa classe será o nosso objeto para armazenarmos os dados salvos em nosso
cadastro.

CRIANDO A INTERFACE INTERFACEBLURAY

Para criar uma interface no NetBeans IDE basta clicar com o botão direito do
mouse sobre o pacote do projeto e no menu escolher Novo > Interface Java... e
adicionar InterfaceBluRay como nome da Interface e clique em Finalizar.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 26: Interface InterfaceBluRay

Nessa interface vamos criar um atributo estático e dois métodos conforme a


figura abaixo:

Figura 27: Interface InterfaceBluRay

Observe que estamos utilizando um atributo do tipo final e static. A instru-


ção final indica que a classe, método ou variável assim declarada tem uma única
atribuição que se mantém constante, ou seja, não pode ser alterada no decorrer
do processamento. A instrução static é utilizada para se criar uma variável que
poderá ser acessada por todas as instâncias de objetos desta classe como uma vari-
ável comum. No nosso exemplo atribuímos para a variável estática PROMOCAO
o valor de 20, e essa variável será responsável por gerar o desconto em nosso sis-
tema. A vantagem em ter um atributo estático e final é que ao alterar a variável

CLASSES ABSTRATAS E INTERFACES


61

estática, todo o sistema receberá o novo valor atualizado.


Observe que os métodos estão sem os modificadores de acesso public, e
conforme já apresentado anteriormente não é necessário declarar os modifica-
dores de acesso, pois todos os métodos e atributos de uma Interface são públicos.

CRIANDO A CLASSE BLURAY E ESTENDENDO A INTERFACE

Agora crie a classe Bluray e acrescente a palavra reservada implements e a


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

nossa interface InterfaceBluRay. Observe na figura abaixo que o NetBeans


IDE destacou a nossa classe para que seja criado todos os métodos exigidos pela
interface. A interface obriga o uso de todos os métodos declarados, porém você
quem decide como implementá-los.

Figura 28: Classe Bluray

Implemente os métodos utilizando o atalho do NetBeans IDE posicionando o


mouse sobre o nome da classe em destaque e pressione alt+enter.

Figura 29: Classe Bluray

Observe que o NetBeans IDE gerou os métodos automaticamente e adicionou


a anotação @override, pois estamos sobrescrevendo os métodos da Interface.
Vamos deletar o código que o NetBeans gerou e escrever as instruções conforme

Implementando um Projeto com Interfaces


II

a figura a seguir:

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 30: Código da Classe Bluray

Nessa classe criamos um vetor de ItemBluray para armazenar os objetos


ItemBluRay e assim obter uma lista. O método adicionarLista( ) recebe
por parâmetro o objeto salvo na classe. Programa que será implementado a
seguir. O método imprimirLista( ) apresenta a relação de BluRay sal-
vos no programa.
Ainda falta um método para realizarmos os cadastros de todos os Blu-Rays.
Como ele não foi implementado na Interface vamos criá-lo diretamente na classe
conforme a figura abaixo:

Figura 31: Método cadastrar da Classe Bluray

O método cadastrarBluRay( ) recebe por parâmetro o objeto ItemBluRay


da classe Programa que será implementado a seguir.

CLASSES ABSTRATAS E INTERFACES


63

CRIANDO A CLASSE PROGRAMA

Para finalizar vamos criar a classe Programa para executar nosso projeto. Confira
na imagem abaixo o código para essa Classe.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 32: Código da Classe Programa

Implementando um Projeto com Interfaces


II

Explicando o código
Observe na linha 16 da classe Programa que criamos uma instância da classe
Bluray, chamada objBluray, lembrando que o termo instância e objeto são
sinônimos. A criação do objeto envolve o operador new( ) que foi o utilizado
no código acima. Em seguida, criamos a variável do tipo ItemBluRay cha-
mado objItem.
Na linha 18 criamos o método while( ) que controla a saída ou perma-
nência no programa e logo em seguida instanciamos a variável do tipo objItem
que será responsável por salvar as informações de cada item de Blu-Ray no

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
objeto Bluray.
Utilizamos também a classe Scanner( ) para adquirir todas opções do
menu digitadas pelo usuário.
Observe que por meio do objeto objBluray temos acesso a todos os méto-
dos da classe Bluray. E na linha 40 fazemos uso, pela primeira vez, do atributo
estático que criamos na InterfaceBluRay, lembra? Na linha 41 aproveita-
mos esse recurso para realizar um cálculo de desconto ao cadastrar o Blu-Ray.
Na nossa interface definimos que o valor do desconto seria de 20%. Caso um
dia o desconto mude, basta alterar o valor da variável estática e todos os progra-
mas que fazem uso dela serão atualizados automaticamente.
Pronto! Agora é só executar o programa e visualizar os resultados.

COMPARANDO INTERFACES E CLASSES ABSTRATAS

Se você leu a seção sobre classes abstratas, talvez esteja se perguntando por que
os projetistas da linguagem Java se deram ao trabalho de introduzir o conceito
de interfaces? Por que a interface que criamos InterfaceBluRay não pode
ser simplesmente uma classe abstrata?
Há, infelizmente, um sério problema com o uso de uma classe básica abs-
trata para expressar uma propriedade genérica. Uma classe só pode estender
uma única classe. Suponha que a classe Bluray já estenda uma classe diferente,

CLASSES ABSTRATAS E INTERFACES


65

digamos Midia. Ela então, não poderá estender uma segunda classe. Mas cada
classe pode implementar quantas interfaces quiser.
Outras linguagens de programação, especialmente o C++, permitem que
uma classe tenha mais de uma superclasse. Esse recurso é chamado de Herança
Múltipla. Os projetistas do Java optaram por não dar suporte à herança múlti-
pla, porque ela torna a linguagem muito complexa (como no C++).
Ao invés disso, as interfaces suportam a maioria dos benefícios da herança
múltipla e, ao mesmo tempo, evitam as complexidades e ineficiências.
Abaixo um quadro comparativo para tornar mais fácil a compreensão entre
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

diferenças e similaridades entre Classes Abstratas e Interfaces.

CARACTERÍSTICA INTERFACE CLASSE ABSTRATA


Herança Uma classe pode implementar Uma classe pode herdar somente
múltipla diversas interfaces. uma classe.
Uma classe abstrata pode for-
Uma interface não pode conter necer código completo, código
Implementação
qualquer tipo de código, muito padrão ou ter apenas a decla-
Padrão
menos código padrão. ração de seu esqueleto para ser
posteriormente sobrescrita.
Suporta somente constantes Pode conter constantes estáticas
Constantes
do tipo estática. e de instância.
Uma implementação de uma Uma classe de terceiros precisa
Componentes
interface pode ser incluída a ser reescrita para estender so-
de terceiros
qualquer classe de terceiros. mente a partir da classe abstrata.
Se as várias implementações são
Se todas as diversas imple-
todas do tipo e compartilham um
mentações compartilham a
Homogeneidade comportamento e status comum,
assinatura do método então a
então a classe abstrata funciona
interface funciona melhor.
melhor.
Se o código do seu cliente
conversa somente em termos
de uma interface, você pode
Manutenção Idêntico.
facilmente alterar a implemen-
tação concreta usando um
método factory.
Lento, requer trabalho extra
Velocidade para encontrar o método cor- Rápido.
respondente na classe atual.

Comparando Interfaces e Classes Abstratas


II

Você pode pôr código compar-


Todas as declarações de cons- tilhado em uma classe abstrata.
tantes em uma interface são Você pode usar código para
Clareza
presumidamente públicas ou computar o valor inicial de suas
estáticas. constantes e variáveis de instân-
cia ou estáticas.
Se você incluir um novo mé- Se você incluir um novo método
Funcionalidades todo em uma interface você em uma classe abstrata você tem
Adicionais precisa ajustar todas as imple- a opção de fornecer uma imple-
mentações da interface. mentação padrão para ele.
Quadro 12: Comparativo entre classe abstrata e Interface

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
CONSIDERAÇÕES FINAIS

Nesta unidade você aprendeu duas estruturas muito importante da orientação a


objetos. Viu que classes abstratas podem conter tanto métodos abstratos quanto
não abstratos, mas que se ao menos um deles for marcado com abstract, a classe
também terá de ser abstrata. Não esqueça que a subclasse concreta (não abstrata)
de uma classe abstrata terá de fornecer implementações de todos os métodos abs-
tratos da superclasse, mas que uma classe abstrata não tem de implementar os
métodos abstratos de sua super classe. Viu também, que uma classe abstrata nunca
poderá ser instanciada em sua única finalidade, missão de vida, é ser estendida.
Além disso, abordamos a implementação de interfaces. Aqui você apren-
deu que as interfaces podem estender outra interface (até mesmo várias) e que
qualquer classe que implementar uma interface terá de implementar os méto-
dos de todas as interfaces existentes na árvore de herança da interface que estiver
sendo implementada.

CLASSES ABSTRATAS E INTERFACES


67

1. Dado o código a seguir:


1. abstract class Automovel {
2. abstract short metodo1 () ;
3. short metodo2() { return (short) 420; }
4. }
5.
6. abstract class MiniCarro extends Automovel {
7. // codigo faltando?
8. short metodo1() { return (short) 42; }
9. }

Três das declarações abaixo são verdadeiras. Quais? (selecione três).


a) O código será compilado sem alterações.
b) A classe MiniCarro criará uma declaração abstract do metodo2() ou implemen-
tará esse método para permitir que o código seja compliado.
c) É válido, mas não necessário, que a classe MiniCarro crie uma declaração abs-
trata do método metodo2() ou implemente esse método para permitir que o
código seja compilado.
d) Já que a linha 8 existe, a classe Automovel deve declarar o método metodo1()
de alguma maneira.
e) Se a linha 6 fosse substituída por “MiniCarro extends Automovel { “ o código
seria compilado.
f ) Se a classe Automovel não fosse abstrata e o método metodo1() da linha 2 fosse
implementado, o código não seria compilado.
2. Marque somente as verdadeiras:
( ) Toda classe que possui um método abstrato é obrigatoriamente uma classe
abstrata.
( ) Uma classe abstrata pode ter métodos não abstratos (não marcados com a pa-
lavra-chave abstract).
( ) Para se evitar erros de compilação, todo método de uma interface necessita ser
marcado com a palavra-chave abstract.
( ) Tanto classes abstratas quanto interfaces necessitam possuir um método ou
variável.
( ) Uma classe não abstrata que herda de uma classe abstrata obrigatoriamente
deve implementar todos seus métodos herdados.
3. Três das opções são assinaturas de métodos válidos em uma interface. Quais?
(selecione três).
a) private int getArea( );
b) public float getVolume(float x);
c) public void main (String[ ] args);
d) public static void main (String [ ] args);
e) boolean setFlag (Boolean [ ] test [ ]);

4. O que está errado com a seguinte interface?

public interface Curso {


void metodo(int nota) {
System.out.println("Nota máxima");
}
}
MATERIAL COMPLEMENTAR

Quando houver a possibilidade de reutilização de código, prefira classe abs-


trata. Se o código reaproveitado é muito pequeno, talvez seja mais interes-
sante uma interface.

Interfaces x Classes Abstratas


Por Luiz Agnelo C. Maia
Com o início do paradigma de desenvolvimento OO, alguns termos se tornam corriqueiros no
mundo de programadores e analistas de sistema. Classes, herança, polimorfismo são alguns
destes termos.
Saiba mais sobre o assunto no artigo completo.
Fonte: <http://www.devmedia.com.br/interfaces-x-classes-abstratas/13337>. Acesso em: 03 abr.
2013.

Classes Abstratas
Fonte: <http://www.youtube.com/watch?v=DyrztWb8Ok0>.

Material Complementar
Professor Dr. Edson A. Oliveira Junior

III
UNIDADE
ARRAYS E COLEÇÕES

Objetivos de Aprendizagem
■■ Criar códigos que declarem, inicializem e utilizem arrays.
■■ Estudar algumas das principais Interfaces e Classes do Framework
Collections.

Plano de Estudo
A seguir, apresentam-se os tópicos que você estudará nesta unidade:
■■ Entendendo um Array
■■ Declarando Array de Objetos e de Tipos Primitivos
■■ Construindo Arrays Unidimensionais
■■ Construindo Arrays Multidimensionais
■■ Inicializando Arrays
■■ Passando Arrays para métodos
■■ Exemplos com Arrays
■■ Visão geral das Coleções
■■ A Interface List
■■ A Interface Set
■■ A Interface Map
■■ A Interface Queue
73

INTRODUÇÃO

Caro(a) aluno(a), esta unidade irá abordar dois assuntos fundamentais no que
se refere à estrutura de dados, Arrays e Coleções.
Arrays são estruturas estáticas que consistem em itens de dados de um mesmo
tipo, ou seja, são objetos que armazenam diversas variáveis de um mesmo tipo
primitivo ou de referência a outros objetos. Uma vez criado, um Array mantêm
o mesmo tamanho, por isso são chamados de estáticos, embora seja possível atri-
buí-lo por referência a outro Array de tamanho diferente.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Coleções são estruturas que permitem armazenar outros objetos, em que o


desenvolvedor as utiliza sem se preocupar como essas estruturas foram criadas.
Uma coleção possui interfaces, como listas (List), conjuntos (Sets), mapas (Maps)
e filas (Queues), entre outras, que definem as operações que um programa pode
executar sobre cada tipo de coleção, por exemplo, adicionar e remover objetos à
coleção; verificar se um objeto está na coleção; recuperar um objeto da coleção
sem removê-lo; iterar pela coleção, examinando cada elemento um após o outro.

ENTENDENDO UM ARRAY

Para entendermos melhor a estrutura de um Array, devemos pensar nele como


um grupo de posições na memória, um imediatamente após o outro, que pos-
suem o mesmo nome e o mesmo tipo de dado. Quando precisamos localizar
algum elemento deste Array, utilizamos o nome declarado para o mesmo, assim
como o número, ou índice, ou ainda, subscrito da posição que queremos acessar.
A imagem, a seguir, mostra um Array de 6 elementos com números intei-
ros para o qual demos o nome de meuArray. Para fazermos referência a uma
posição específica deste Array, devemos fornecer o nome do Array seguido pelo
índice da posição entre colchetes ( [ ] ). Note, caro(a) aluno(a), que o primeiro
elemento do Array possui o número de posição zero (meuArray [ 0 ]),
as vezes chamado de zero-ézimo elemento, ou seja, não devemos relacionar a

Introdução
III

primeira posição de um Array com a posição um, a partir deste momento você
deve ter em mente que o primeiro elemento do Array meu meuArray é meuAr-
ray [ 0 ], o segundo elemento do Array meu meuArray é meuArray
[ 1 ], o quinto elemento do Array meu meuArray é meuArray [ 4 ].
Para fixar melhor esta regra, adote a seguinte expressão: o i-ésimo elemento do
Array meuArray é meuArray [
i - 1 ].

©Fonte: o autor
Se recordarmos a introdução
desta unidade e analisarmos melhor

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
o Array meuArray, podemos notar
que esse Array possui 6 elementos
(meuArray [ 0 ] com valor -45,
meuArray [ 1 ] com valor 6,
meuArray [ 2 ] com valor 0, ...,
meuArray [ 5 ] com valor -4)
onde todos são do mesmo tipo, isso
significa que todos os Arrays em Java
conhecem seu próprio tamanho. Esta
informação pode ser acessada por
Figura 33: Um Array de 6 elementos
meio da variável length. Portanto, para
recuperar o tamanho do Array meuArray, devemos usar a expressão meuAr-
ray.length.

DECLARANDO ARRAYS DE OBJETOS E DE TIPOS


PRIMITIVOS

Em Java, os Arrays são declarados mediante a descrição do tipo de dado arma-


zenado seguido de colchetes à direita ou à esquerda do identificador.
O código, a seguir, mostra declarações válidas e inválidas de Arrays de tipo
primitivo.

ARRAYS E COLEÇÕES
75

long [] id; // neste exemplo os colchetes foram definidos antes do


nome (válido e recomendado)
int sequencia[]; // neste exemplo os colchetes foram definido
depois do nome (válido, mas menos legível)
[] double valor; //neste exemplo os colchetes foram definidos no
início da declaração do Array (inválido)

Quadro 13: Declarações válidas e inválidas de Arrays

O código, a seguir, mostra declarações válidas e inválidas de referência a objetos.


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

String[] nomes; // neste exemplo os colchetes foram definidos


antes do nome (válido e recomendado)
Thread threads[]; // neste exemplo os colchetes foram definido
depois do nome (válido, mas menos legível)
[] Thread threads; //neste exemplo os conchetes foram definidos no
início da declaração do array (inválido)

Quadro 14: Declarações válidas e inválidas de referência a objetos

Analisando os códigos anteriores, é interessante quando que for declarar uma


variável de referência a um Array, procure definir os colchetes imediantamente
após a declaração do tipo e não após o identificador. Ambas as situações são
válidas, no entanto fica mais legível para quem for ler seu código, perceber de
maneira fácil, que id é uma variável de referência do objeto Array do tipo long e
não um tipo primitivo de long.
Note que até o momento, vimos apenas declarações de Arrays Unidimensionais,
no entanto, podemos criar Arrays Multidimensionais, que nada mais é que um
Array com outros Arrays armazenados. Veja o código a seguir.

String[][][] ocupantePoltronas; //válido e recomendado


String[] aniversariantesMes[]; //deselegante, porém válido
[][] String cardapioSemana; //inválido

Quadro 15: Declarações válidas e inválidas de Arrays Multidimensionais

Declarando Arrays de Objetos e de Tipos Primitivos


III

Perceba que o primeiro exemplo se trata de um Array com três dimensões


(Tridimensional – um Array com outros Arrays também armazenando Arrays),
já o segundo, é um Array com duas dimensões (Bidimensional), no entanto um
colchete foi declarado antes do identificador da variável aniversariantes-
Mes e outro logo após. Totalmente válido, porém não é uma maneira correta de
realizar este tipo de declaração.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
CONSTRUINDO ARRAYS UNIDIMENSIONAIS

Dando sequência ao nosso estudo, agora vamos aprender como construir Arrays.
No tópico anterior apenas vimos como realizamos as declarações de Arrays e
as maneiras como estas declarações podem ser feitas da melhor forma possível.
Para que seja possível trabalhar com Arrays precisamos construir, ou melhor,
criar um objeto de Array e a maneira mais simples de alcançarmos este feito é
por meio do operador new. Todo e qualquer Array se trata de um objeto que
ocupa espaço na memória e para o compilador saber quanto espaço alocar você,
caro(a) aluno(a), precisa especificar o tamanho do seu Array na hora da sua cons-
trução. Para alocar 6 elementos para o Array de inteiros meuArray, devemos
usar a seguinte declaração.

//declarando e construindo o array com apenas uma instrução


int[] meuArray = new int[6];
//executando a declaração e construção em etapas separadas
int[] meuArray;
meuArray = new int[6];

Quadro 16: Declarando e construindo Arrays

ARRAYS E COLEÇÕES
77
©Fonte: o autor

No exemplo acima, quando o compilador


executar a instrução new int[6], será
criado um novo objeto na memória con-
tendo 6 elementos com um tipo int de
valor default igual a 0. Agora, preste bem
atenção nesta frase: todo e qualquer Array
alocado na memória possui um valor default
para cada elemento do Array de acordo
Figura 34: Um Array Unidimensional na pilha com o tipo do elemento. Para variáveis
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

numéricas do tipo primitivo, será atribuído o valor 0, false para variáveis


boolean ou null para qualquer tipo não primitivo. Veja, a seguir, uma ima-
gem que ilustra nosso Array unidimensional meuArray na memória.

CONSTRUINDO ARRAYS MULTIDIMENSIONAIS

Como já vimos anteriormente, um Array multidimensional consiste em um


Array onde cada elemento possui outro Array armazenado. O tipo mais comum
de Array multidimensional é o Array bidimensional que consiste em dois subs-
critos. São utilizados frequentemente para representar tabelas de valores que
consistem em informações organizadas em linhas e colunas. Para identificar
um elemento específico da tabela, devemos utilizar os dois subscritos, no qual
o primeiro representa uma linha do elemento e o segundo representa a coluna.
Portanto, um Array bidimensional do tipo int é um objeto com o tipo de Array
int (int [ ]), onde cada elemento fará referência a outro Array do tipo int.
O código, a seguir, representa a criação de um Array bidimensional com 3
linhas e 4 colunas.

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

Quadro 17: Criando Array Bidimensional com 3 linhas e 4 colunas

Construindo Arrays Multidimensionais


III

©Fonte: o autor
Uma representação do Array
criado no código anterior
pode ser representada na
imagem que segue.
Agora, veremos uma repre-
sentação deste Array alocado
Figura 35: Representação de um Array Bidimensional com 3 linhas e 4 colunas
na memória.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
©Fonte: o autor

Figura 36: Um Array Bidimensional na pilha

Nos exemplos anteriores vimos como criar um Array bidimensional definindo


os valores literais 3 e 4 para especificar o número de linhas e o número de colu-
nas, respectivamente. Nessa situação, caro(a) aluno(a), você se pergunta: seria
possível definir para cada linha um número de colunas diferente, por exemplo,
para linha 1 definir 2 colunas e para a linha 2 definir 3 colunas? Nós te respon-
demos: claro que sim. Note o exemplo a seguir.

ARRAYS E COLEÇÕES
79

int[][] a;
a = new int[2][]; //aloca linhas
a[0] = new int[5]; //aloca 5 colunas para a linha 0
a[1] = new int[3]; //aloca 3 colunas para a linha 1

Quadro 18: Alocando colunas para linhas de um Array

©Fonte: o autor
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 37: Um Array com 2 linhas, onde uma contém 5 colunas e a outra 3 colunas

Agora, perceba como ficaria uma representação deste Array.


Perceba também este mesmo Array alocado
na memória.
©Fonte: o autor

INICIALIZANDO ARRAYS

Nos estudos anteriores o que fizemos


até então foi simplesmente declarar e
construir Arrays unidimensionais e mul-
tidimensionais. A partir de agora, vamos
aprender como inicializar um Array, ou
seja, inserir itens nele, seja com valores Figura 38: Representação do Array da Figura 31 na pilha

primitivos (5,’y’,true e outros) ou com objetos citados pelas variáveis de referên-


cia do Array. É muito importante ressaltar que quando dizemos que um Array
foi inicializado com um objeto, não signfica que o objeto propriamente dito está
armazenado em um determinado elemento do Array e sim a referência deste

Inicializando Arrays
III

objeto na memória. Lembre-se que quando construímos um Array de referên-


cia a objetos, por padrão, o valor de cada elemento deste Array é null. Portanto,
se o Array não for inicializado adequadamente e tentarmos acessar a referên-
cia null aplicando o operador ponto, você irá receber a famosa exceção java.
lang.NullPointerException.
Como já vimos anteriormente, os elementos de um Array podem ser acessa-
dos por meio de um índice ou subscrito. Vimos também que o primeiro elemento
de um Array é o zero-ésimo elemento, ou seja, um elemento com índice 0. Logo,
sabemos então, que um Array com 7 elementos possuirá índices de 0 a 6. Então,

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
caro(a) aluno(a), o que teríamos de fazer para criar um Array com 4 carros? Sim,
4 carros. Veja a seguir.

Carro[] carros = new Carro[4];

Quadro 19: Criando um Array com referência a 4 objetos de Carro

No código acima, quando o programa for executado, será criado na memória


um Array com o nome carros contendo 4 referências a objetos do tipo Carro.
Lembre-se, o Array ainda não foi inicializado, não temos nenhum objeto Carro
criado, portanto, essas referências são null. O que temos de fazer agora? Vamos
criar 4 objetos do tipo Carro. Veja a seguir.

carros[0] = new Carro();


carros[1] = new Carro();
carros[2] = new Carro();
carros[3] = new Carro();

Quadro 20: Criando 4 objetos de Carro

A partir deste momento temos criados 4 objetos do tipo Carro, onde a refe-
rência de cada objeto na memória foi armazenado em um elemento do Array
carros. Note que para inicializarmos os elementos foram utilizados os índi-
ces de cada elemento, desta maneira, conseguimos acessar elementos específicos
e armazenar a referência de cada novo objeto Carro.

ARRAYS E COLEÇÕES
81

Bem, até aqui tudo perfeito e funcionando corretamente, mas o que acon-
teceria se você tentasse armazenar um novo objeto Carro ao elemento [4] do
Array carros? Ao recordarmos os estudos anteriores, vamos lembrar que a
partir do momento que usamos o operador new para construir um Array, esse
Array passa a conhecer o seu tamanho, portanto, se você tentar acessar um ele-
mento com um índice que não existe, será lançada em tempo de execução a
exceção java.lang.ArrayIndexOutOfBoundsException. A mesma
exceção será lançada se você tentar utilizar um índice com número negativo, ex:
-1. Veja os exemplos a seguir.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

int[] y = new int[3];


y[2] = 7; //Correto, o último elemento está no índice 2
y[3] = 4; //Errado, será gerado uma exceçao em tempo de execução.
Não há nenhum elemento no índice 3.

int[] w = new int[7];


int k = -1;
w[k] = 3; //Exceção, pois k é um número negativo.

Quadro 21: Utilizando índices de um Array

Nos exemplos anteriores, vimos primeiramente como criamos e, em seguida,


inicializamos os elementos de um Array. Agora, vamos aprender como decla-
ramos, construímos e inicializamos um Array em apenas uma linha. Considere
o seguinte exemplo.

long x = 2;
long[] id;
id = new long[3];
id[0] = 1;
id[1] = x;
id[2] = 3;

Quadro 22: Declarando e inicializando Array com várias linhas

O código acima não possui nada de diferente do que vimos até agora. Contudo,
veja o código a seguir.

Inicializando Arrays
III

long x = 2;
long[] id = {1,x,3};

Quadro 23: Declarando e inicializando Array em uma linha

Os dois códigos são equivalentemente funcionais, no entanto o segundo bem


mais curto. Analisando a segunda linha do código acima, podemos notar que
foram executadas quatro operações:
■■ Declaramos uma variável de referência ao Array de long chamada id.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
■■ Criamos um Array de long com tamanho igual a três, ou seja, três elementos.
■■ Atribuimos a estes elementos os valor 1, 2 e 3.
■■ Atribuimos um novo objeto de Array à variável de referência id.

Da mesma maneira que inicializamos em apenas uma linha um Array de tipos


primitivos, também podemos fazer referência a objetos, como mostra o código
a seguir.

Carro fiat = new Carro("fiat");


Carro[] carros = {fiat, new Carro("audi"), new Carro("chevrolet"),
new Carro("ford")};

Quadro 24: Realizando referência a objetos em um Array

Perceba, caro(a) aluno(a), que a inicialização do Array Carro referenciada pela


variável carros é muito semelhante ao exemplo dado anteriormente com tipos
primitivos. Note também que este Array possui um tamanho de quatro elemen-
tos onde ao primeiro elemento foi atribuída uma referência para o objeto fiat
do tipo Carro criado anteriormente. Foram criados também três novos objetos
do tipo Carro (audi, chevrolet e ford) atribuindo, respectivamente,
a referência destes objetos aos três últimos elementos.
Vamos voltar agora lá no início do nosso estudo sobre Arrays. Você lembra
que aprendemos que podemos recuperar o tamanho de uma Array utilizando a
variável length? Então, agora vamos ver um exemplo que utiliza esta variável em
um laço de repetição para inicializarmos nosso Array carros, por exemplo, for.

ARRAYS E COLEÇÕES
83

Carro[] carros = new Carro[6]; //cria um Array de 6 referências a


Carro
for (int i = 0; i < carros.length; i++) {
carros[i] = new Carro(); //atribui um novo elemento Carro a
posiçao de índice i
}

Quadro 25: Inicializando um Array em um laço de repetição


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

PASSANDO ARRAYS PARA MÉTODOS

Para enterdermos melhor a passagem de Arrays para métodos, precisamos abor-


dar um assunto que implica diretamente nessa questão, a passagem de parâmetros
por referência.
A maioria das linguagens de programação, por exemplo, C++, possuem
duas maneiras de passar argumentos para métodos. Uma é a passagem por valor,
também chamadas de chamada por valor e a outra se trata da passagem por refe-
rência também conhecida por chamada por referência.
Quando passamos um argumento por valor, é realizada uma cópia do valor
deste argumento e passado essa cópia para o método chamador. Quando fazemos
uma chamada por referência, na verdade estamos passando para o método cha-
mado, o endereço daquele objeto na memória, ou seja, estamos passando uma
referência desse objeto. Neste caso, o método chamador permite que o método
chamado possa acessar e modificar os dados do chamador se for necessário.
No entanto, Java difere das outras linguagens quando precisamos passar argu-
mentos por valor ou referência. Java não permite que você escolha entre passar
cada argumento por valor ou referência. Quando você trabalha com variáveis
de tipos primitivos, estas sempre serão passadas por valor. Quando falamos de
objeto, estes não são passados para o método e sim a referência desse objeto.
Nesse caso, a referência que é passada por valor, ou seja, é feita uma cópia da

Passando Arrays para Métodos


III

referência do objeto e passado esta cópia para o método chamado, permitindo


assim, por meio da referência, acessar o objeto e manipulá-lo se necessário. No
caso de retornar informações de um método mediante a instrução return, a
regra é praticamente a mesma. Variáveis do tipo de dado primitivo são retor-
nadas por valor, ou seja, devolvida uma cópia cujos objetos são retornados por
referência.
Bem, agora que você aprendeu como os argumentos em Java são passados
para um método, chegou a hora de aplicarmos esse conceito com Arrays. Como
já vimos até agora, Arrays em Java são tratados como objetos, sendo assim, os

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Arrays também são passados para os métodos como referência. Ora, isso sig-
nifica então que também podemos manipular os elementos de um Array? Sim,
podemos, o método chamado pode acessar os elementos dos Arrays originais
do chamador. Para isso, bastar passar para o método chamado o nome do Array
sem colchetes, que na verdade é uma referência para um objeto que contém os
elementos do Array. O exemplo, a seguir, demonstra esta situação.

int[] temperaturaHora = new int[24];


modificarArray(temperaturaHora);

Quadro 26: Passando Arrays para métodos

Note que o método modificarArray recebe como argumento a variável tem-


peraturaHora, sem colchetes, que contém uma referência para um Array de
int de 24 elementos. Para que isso seja possível, o método que recebe o Array
deve conter em sua lista de argumentos um argumento que seja um Array ou
vários, se mais de um Array for recebido pelo método. Veja a seguir, como pode-
mos definir o escopo do método modificarArray.

ARRAYS E COLEÇÕES
85

void modificarArray( int[] a )

Quadro 27: Método esperando um Array como argumento

No código anterior você pôde perceber que o método modificarArray espera


receber no argumento a um Array do tipo int. Neste caso, quando o método
chamado utilizar o Array a, na verdade ele estará se referindo ao Array real no
chamador que é temperaturaHora.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

EXEMPLOS COM ARRAYS

Bem, mãos à obra. Chegou a hora de colocar em prática tudo aquilo que você
aprendeu até agora. Vamos criar exemplos funcionais para aplicar de forma prá-
tica os conceitos estudados até agora.
Como no nosso primeiro exemplo, vamos criar uma classe que declara e
aloca um Array de 10 elementos na memória. Em seguida, vamos recuperar o
valor contido nos elementos desse Array e imprimir em uma janela o índice e
o valor respectivo.

Exemplos com Arrays


III

1
2
3 import javax.swing.*;
4
5 public class Exemplo1 {
6
7 public static void main(String[] args) {
8 int[] array; //declara referência para um
array
9 array = new int[10]; //cria um array com 10 elementos

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
10 String saida = "Índice\tValor\n";
11
12 //adicionando o valor de cada
13 //elemento do Array na variável saida
14 for (int i = 0; i < array.length; i++) {
15 saida += i + "\t" + array[i] + "\n";
16 }
17
18 JTextArea saidaArea = new JTextArea();
19 saidaArea.setText(saida);
20
21 JOptionPane.showMessageDialog(null, saidaArea,
22 "Criando um Array de Inteiros",
23 JOptionPane.INFORMATION_MESSAGE);
24
25 System.exit(0);
26 }
27 }

Quadro 28: Exemplo que apresenta os índices de um Array

Vamos entender o que aconteceu. Note que na linha 8 foi declarada a variá-
vel array capaz de referir-se a um Array de elementos int. Na linha 9, foi
utilizado o operador new para construir o Array e alocar os 10 elementos na
memória. Declaramos também na linha 10 uma variável do tipo String cha-
mada saida, na qual será responsável por armazenar os índices e os valores dos
elementos para, posteriormente, serem exibidos em um diálogo de mensagem.

ARRAYS E COLEÇÕES
87

Nas linhas 14, 15 e 16, utilizamos uma estrutura for para adicionar o índice
e o valor de cada elemento do Array a saida. Note o uso da contagem na vari-
ável i, perceba que a contagem se inicia em zero (nesse momento, você deve
recordar que os índices iniciam em 0 em um Array). Desse modo, o laço irá aces-
sar cada elemento do Array iniciando por 0. Perceba agora o uso da expressão
array.length para recuperar o comprimento do Array. Neste nosso exem-
plo o comprimento do Array é 10 e o laço será executado enquanto a variável
de controle i for menor que 10. Lembre-se que para um Array com 10 elemen-
tos os valores dos índices vão de 0 a 9, portanto, ao utilizarmos o operador
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

menor que, <, garantimos que o laço não irá acessar um elemento além do fim
do Array, evitando assim, um erro e também o lançamento da famosa exceção
java.lang.ArrayIndexOutOfBoundsException. Veja na imagem,
a seguir, o resultado apresentado em um diálogo de mensagem quando execu-
tamos o exemplo que acabamos ver.

Figura 39: Resultado apresentando índice e valores de um Array


Fonte: o autor

Vamos a mais um exemplo? Bem, o nosso segundo exemplo com Arrays será
bem semelhante ao exemplo anterior, a diferença é que agora vamos inicializar
os elementos do Array, apresentar o Array inicializado e, em seguida, vamos
somar os elementos deste Array. Por fim, também vamos apresentar esta soma
em um diálogo de mensagem.

Exemplos com Arrays


III

1
2
3 import javax.swing.JOptionPane;
4 import javax.swing.JTextArea;
5
6 public class Exemplo2 {
7
8 public static void main(String[] args) {
9 //cria um array com 6 elementos
10 int[] array = {10, 15, 25, 3, 8, 7};
11 int total = 0;

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
12 String saida = "Índice\tValor\n";
13
14 //adicionando o valor de cada
15 //elemento do Array na variável saida
16 for (int i = 0; i < array.length; i++) {
17 total += array[i];
18 saida += i + "\t" + array[i] + "\n";
19 }
20
21 saida += "\n\nA soma dos elementos do array é: " +
total;
22
23 JTextArea saidaArea = new JTextArea();
24 saidaArea.setText(saida);
25
26 JOptionPane.showMessageDialog(null, saidaArea,
27 "Criando um Array de Inteiros",
28 JOptionPane.INFORMATION_MESSAGE);
29
30 System.exit(0);
31 }
32 }

Quadro 29: Somando os elementos de um Array

Você pode notar que o exemplo acima é bem parecido com o primeiro exemplo
que estudamos há pouco. Em nosso primeiro exemplo, nós não inicializamos
o Array. Note que quando executamos o primeiro exemplo, os valores de cada
elemento do Array é zero. No segundo exemplo, não fizemos nada de diferente
do que estudamos até aqui. O que fizemos foi declarar na linha 10 uma variável

ARRAYS E COLEÇÕES
89

array que faz referência a um Array do tipo int, já inicializando este Array com
os valores (10, 15, 25, 3, 8, 7). Quando o programa executar esta linha, automa-
ticamente um Array com 6 elementos será alocado na memória e já inicializado.
Perceba agora, que na linha 11 foi declarada uma variável total do tipo int,
para podermos armazenar nesta variável a soma dos valores dos elementos do
Array. Se analisarmos a linha 17, note que uma soma está sendo realizada nessa
variável com base no valor do elemento. Nesse momento, utilizamos o índice
corrente no laço de repetição for para recuperar o valor do Array por meio da
expressão array[i]. Por fim, atribuimos na variável saida um texto apre-
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

sentando o total da soma. Veja, a seguir, o resultado.

Figura 40: Resultado apresentando índices, valores e a soma dos elementos de um Array
Fonte: o autor

Dando continuidade aos nossos estudos, agora vamos ver um exemplo traba-
lhando com Arrays multidimensionais e passagem de Array por referência. O
exemplo, a seguir, irá demonstrar a inicialização de dois Arrays bidimensionais e
o uso de laços de repetição aninhados (laços aninhados é o mesmo que um laço
sendo executado dentro de outro e assim sussecivamente) for para percorrer
os Arrays. Vamos ao exemplo.

Exemplos com Arrays


III

1 import java.awt.Container;
2 import javax.swing.JApplet;
3 import javax.swing.JTextArea;
4
5 public class Exemplo3 extends JApplet{
6 JTextArea saidaArea;
7
8 @Override
9 public void init() {
10 super.init();
11

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
12 saidaArea = new JTextArea();
13 Container container = getContentPane();
14 container.add(saidaArea);
15
16 int[][] array1 = { {1,2,3}, {4,5,6} };
17 int[][] array2 = { {1,2}, {3}, {4,5,6} };
18
19 saidaArea.setText("Os valores do array1 são\n");
20 buildSaida(array1);
21
22 saidaArea.append("Os valores do array2 são\n");
23 buildSaida(array2);
24 }
25
26 public void buildSaida(int[][] array) {
27 //percorre as linhas do array com um for
28 for (int linha = 0; linha < array.length; linha++) {
29 //percorre as colunas da linha corrente com outro
30for
31 for (int coluna = 0; coluna < array[linha].length;
32 coluna++) {
33 saidaArea.append(array[linha][coluna] + " ");
34 }
35 saidaArea.append("\n");
36 }
37 saidaArea.append("\n");
38 }
39
40 }

Quadro 30: Exemplo de como declarar e inicializar Arrays Multidimensionais

ARRAYS E COLEÇÕES
91

O exemplo acima declara e inicializa dois Arrays bidimensionais. O primeiro


Array referenciado pela variável array1 na linha 18 cria seis elementos em
duas sublistas. Perceba que se trata de um Array com duas linhas e 3 colunas em
que a primeira sublista é inicializada com os valores (1,2,3) e a segunda sublista
com os valores (4,5,6). O segundo Array referenciado pela variável array2 na
linha 19 também fornece seis elementos, porém inicializados em três sublistas
com os valores (1,2), (3) e (4,5,6), respectivamente. Note na linha 22 e 25 as cha-
madas para o método buildSaida, no qual é responsável por percorrer todos
os elementos do Array passado como parâmetro para e apresentar em um diá-
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

logo de mensagem os valores de cada elemento. A mágica neste método é o tipo


do argumento que ele está esperando, que neste caso é um Array bidimensio-
nal do tipo int. Se você retornar ao nosso estudo de passagem de parâmetros
por referência, recordará que um Array nada mais é do que um objeto, portanto,
também pode ser passado por referência. No nosso exemplo, foi passado na pri-
meira chamada do método buildSaida a variável array1 e array2 na
segunda, desta maneira, o método tem a capacidade de percorrer os elementos
dos dois Arrays e apresentar no diálogo de mensagem os valores de cada ele-
mento do Array.
Agora repare o uso do laço de repetição for (linhas 30 e 32) para per-
correr um Array bidimensional. No laço externo for, foi utilizada a expressão
array.lenght para determinar o número de linhas do Array. Para determi-
nar o número de colunas do Array, foi utilizada a expressão array[linha].
lenght para determinar o número de colunas na linha corrente do Array, per-
mitindo assim determinar o número exato de colunas em cada linha. Veja, a
seguir, o resultado da execução do código acima.

Figura 41: Resultado mostrando valores de Arrays Multidimensionais


Fonte: o autor

Exemplos com Arrays


III

VISÃO GERAL DAS COLEÇÕES

No começo do nosso estudo, vimos que Arrays são estruturas que consistem em
itens de dados de um mesmo tipo, seja este primitivo ou de referência a outros
objetos, e que quando precisamos manipular informações de um Array, temos
que criar programas que atendam a essa necessidade. Quando trabalhamos com
estruturas de Coleções, o desenvolvedor não precisa se preocupar como estas
estruturas foram criadas e sim qual a Coleção que ele irá utilizar e em que deter-
minada situação se encontra isso, graças às interfaces que a estrutura de Coleções

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
fornece. As interfaces definem várias operações a serem realizadas generica-
mente sobre vários tipos de Coleções minimizando a quantidade de código que
um programador precisa escrever para criar e manipular Coleções.
O conjunto de interfaces e classes de coleções contidos na API Java consti-
tui o chamado Framework Collections que tem por raíz duas interfaces
básicas: Collection, utilizada para manipular coleções onde os elementos
são objetos individuais, e Map, onde se mapeia uma chave única para um valor
específico, por meio de uma estrutura de pares de objetos, no qual um é utli-
zado como chave para acesso.
Veja, a seguir, algumas das principais interfaces fornecidas pelo pacote
java.util.*.
■■ Collection – interface raiz da hierarquia de Coleções a partir da qual se
derivam as interfaces Set e List.
■■ Set – dá relevância à exclusividade, ou seja, contém elementos únicos.
■■ List – interface onde o índice tem relevância. Esta interface possui diversas
operações relacionadas ao índice que outras interfaces não list não têm.
■■ Map – diz respeito a identificadores únicos, onde se mapeia uma única
chave para um determinado valor. Para os Maps são associados chaves e
valores onde estas não podem ser duplicadas, ou seja, cada chave pode
mapear somente um valor.

ARRAYS E COLEÇÕES
93

■■ Queue – o mesmo que fila. Geralmente utilizada para se manter uma lista
de execuções a serem processadas. A ela se atribui o conceito de FIFO (first
in, first out. Que em português significa primeiro a entrar, primeiro a sair).

Veja, a seguir, uma representação da hierarquia de interfaces e classes para


coleções.

©Fonte: o autor
<<interface>>
Collection

<<interface>> <<interface>> <<interface>>


Set List Queue
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

<<interface>>
SortedSet

ArrayList Vector LinkedList PriorityQueue

<<interface>>
HashSet <<interface>>
NavigableSet
Map

<<interface>>
SortedMap
LinkedHashSet TreeSet

<<interface>>
Hashtable HashMap
NavigableMap
Object

LinkedHashMap TreeMap
Arrays Collections

Hierarquia de interfaces e classes para coleções


Implementa
Pacote java.util.*
Estende
Figura 42: Representação do pacote java.util.*
A INTERFACE LIST

Também chamada de sequência, a interface List é uma Collection que


permite elementos duplicados de maneira ordenada, onde o programador tem
controle preciso sobre onde o elemento está inserido na lista. Assim como os
Arrays, essa interface também á baseada em índice, onde o primeiro elemento

A Interface List
III

da lista é zero. Uma das vantagens que uma coleção list possui sobre as cole-
ções não list é a grande variedade de métodos relacionados com índices, como
o get(int index), indexOf(Object o), add(int index, Object obj), entre outros. A
interface List possui três classes que a implementa: ArrayList, LinkedList
e Vector. A seguir, vamos estudar a classe mais utilizada entre as três, estamos
falando da classe ArrayList.
Quando falamos de ArrayList, devemos considerar esse conjunto como um
Array redimensionável, isto é, que pode crescer. Pois além de implementar a
interface List, essa classe fornece métodos que permitem manipular o tamanho

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
da matriz que á usada internamente para armazenar a lista. Cada instância de
uma ArrayList possui uma capacidade que define o tamanho da matriz usada
para armazenar os elementos da lista. Quando adicionamos um elemento a uma
ArrayList, sua capacidade aumenta automaticamente. A seguir, vamos ver um
exemplo de como se usa um ArrayList que contenha uma lista de frutas.

1import java.util.ArrayList;
2 import java.util.List;
3 import javax.swing.JOptionPane;
4 import javax.swing.JTextArea;
5
6 public class Exemplo4 {
7 public static void main(String[] args) {
8 List<String> listaFrutas = new ArrayList<String>();
9 String s = "uva";
10 listaFrutas.add("melancia");
11 listaFrutas.add(s);
12 listaFrutas.add("caju");
13
14 String saida = "";
15 saida += "Frutas da Lista: "+
16 listaFrutas.toString();
17 saida += "\nTotal de Frutas na lista: "+
28 listaFrutas.size();
29 saida += "\nA lista possui pera? "+
20 listaFrutas.contains("pera");
21 saida += "\nA lista possui caju? "+
22 listaFrutas.contains("caju");

ARRAYS E COLEÇÕES
95

23 listaFrutas.remove("uva");
24
25 saida += "\nTotal de Frutas na lista "
26 + "apos remover uva: "+listaFrutas.size();
27 saida += "\nFrutas da Lista "
28 + "apos remover uva: "+listaFrutas.toString();
29 saida += "\nÍndice da Fruta "
30 + "caju na lista: "+listaFrutas.
31 indexOf("caju");
32
33 JTextArea saidaArea = new JTextArea();
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

34 saidaArea.setText(saida);
35
36 JOptionPane.showMessageDialog(null, saidaArea,
37 "Trabalhando com ArrayList",
38 JOptionPane.INFORMATION_MESSAGE);
39
40 System.exit(0);
41 }
42 }

Quadro 31: Criando um ArrayList

Perceba que este pequeno programa executou vários controles relacionados com
a ArrayList. Bem, caro(a) aluno(a), vamos entender o que acontece então? Se
você recordar ao nosso estudo sobre Arrays, sempre que precisávamos alocar um
Array na memória com o operador new era necessário definir o tamanho deste
Array assim como o seu tipo de dado (primitivo ou referenciando um objeto),
por exemplo, int[] meuArray = new int[6];. Perceba que quando
declaramos nosso ArrayList na linha 10, não demos a ele um tamanho e, mesmo
assim, conseguimos pedir para o ArrayList nos informar seu tamanho na linha
19 por meio do método listaFruta.size(), isso, graças à capacidade que
o ArrayList tem de definir o seu tamanho automaticamente quando adiciona-
mos ou removemos um objeto da lista como foi feito na linha 26. Note que ao
consultarmos novamente o tamanho da lista na linha 28, o ArrayList foi capaz
de nos informar esse novo tamanho sem a necessidade de você, caro(a) aluno(a),
precisar programar códigos e mais códigos para isso. Perceba agora que utiliza-
mos a sintaxe <String> no nosso ArrayList. Esse tipo de programação segue

A Interface List
III

o princípio da POO (Programação Orientada a Objetos) de “programar para


uma interface” fazendo o uso de genéricos para declarar o tipo de uma coleção.
Não entraremos em detalhes sobre o uso de genéricos neste tópico, por enquanto
basta você saber que essa é a maneira correta de definir tipos em coleções. Bem,
vamos continuar nossa análise.
Outro ponto interessante neste programa é que pudemos perguntar para o
ArrayList se ele possuía determinadas frutas na lista por meio do método lis-
taFrutas.contains(). Agora, por favor, pare e pense. Como você faria
isso com um Array? Provavelmente, você criaria um laço de repetição for, e

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
com base no tamanho do seu Array, você percorreria esse Array, verificando ele-
mento por elemento por meio do índice. Trabalhoso, não? Note que você seguiria
a mesma ideia se precisasse recuperar o índice de uma determinada fruta se
estivesse trabalhando com Array. No nosso exemplo acima, simplesmente uti-
lizamos o método listaFrutas.indexOf(), como mostra a linha 33 do
nosso programa. Veja, a seguir, o resultado no nosso exemplo.

Figura 43: Apresentando informações de um Array


Fonte: o autor

Continuando nossos estudos, agora vamos ver um exemplo que nos mostra
como classificar um ArrayList. Algo bem simples, por exemplo, classificar uma
lista com nomes por ordem alfabética. Certamente, você pensou: “Vou procu-
rar o método sort() na classe ArrayList”. Boa sorte. Essa classe não fornece de
forma alguma uma maneira que permita classificar o seu conteúdo. Mas não
desanime, para isso vamos utilizar a classe java.util.Collections. Veja
o exemplo a seguir.

ARRAYS E COLEÇÕES
97

1
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import javax.swing.JOptionPane;
7 import javax.swing.JTextArea;
8
9 public class Exemplo5 {
10
11 public static void main(String[] args) {
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

12 List<String> listaNomes = new ArrayList<String>();


13 listaNomes.add("Maria");
14 listaNomes.add("João");
15 listaNomes.add("José");
16 listaNomes.add("Adriano");
17 listaNomes.add("Willian");
18 listaNomes.add("Patrícia");
19
20 String saida = "";
21 saida += "Lista desordenada: "+listaNomes;
22
23 Collections.sort(listaNomes);
24
25 saida += "\nLista ordenada: "+listaNomes;
26
27 JTextArea saidaArea = new JTextArea();
28 saidaArea.setText(saida);
29
30 JOptionPane.showMessageDialog(null, saidaArea,
31 "Trabalhando com ArrayList",
32 JOptionPane.INFORMATION_MESSAGE);
33
34 System.exit(0);
35
36 }
37 }

Quadro 32: Classificando um ArrayList

No exemplo acima, a linha 12 declara um ArrayList de String, e nas seguintes, 13


a 18, utilizamos o método listaNomes.add() para adicionarmos na lista,
nomes de pessoas de forma desordenada. Note que na linha 21 adicionamos na

A Interface List
III

variável saida os nomes contidos na lista antes de realizarmos qualquer tipo


de ordenação. Agora vamos dar atenção para a execução da linha 23. Perceba
que utilizamos o método sort() da classe Collections para realizar a clas-
sificação, ou melhor, ordenação da lista. Em seguida, na linha 25, recuperamos
novamente os nomes contidos na lista para que possamos nos maravilhar com
a mágica demonstrada a seguir.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 44: Ordenando Arrays
Fonte: o autor

A INTERFACE SET

Diferentemente da interface List, a interface Set é uma Collection que não


permite elementos duplicados, ou seja, só contém elementos únicos. O que deter-
minará que dois objetos seja idênticos é o metodo equals(), situação onde só
um objeto poderá ficar no Set, ou seja, se você tentar adicionar um elemento que
já existe nele, o método add() retornará false e o elemento não será adicio-
nado. As três classes que implementam Set são HashSet, LinkedHashSet
e TreeSet.
Como exemplo de estudo para a interface Set, vamos codificar e analisar
um exemplo utilizando HashSet. Esta classe trata-se de um conjunto Set não
ordernado e não classificado. Você pode utilizar esta classe quando quiser obter
um conjunto sem elementos duplicados sem precisar de ordem na sua iteração.
Quando construimos um HashSet, ele remove qualquer duplicidade existente
na Collection como mostra o exemplo a seguir.

ARRAYS E COLEÇÕES
99

Quadro 33: Exemplo utilizando HashSet

1
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.HashSet;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Set;
10 import javax.swing.JOptionPane;
11 import javax.swing.JTextArea;
12
13 public class Exemplo6 {
14
15 String saida = "";
16 private String[] cores = {"vermelho", "branco",
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

17 "azul", "verde", "cinza", "laranja",


18 "bronzeado", "branco", "ciano", "pêssego",
19 "cinza", "laranja"};
20
21 public static void main(String[] args) {
22 new Exemplo6();
23 }
24
25 public Exemplo6() {
26 List lista;
27
28 lista = new ArrayList(Arrays.asList(cores));
29 saida += "Lista com elementos duplicados: ";
30 saida += "\n" + lista;
31
32 this.gerarListaNaoDuplicada(lista);
33
34 JTextArea saidaArea = new JTextArea();
35 saidaArea.setText(saida);
36
37 JOptionPane.showMessageDialog(null, saidaArea,
38 "Trabalhando com Sets",
39 JOptionPane.INFORMATION_MESSAGE);
40
41 System.exit(0);
42 }
43
44 public void gerarListaNaoDuplicada(Collection collection) {
45 Set set = new HashSet(collection);
46 Iterator iterator = set.iterator();
47
48 saida += "\n\nLista com elementos não duplicados\n";
49
50 while (iterator.hasNext()) {
51 saida += iterator.next() + " ";
52 }
53 }
54 }

A Interface Set
III

No exemplo anterior utilizamos um HashSet para remover Strings duplicados de


uma ArrayList. Perceba que o método gerarListaNaoDuplicada recebe
como argumento uma Collection onde na linha 45 é construído um HashSet desta
Collection. Quando esta construção é realizada, quaisquer elemento duplicado
na Collection, neste caso nosso ArrayList declarado e criado na linha 28, é remo-
vido. No nosso exemplo, declamos e criamos na linha 16 um Array cores com
nomes duplicados, perceba as cores branco, cinza e laranja. Na constru-
ção do ArrayList na linha 28, utilizamos o Array de cores para criar a lista de
cores duplicadas. Depois que construimos nosso HashSet na linha 45 com base

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
na nossa lista de cores duplicadas, foi utilizado um Iterator para podermos
acessar os elementos do HashSet. Note que na linha 46 foi obtido um Iterator
de HashSet e nas linhas 50 e 51, utilizamos os métodos hasNext e next de
Iterator para acessarmos os elementos de HashSet. Veja, a seguir, a execução do
nosso exemplo.

Figura 45: Utilizando Sets para mostrar elementos não duplicados


Fonte: o autor

No exemplo anterior utilizamos HashSet para apresentar um conjunto de ele-


mentos não duplicados e não ordenados. Mas, e se você precisar ordenar estes
elementos? A seguir, vamos ver um exemplo utilizando a classe TreeSet e da
interface SortedSet que estende Set. A interface SortedSet mantém seus ele-
mentos em ordem natural ou uma ordem especificada por um Comparator.
A classe TreeSet implementa SortedSet e cria uma estrutura de árvore garan-
tindo que os elementos estejam ordenados de forma ascendente, de acordo com
a ordem natural. No entanto, ela nos possibilita criar um TreeSet com um cons-
trutor que permite gerar suas próprias regras de ordenação. Vamos ao exemplo?

ARRAYS E COLEÇÕES
101

Quadro 34: Utilizando a classe TreeSet

1
2
3 import java.util.Arrays;
4 import java.util.Iterator;
5 import java.util.SortedSet;
6 import java.util.TreeSet;
7 import javax.swing.JOptionPane;
8 import javax.swing.JTextArea;
9
10 public class Exemplo7 {
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

11
12 String saida = "";
13 private String[] cores = {"vermelho", "branco",
14 "azul", "verde", "cinza", "laranja",
15 "bronzeado", "branco", "ciano", "pêssego",
16 "cinza", "laranja"};
17
18 public static void main(String[] args) {
19 new Exemplo7();
20 }
21
22 public Exemplo7() {
23 TreeSet tree = new TreeSet(Arrays.asList(cores));
24
25 saida += "\nSet de elementos não "
26 + "duplicados e ordenados:\n";
27 this.mostrarSet(tree);
28
29 saida += "\n\nSubconjunto de TreeSet "
30 + "menor que ‘laranja’:\n";
31 this.mostrarSet(tree.headSet("laranja"));
32
33 saida += "\n\nSubconjunto de TreeSet "
34 + "maior que ou igual a ‘laranja’:\n";
35 this.mostrarSet(tree.tailSet("laranja"));
36
37 saida += "\n\nPrimeiro elemento de set: "
38 + tree.first();
39 saida += "\nÚltimo elemento de set: "
40 + tree.last();
41
42 JTextArea saidaArea = new JTextArea();
43 saidaArea.setText(saida);

A Interface Set
III

44
45 JOptionPane.showMessageDialog(null, saidaArea,
46 "Trabalhando com Sets",
47 JOptionPane.INFORMATION_MESSAGE);
48
49 System.exit(0);
50 }
51
52 private void mostrarSet(SortedSet ss) {
53 Iterator iterator = ss.iterator();
54

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
55 while (iterator.hasNext()) {
56 saida += iterator.next() + " ";
57 }
58 }
59 }

Perceba que no código anterior a linha 28 cria-se um objeto TreeSet com base
no Array cores e atribui uma referência para esse objeto a tree. A linha 36
realiza uma chamada para o método headSet no qual retorna um subcon-
junto de TreeSet com elementos menores que "laranja". Para retornar os
elementos maiores que ou igual a "laranja", realizamos um chamada para
o método tailSet. Quaisquer alterações realizadas por meios destas duas
visões, headSet e tailSet, serão refletidas em TreeSet. Note agora as chamadas
para os métodos first e last nas linhas 43 e 45. Estes são responsáveis por obter o
menor e o maior elemento, respectivamente. Finalmente, vamos nos atentar ao
método mostrarSet declarado na linha 57. Este método recebe como argu-
mento um SortedSet e o imprime quando realizamos chamadas deste método
nas linhas 32, 36 e 40 para mostrar o set ordenado, os elementos menores que
"laranja" e os elementos maiores que ou igual a "laranja", respectivamente.
Veja o resultado desta execução.

ARRAYS E COLEÇÕES
103
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 46: Trabalhando com Sets


Fonte: o autor

A INTERFACE MAP

O primeiro ponto que você precisa saber sobre a interface Map é que embora as
classes SortedMap, Hashtable, HashMap, TreeMap e LinkedHashMap
sejam consideradas coleções, nenhuma destas estendem de Collection como
as classes que implementam as interfaces Set e List. Você deve considerar um
objeto Map como um objeto que mapeia chaves para valores não permitindo que
existam chaves duplicadas (assim como Sets, Maps conta apenas com o método
equals() para derterminar se as chaves são iguais ou diferentes) e que cada
chave pode ser mapeada para no máximo um valor.
Chamamos este tipo de mapeamento de mapeamento um para um. Um
objeto Map difere de um Set no fato de que Map possui chave e valor, enquanto
Set possui somente chave. A inteface que estente Map responsável por manter
suas chaves ordenadas é a SortedMap. Implementações realizadas com Maps per-
mitem buscar um valor com base em uma determinada chave, recuperar uma
coleção apenas dos valores ou apenas das chaves. No exemplo que iremos estu-
dar a seguir, vamos utilizar um HashMap para contar o número de Strings que
iniciam com uma determinada letra.

A Interface Map
III

1
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import javax.swing.JOptionPane;
6 import javax.swing.JTextArea;
7
8 public class Exemplo8 {
9
10 private static String[] nomes = {"João", "José,
11 "Pedro", "Carlos", "Jaqueline",

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
12 "Matheus", "Marcelo"};
13
14 public Exemplo8() {
15 HashMap map = new HashMap();
16 Integer i;
17
18 for (int j = 0; j < nomes.length; j++) {
19 i = (Integer) map.get(
20 new Character(nomes[j].charAt(0)));
21
22 if (i == null) {
23 map.put(new Character(nomes[j].charAt(0)),
24 new Integer(1));
25 } else {
26 map.put(new Character(nomes[j].charAt(0)),
27 new Integer(i.intValue() + 1));
28 }
29 }
30
31 this.geraSaidaMap(map);
32 }
33
34 private void geraSaidaMap(Map mapRef) {
35 String saida = "";
36 saida += "Número de palavras iniciadas com a letra:";
37 saida += "\n" + mapRef.toString();
38 saida += "\nQuantidade de valores do Map: " + mapRef.
size();
39 saida += "\né vazio?: " + mapRef.isEmpty();
40

ARRAYS E COLEÇÕES
105

41 JTextArea saidaArea = new JTextArea();


42 saidaArea.setText(saida);
43
44 JOptionPane.showMessageDialog(null, saidaArea,
45 "Trabalhando com Maps",
46 JOptionPane.INFORMATION_MESSAGE);
47
48 System.exit(0);
49 }
50
51 public static void main(String[] args) {
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

52 new Exemplo8();
53 }
54 }

Quadro 35: Exemplo utilizando HashMap

Na linha 15 do nosso exemplo, construímos um HashMap para armazenar a


quantidade de palavras nomes que iniciam por uma determinada letra em map.
Perceba que este armazenamento é realizado no laço for das linhas 18 a 29. Note
que nas linhas 19 e 20 foi realizada uma chamada para o método get de map
para recuperar do HashMap a primeira letra de uma String em nomes utilizando
Character. Se não for encontrado um objeto mapeado em HashMap, o método
get irá devolver null, caso contrário, o valor do mapeamento é devolvido como
um objeto, convertido para Integer e atribuído em i.
Perceba que na linha 22 do nosso exemplo é verificado se i é null. Caso
seja, as linhas 23 a 24 realizam uma chamada para o método put de map para
armazenar um Integer com valor 1 no HashMap. Esse valor é o número de pala-
vras que inicia com Character. Se i não for null, significa que Character está
no HashMap, por isso, as linhas 26 a 27 incrementam o valor de Integer em 1
atualizando o valor no HashMap.
O método geraSaidaMap declarado na linha 34 recebe como argumento
um Map e atribui o seu conteúdo na variável saida utilizando o método toS-
tring. A linha 38 recupera o número de valores no Map por meio do método
size e a linha 39 recupera um boolean pro meio do método isEmpty indi-
cando se o Map está vazio. Veja, a seguir, o resultado da execução deste programa.

A Interface Map
III

Figura 47: Trabalhando com Maps


Fonte: o autor

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
A INTERFACE QUEUE

Você, provavelmente, já deve ter ouvido falar do conceito FIFO (first in, first out),
ou em português: primeiro a entrar, primeiro a sair. Pois bem, uma Queue, que
significa fila em português, segue este conceito (embora outras ordens sejam
possíveis) e tem como objetivo manter uma lista de tarefas a serem processa-
das de alguma maneira. Além de suportar todos os métodos padrões de uma
Collection, ela também possui métodos adicionais para adicionar, extrair e revi-
sar os elementos da fila.
A classe responsável por implementar uma Queue é a PriorityQueue.
Adicionada no Java 5, seus elementos são ordenados pela ordem natural e seu
objetivo é criar uma fila onde o elemento que tem prioridade para entrar, tem
prioridade para sair (priority in, priority out), ou seja, os elementos ordenados
primeiro serão acessados pimeiro, o que difere de uma fila do tipo FIFO (pri-
meiro a entrar é o primeiro a sair).
Vimos no começo desse tópico que uma Queue é uma interface com o pro-
pósito de manter uma lista de tarefas ou coisas a se fazer. A seguir, vamos ver
um exemplo de implementação de Queue utilizando a classe LinkedList.

ARRAYS E COLEÇÕES
107

1
2
3 import java.util.LinkedList;
4 import java.util.Queue;
5 import javax.swing.JOptionPane;
6 import javax.swing.JTextArea;
7
8 public class Exemplo9 {
9
10 String saida = "";
11
12 public Exemplo9() {
13 Queue<Integer> queue = new LinkedList<Integer>();
14 this.adicionarElemento(queue);
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

15 saida += "\n";
16 this.removerElemento(queue);
17
18 JTextArea saidaArea = new JTextArea();
19 saidaArea.setText(saida);
20
21 JOptionPane.showMessageDialog(null, saidaArea,
22 "Trabalhando com Queues",
23 JOptionPane.INFORMATION_MESSAGE);
24
25 System.exit(0);
26 }
27
28 public static void main(String[] args) {
29 new Exemplo9();
30 }
31
Quadro 36: Implementação de Queue utilizando LinkedList

32 private void adicionarElemento(Queue qe) {


33 int elemento = 10;
34 for (int i = elemento; i >= 0; i--) {
35 saida += "Adicionando o elemento: " + i + " na fila\n";
36 qe.add(i);
37 }
38 }
39
40 private void removerElemento(Queue qe) {
41 while (!qe.isEmpty()) {
42 saida += "Removendo o elemento: " + qe.remove()
43 + " da fila\n";
44 }
45 }
46 }

A Interface Queue
III

Vamos analisar nosso exemplo. Note que na linha 13 estamos declarando uma
Queue (fila) que recebe uma instância de uma LinkedList. Assim como um
ArrayList, LinkedList é uma classe onde seus elementos são ordenados pela
posição no índice exceto pelos elementos serem duplamente encadeados. Além
dos métodos obtidos da interface List, esse encadeamento fornece métodos para
inserção ou remoção do início ou final da fila tornando-se a melhor opção para
implementações de pilha ou fila.
Vamos agora analisar o método adicionarElemento() declarado na
linha 32. Este método recebe como argumento uma Queue na qual são adiciona-

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
dos 6 elementos. Perceba na linha 33 que foi declarada uma variável elemento
de tipo int e inicializa com o valor 5. A linha 34 realiza um laço for decre-
mento este valor até 0 e adicionando o valor decrementado na fila como mostra
a linha 33, ou seja, o primeiro elemento a entrar na fila é o 5, o próximo é o 4, 3
o seguinte e assim sucessivamente decrementando e adicionando até 0.
O método removerElemento declarado na linha 40 também recebe como
argumento uma Queue da qual serão removidos os elementos contidos nela. A
linha 41 realiza um laço while que enquanto a fila não for vazia (verificação
realizada com o método isEmpty()) será removido um elemento como mos-
tra a linha 42 ao utilizar o método remove(). Esse método tem a finalidade de
recuperar e remover um objeto da fila.
Como dito anteriormente, uma Queue segue o conceito FIFO, onde o pri-
meiro que entra é o primeiro que sai. Em nosso exemplo, o primeiro elemento
que entrou na fila é o 5 e o último foi o 0. Portanto, o primeiro elemento a sair
da fila será o 5 e o último será o 0. Veja, a seguir, a execução do programa.

ARRAYS E COLEÇÕES
109
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 48: Trabalhando com Queues


Fonte: o autor

CONSIDERAÇÕES FINAIS

Prezado(a) aluno(a), nesta unidade você estudou sobre duas estruturas de dados
muito utilizadas para armazenamentos e processamento de informações, Arrays
e Coleções.
Você aprendeu que Arrays são estruturas simples que consistem em uma
estrutura de dados de um mesmo tipo onde os elementos são armazenados um
após o outro sendo possível seu acesso por meio de um índice e, que para pro-
cessarmos algum tipo de informação é preciso criar programas que atendam a
tal necessidade.
Vimos que Coleções são estruturas de dados mais elaboradas que permi-
tem armazenar outros objetos. Diferentemente de Arrays, Coleções possuem um
conjunto de interfaces que possibilita manipular os elementos de uma Coleção
sem você se preocupar como a estrutura foi criada.

Considerações Finais
1. Três das declarações de Arrays são válidas. Selecione quais.
a) int [ ] idade;
b) [ ] int idade;
c) int idade [ ];
d) Thread [ ] threads;
e) [ ] threads Thread;

2. O código abaixo gera a exceção ArrayIndexOutOfBoundsExcep-


tion. Indique em qual linha ocorre esta exceção e por qual motivo.

1
2
3 public class Exercicio2 {
4
5 public static void main(String[] args) {
6 String[] texto = new String[10];
7
8 for (int i = 0; i < 10; i++) {
9 texto[i] = "Texto"+(i+1);
10 }
11
12 for (int i = 0; i <= texto.length; i++) {
13 String stringTexto = texto[i];
14 System.out.println(stringTexto);
15 }
16 }
17 }

3. Segundo o pacote java.util.*, quais as interfaces que implementam diretamente


a interface Collection?
a) Set
b) Map
c) List
d) Queue
e) SortedSet
MATERIAL COMPLEMENTAR

Collections Framework – Apostila Java e Orientação a Objetos (Capítulo 16)


Por Caelum

Ao término desta unidade, você será capaz de:


utilizar arrays, lists, sets ou maps dependendo da necessidade do programa;
iterar e ordenar listas e coleções;
usar mapas para inserção e busca de objetos.

Saiba mais sobre o assunto no artigo completo.


Fonte: <http://www.caelum.com.br/apostila-java-orientacao-objetos/collections-framework/>

Coleções no Java – Parte 1


Fonte: <http://www.youtube.com/watch?v=QTrlTt9kE4E>.
Coleções no Java – Parte 2
Fonte: <http://www.youtube.com/watch?v=GyCzVTsp3Mo>.
Coleções no Java – Parte 3
Fonte: <http://www.youtube.com/watch?v=KMp6QoMNPGM>.

Sempre que precisar manipular informações em uma estrutura de dados,


lembre-se que as Coleções possuem métodos prontos que lhe auxiliam nes-
ta tarefa, diferentemente de Arrays que necessecitam de implementações
para manipular os registros contidos no Array.

Material Complementar
Professor Dr. Edson A. Oliveira Junior
Professor Me. André Abdala Noel

INTRODUÇÃO À INTERFACE

IV
UNIDADE
GRÁFICA

Objetivos de Aprendizagem
■■ Entender o que é a biblioteca SWING.
■■ Estudar o tratamento de exceções do JAVA.

Plano de Estudo
A seguir, apresentam-se os tópicos que você estudará nesta unidade:
■■ O que é a biblioteca Swing
■■ Criando um Projeto no NetBeans IDE
■■ Criando um Container JFrame
■■ Adicionando componentes SWING
■■ Construindo Interface
■■ Escrevendo o código
115

INTRODUÇÃO

Caro(a) aluno(a), nesta unidade, iremos apresentar o processo de criação da


interface gráfica do usuário (GUI), utilizando a biblioteca Swing do Java. Vamos
implementar um simples sistema de cadastro de cursos de idiomas, utilizando a
ferramenta de desenvolvimento NetBeans.
O GUI Builder do NetBeans IDE permite criar visualmente aplicações GUI
em Java, facilitando o desenvolvimento das telas de forma integrada com o
código-fonte.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

O QUE É A BIBLIOTECA SWING?

O Swing é um toolkit que inclui um conjunto de componentes para fornecer


uma construção de interface gráfica para usuário (GUI) de programas Java.
O Swing é a principal biblioteca para criação de aplicações desktop com Java. 
Aplicações desktop são aquelas que rodam diretamente na máquina do usuário,
sendo necessária a instalação prévia do programa para que possam ser executa-
das. Aplicativos office, players de vídeo e áudio, ambientes de desenvolvimento
de software são exemplos comuns desse tipo de aplicação.
O Swing foi desenvolvido para fornecer um conjunto mais sofisticado de
componentes GUI comparando com o Abstract Window Toolkit (AWT). Swing
fornece um visual nativo que simula a aparência de várias plataformas. Além de
componentes familiares, tais como botões, caixas de seleção e rótulos, há ainda
uma seção especialmente sobre gerenciamento de layout, os chamados “Layout
Managers”, item muito importante quanto se trata de programação de Interfaces
Gráficas. O GUI Builder do NetBeans torna possível construir interfaces de apa-
rência profissional sem um conhecimento profundo dos gerenciadores de layout.
Você pode criar formulários simplesmente colocando componentes onde desejar.

Introdução
IV

CRIANDO UM PROJETO NO NETBEANS IDE

Para criar um novo projeto no NetBeans IDE, siga os passos abaixo:


1. Escolha Arquivo > Novo Projeto. Se preferir é possível clicar no ícone
Novo Projeto na barra de ferramentas do NetBeans.
2. No painel Categorias, selecione o nó Java e no painel Projetos, escolha
Aplicação Java. Clique em Próximo.

3. Insira o nome do projeto, aqui vamos nomear para “ProjetoSwing”

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
e especifique o local do projeto.
4. Deixe desmarcada a caixa de seleção Utilizar Pasta Dedicada para Arma-
zenar Bibliotecas.
5. Verifique se a caixa de seleção Definir como Projeto Principal está mar-
cada e desmarque o campo Criar Classe Principal.
6. Clique em Finalizar.

Figura 49: Criando projeto no NetBeans

INTRODUÇÃO À INTERFACE GRÁFICA


117

O NetBeans criará o projeto ProjetoSwing no sistema. Esse projeto contém todos


os arquivos associados como pastas para armazenamento de códigos-fontes e
testes e uma pasta para os metadados específicos do projeto.

CRIANDO UM CONTÊINER JFRAME


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Para adicionar um contêiner JFrame:


1. Clique com o botão direito do mouse no nó ProjetoSwing e selecione
Novo > Form JFrame.

2. Insira como Nome da Classe “Formulario”.


3. Clique em Finalizar.

Figura 50: Criando um JFRAME no NetBeans

Criando um Contêiner Jframe


IV

Observe que será criada uma nova tela com uma caixa de edição, onde você irá
construir toda sua interface gráfica, é possível redimensionar a tela com faci-
lidade. Observe ao lado direito da tela que há 2 seções, Paleta e Propriedades.
Em paleta se encontra todos os componentes para criar sua interface gráfica e
na seção Propriedades é possível definir vários atributos a cada componente.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
ADICIONANDO COMPONENTES SWING

Como já adicionamos um JFrame como container principal vamos separar os


itens do nosso formulário com JPanel.
Para adicionar um JPanel:
Na janela Paleta, selecione o componente Painel na categoria Contêineres do
Swing e mova até o canto esquerdo superior do form no GUI Builder. Alinhe o
componente ao JPanel e, em seguida, acrescente mais um Jpanel para que pos-
samos separar as categorias em nosso form.
Adicionando título aos JPanels:

Figura 51: JFrame do NetBeans

INTRODUÇÃO À INTERFACE GRÁFICA


119

1. Selecione o JPanel superior no GUI Builder.


2. Na janela Propriedades, clique no botão de reticências (...) ao lado da
propriedade Borda.
3. No editor de Bordas do JPanel exibido, selecione o nó Borda com Título
no painel Bordas Disponíveis.

4. No painel Propriedades abaixo, insira CADASTRO para a propriedade


Título.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 52: Inserindo JPanel

Adicionando Componentes Swing


IV

5. Clique nas reticências (...) ao lado da propriedade Fonte, selecione Negrito


em Estilo de Fonte e insira 14 no Tamanho. Clique em OK para fechar
as caixas de diálogo.
6. Selecione o JPanel inferior e repita as etapas acima.

As bordas com título serão adicionadas a ambos componentes JPanel.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 53: Definindo as bordas dos JPanels

CONSTRUINDO A INTERFACE

Como vamos fazer um sistema simples de cadastro, utilizaremos os seguintes


componentes:
■■ JLabel: permite inserir textos e imagens.

■■ JTextField: caixa de texto para que o usuário insira os dados no pro-


grama. – lembrando que todos os dados inseridos em um JTextField são
tratados como String.

■■ JRadioButton: botão que permite apenas seleção de uma opção quando

INTRODUÇÃO À INTERFACE GRÁFICA


121

relacionado a um ButtonGroup.

■■ JComboBox: componente semelhante a um vetor, que permite ao usu-


ário escolher apenas uma opção.

■■ JButton: botão onde serão implementados os eventos.

■■ JTextArea: campo semelhante ao JTextField, normalmente usado para


entrada de textos maiores. Como críticas, sugestões etc.

■■ JCheckBox: caixas de múltiplas seleções, permite o usuário marcar


várias opções ao mesmo tempo.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Para adicionar os componentes JLabel ao form:


1. Na janela Paleta, selecione o componente Label na categoria Controles
do Swing.

2. Mova o cursor acima do JPanel CADASTRO e posicione o Label no Canto


superior esquerdo.
3. Clique duas vezes no JLabel para selecionar a exibição de texto.

4. Digite “Nome:” e pressione Enter para que o novo nome do Label seja
exibido.

Para adicionar um JTextField ao form:


1. Na janela Paleta, selecione o componente Campo de texto na categoria
Controles do Swing.
2. Mova o cursor imediatamente à direita do JLabel Nome: recém-adicio-
nado.

Construindo a Interface
IV

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 54: Inserindo os JTextField

Antes de continuar, vamos selecionar o campo JTextField e no menu proprieda-


des navegar até a propriedade text do componente.
Agora que você aprendeu a inserir os componentes de JTextField e JLabel,
vamos deixar nosso formulário igual a figura abaixo:

Figura 55: Inserindo os JTextField

Para você deixar os componentes JTextField do mesmo tamanho basta selecio-


nar todos ao mesmo tempo e clique com o botão direito do mouse em um deles
e escolha, Definir Mesmo Tamanho > Mesma Largura no menu pop-up.

INTRODUÇÃO À INTERFACE GRÁFICA


123

Para adicionar um JComboBox:


1. Selecione a Caixa de Combinação no GUI Builder.
2. Arraste o JComboBox e posicione conforme a figura abaixo.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 56: Inserindo componentes SWING no Formulário

Para inserir itens no JComboBox da opção ‘UF, você deverá clicar nas reticências
(...) da opção model em propriedades, insira o nome do item que você quer que
apareça e clique em adicionar. Nesse exemplo coloquei todos os estados brasileiros.
Para adicionar JRadioButton:
1. Na janela Paleta, selecione o componente Botão de Rádio na categoria
Controles do Swing.
2. Arraste e posicione os JRadioButton conforme figura abaixo.

Construindo a Interface
IV

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 57: Inserindo componentes SWING no Formulário

Para permitir que seja marcada apenas uma opção nos JRadioButtons, da
opção Sexo de nosso cadastro, você deve adicionar ao projeto o componente
ButtonGroup, este componente não apresenta nenhum tipo de interface, ao
inseri-lo note que ele será adicionado no inspetor de componentes à esquerda
da tela. Em seguida, vá até as propriedades dos JRadioButtons, opção button-
Group e escolha buttonGroup1 (nome padrão para este componente), faça isso
para ambos os JRadioButtons.
Para adicionar JCheckBox:
1. Na janela Paleta, selecione o componente Caixa de Seleção na categoria Con-
troles do Swing.
2. Arraste e posicione os JCheckBox.
3. Altere o campo text de cada JCheckBox conforme abaixo.

INTRODUÇÃO À INTERFACE GRÁFICA


125
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 58: Inserindo componentes SWING no Formulário

Para alinhar os JCheckBox selecione todos ao mesmo tempo e com o botão direito
do mouse vá em redimensionamento automático horizontal.
Para adicionar JTextArea:
1. Na janela Paleta, selecione o componente Área de Texto na categoria
Controles do Swing.
2. Arraste e posicione o JTextArea.

Para adicionar JButton:


1. Na janela Paleta, selecione o componente Botão na categoria Contro-
les do Swing.
2. Arraste e posicione o JButton.

Construindo a Interface
IV

Nosso formulário deve ficar conforme abaixo:

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 59: Inserindo componentes SWING no Formulário

No exemplo acima, estamos usando todos os componentes mencionados


anteriormente.

ESCREVENDO O CÓDIGO

Para iniciar a implementação do código, deve-se alterar o nome das variáveis


de todos os componentes que serão utilizados para que nosso código fique mais
limpo e organizado.
Para alterar o nome da variável de um componente, clique sobre ele, com o
botão direito do mouse escolha ‘Alterar o nome de variável...’.
Coloque:
■■ Para os JTextField os nomes a seguir: nomeCampo; telefoneCampo;
enderecoCampo; cidadeCampo; emailCampo.
■■ Para o JComboBox: estadoCampo.

INTRODUÇÃO À INTERFACE GRÁFICA


127

■■ Para os JRadioButton: masculinoCampo; femininoCampo.


■■ Para JCheckBox: alemaoCampo; espanholCampo; francesCampo; ingles-
Campo; italianoCampo; japonesCampo.
■■ Para JTextArea: motivoCampo.
■■ Para JButton: salvar.
Não é necessário alterar os JPanels nem os JLabels.
O próximo passo é criar uma classe com todas as variáveis utilizadas no
formulário Swing. Lembrando que o nosso objetivo é compreender como os
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

componentes do Swing funcionam e como adicionamos os eventos e métodos


necessários à implementação dos componentes. Aqui será criada apenas uma
classe que será o nosso objeto para manipular e armazenar os dados contidos
em todos os componentes do nosso formulário.
Para criar a classe que será nosso Objeto:
1. Clique com o botão direito do mouse sobre o pacote default, selecione
Novo>classe Java.
2. No nome da Classe coloque Cadastro e clique em finalizar.

Observe que foi criado uma classe chamada Cadastro ao lado esquerdo da tela.

Figura 60: Criando a Classe Cadastro

Agora, vamos inserir todos os atributos que serão utilizados em nosso projeto e
gerar todos os gets e sets. Para gerar os gets e sets clique com o botão direito do
mouse e selecione a opção “Inserir código”; na janela pop up selecione “Getter
e Setter ...” conforme a figura abaixo:

Escrevendo o Código
IV

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 61: Implementando os métodos da Classe Cadastro

Observe que os nomes dos atributos são semelhantes aos campos em nosso
formulário. É importante manter nomes de atributos condizentes com as
variáveis utilizadas no form do Swing para facilitar na implementação.

Para criar um evento no Botão Salvar:


1. Clique com o botão direito do mouse sobre o botão Salvar.
2. Navegue até a propriedade evento>action>actionPerformed.
3. O NetBeans irá apresentar o método salvarActionPerformed criado auto-
maticamente.

Figura 62: Atribuindo evento ao botão Salvar

Aqui, iremos implementar o código dos dados recebidos nos campos do nosso
Form. Primeiramente, é necessário instanciar o objeto que criamos da seguinte
maneira:

Figura 63: Instanciando o objeto Cadastro

INTRODUÇÃO À INTERFACE GRÁFICA


129

É necessário utilizar o método getText() para receber os dados inseridos em um


JTextField conforme a figura abaixo.

Figura 64: Atribuindo os valores das variáveis aos atributos

Observe que a nomenclatura dos atributos e dos campos facilita a visualização


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

do código, nesse caso está claro que o atributo nome do objeto está recebendo
os dados do campo nome do formulário.
Agora implemente o mesmo método para os outros atributos de texto con-
forme abaixo incluído o campo JTextArea:

Figura 65: Atribuindo os valores das variáveis aos atributos

Agora, vamos implementar os códigos dos campos de seleção JCheckBox, a


diferença é que teremos de fazer algumas validações para descobrir se estão sele-
cionados ou não. Os atributos que fazem referência aos JCheckBox são do tipo
boolean, então a chamada do método ficará da seguinte maneira:

Escrevendo o Código
IV

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Figura 66: Atribuindo os valores das variáveis aos atributos

A mesma ideia será utilizada para o campo sexo do nosso formulário, porém
como é um buttonGroup, teremos de fazer uma condição para atribuir uma String
ao nosso Objeto quando um deles estiverem selecionados da seguinte forma:

Figura 67: Atribuindo os valores das variáveis aos atributos

E, finalmente, o JComboBox que se refere ao nosso atributo Estado, o método a


ser implementado para esse componente é o getSelectedItem(), mas é necessário
observar que o tipo do atributo Estado é String e, por isso teremos de realizar um
“casting” ou moldagem para converter um objeto ou primitiva de um tipo para
outro. No caso iremos converter a nossa primitiva para String. O nosso método
ficará da seguinte forma:

Figura 68: Atribuindo os valores das variáveis aos atributos

Todos os métodos necessários para salvar os dados inseridos no nosso formu-


lário foram implementados.

INTRODUÇÃO À INTERFACE GRÁFICA


131

Para concluir o método salvar devemos inserir uma informação apresen-


tando ao usuário que o formulário foi salvo. Para isso, fazemos uso da classe
JOptionPane. Essa classe proporciona uma série de métodos estáticos que ao serem
invocados criam caixas de diálogos simples e objetivas. Para usar JOptionPane
temos de importar o pacote javax.swing.JOptionPane primeiro.
O método showMessageDialog é responsável por trazer a caixa de mensa-
gem, o qual pode ter muitos argumentos. Abaixo é possível visualizar o método
para apresentação da Mensagem de confirmação do cadastro.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 69: Declarando a mensagem de confirmação

Outro método que deve ser implementado em nosso projeto é o método lim-
par(). O objetivo desse método é eliminar da tela todas as informações que foram
digitadas no formulário após clicar no botão Salvar.
Para deixar o nosso código mais organizado vamos criar um método novo
na mesma classe Formulário, abaixo do método salvar da seguinte forma:

Figura 70: Implementando o método limpar

Aqui, vamos definir novos valores para limpar cada campo de nosso formulário.
Para os campos de texto, JTextField e JTextArea, basta atribuirmos “” por meio
do método setText(“”); para os JCheckBox devemos fazer uso do método setSe-
lected(false) conforme pode ser visto na figura abaixo:

Escrevendo o Código
IV

Figura 71: Implementando o método limpar

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Para alterar o estado dos JRadioButton definidos para representar Masculino e
Feminino deve-se modificar o componente buttonGroup1 por meio do método
clearSelecion(). Segue abaixo o método para limpar esse componente.

Figura 72: Implementando o método limpar

E, finalmente, para alterar o estado do JComboBox fazemos uso da propriedade


índex definindo -1 para sua posição conforme abaixo:

Figura 73: Implementando o método limpar

Para que o método limpar() seja executado fazemos a chamada no método Salvar
antes da mensagem de confirmação de cadastro salvo.

INTRODUÇÃO À INTERFACE GRÁFICA


133

Figura 74: Fazendo a chamada do método limpar no método salvar

Para executar o projeto é necessário pressionar o botão executar projeto ou ape-


Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

nas pressionar a tecla F6. A tela do cadastro deve ser semelhante à tela da figura
abaixo.
Observe que o formulário não possui validações quanto à inserção de dados
vazios. E nem tratamento de exceções. Vamos ver esse tópico a seguir.

Figura 75: Formulário em execução

Escrevendo o Código
IV

CONSIDERAÇÕES FINAIS

Nessa unidade você aprendeu a construir aplicativos utilizando interface gráfica


Swing. Você conheceu a ferramenta NetBeans IDE que torna muito simples o
desenvolvimento de interfaces gráficas. Uma boa interface gráfica faz toda dife-
rença em qualquer programa, e a utilização de Swing para criação desta interface
pode vir a ser muito útil.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

INTRODUÇÃO À INTERFACE GRÁFICA


135

1. Crie o seguinte GUIs usando Java Swing. Você não tem de fornecer
qualquer funcionalidade.

2. Dado o código a seguir:

1. System.out.print ("Inicio");
2. try{
3. System.out.print ("ola_mundo")
4. throw new FileNotFoundException();
5. }
6. System.out.print ("capturar_aqui");
7. catch (EOFException e){
8. System.out.print ("fim_da_exceção_do_arquivo");
9. }
10. catch (FileNotFoundException e){
11. System.out.print ("arquivo_nao_encontrado");
12. }

Sabendo-se que tanto o EOFException quanto FileNotFoundException são


subclasses de IOException e presumindo que esse bloco de código seja
inserido em uma classe, que declaração estará mais perto da verdade com
relação a esse código?
a) O código não será compilado.
b) Saída do código: Inicio ola_mundo arquivo_nao_encontrado.
c) Saída do código: Inicio ola_mundo fim_da_exceção_do_arquivo.
d) Saída do código: Inicio ola_mundo capturar_aqui arquivo_nao_encon-
trado.
3. Há algo de errado com o manipulador de exceção a seguir? Será que este
código compila?

try {

} catch (Exception e) {

} catch (ArithmeticException a) {

}
MATERIAL COMPLEMENTAR

Projeto Java Completo com Swing – Parte 1


Fonte: <http://www.youtube.com/watch?v=HhulpEIWTds>.
Projeto Java Completo com Swing – Parte 2
Fonte: <http://www.youtube.com/watch?v=mxJos-f23ec>.

Os vídeos, a seguir, apresentam um Tutorial que mostra como desenvolver uma


calculadora usando NetBeans IDE. Assista e aprenda um pouco mais.
Parte 1: <http://www.youtube.com/watch?v=v2w74ZwTrd4>.
Parte 2: <http://www.youtube.com/watch?NR=1&v=pjTHUlDpmls&feature=fvwp>.

Quando trabalhar com Swing e projetar telas, lembre-se que as telas devem
ser equilibradas e ordenadas.

Introdução à Programação Gráfica em Java com Swing


Por Rafael Steil
Neste artigo vamos ver como criar aplicações gráficas em Java, mais precisamente usando um
Framework (conjunto de classes) chamado Swing. Veremos três exemplos, começando com um
simples programa que apenas escreve uma mensagem na tela, passando para um programa que
já trabalha com caixas de texto e botões, e por final veremos como trabalhar com listas. Há ainda
uma seção especialmente sobre gerenciamento de layout, os chamados “Layout Managers”, item
muito importante quanto se trata de programação GUI. Não é necessário que você tenha alguma
experiência anterior em programação gráfica com Java, porém um mínimo de conhecimento
da tecnologia ajudaria, apesar de não ser imprescindível, uma vez que é bastante comum as
pessoas terem o primeiro contato com Java por meio de programação gráfica. Conhecimentos
de lógica de programação são necessários, mesmo que seja apenas uma base. Para digitar os
programas você pode usar qualquer editor de textos ou código de sua preferência, tais como
Notedad, UltraEdit, VI, Emacs, KWrite e assim por diante. Programas em Java necessitam do JDK
para serem desenvolvidos e, uma vez compilados, apenas a JRE faz-se ncessário. O JDK, por já
ser um ambiente completo de desenvolvimento, já traz uma versão da JRE, portanto você não
precisa ter os dois pacotes instalados na mesma máquina. Se você nunca mexeu com Java ou não
tem (ou não sabe como instalar) o JDK, dê uma lida nos tutoriais “Instalando e configurando o
JDK no Linux” (ou “Instalando e configurando o JDK no Windows” caso seja usuário de Windows),
“Classpath, entendendo o que é e para que serve”, “Sopa de letrinhas sabor Java” e “Os erros e
dúvidas de um iniciante”, disponíveis no site do GUJ seção “Artigos” e “Tutoriais”.
Saiba mais sobre o assunto no artigo completo.
Fonte: <http://www.guj.com.br/articles/38>. Acesso em: 03 abr. 2013

Material Complementar
Professor Dr. Edson A. Oliveira Junior

PERSISTÊNCIA DE

V
UNIDADE
DADOS COM JPA

Objetivos de Aprendizagem
■■ Estudar os principais fundamentos sobre JDBC.
■■ Estudar os principais fundamentos sobre a API JPA.

Plano de Estudo
A seguir, apresentam-se os tópicos que você estudará nesta unidade:
■■ JDBC – Java Database Connectivity
■■ Drivers JDBC
■■ Conectando a um SGDB com Connection
■■ Executando Instruções SQL com Statement
■■ Executando Instruções SQL com PreparedStatement
■■ Recuperando e utilizando dados de um ResultSet
■■ O JPA – Java Persistence API
■■ Entidades
■■ Principais Anotações JPA
■■ Relacionamentos JPA
■■ Unidades de Persistência (Persistence Unit)
■■ Gestor de Entidade (Entity Manager)
141

INTRODUÇÃO

Caro(a) aluno(a), nesta unidade iremos abordar os principais fundamentos da


API JPA – Java Persistence API.
Introduzida pelo EJB 3 (Enterprise Java Beans 3), o JPA é uma API que define
um framework de persistência na qual fornece um modelo de mapeamento objeto
relacional para a persistência em bancos de dados relacionais. Embora tenha sido
projetado principalmente para o uso com grandes aplicações baseadas em servi-
dor, JPA pode ser usado diretamente tanto por aplicações web quanto desktop.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Quando falamos de persistência em Java com JPA, estamos falando de mapear


objetos Java normais de forma automática para um banco de dados SQL. Sabe
todos aqueles códigos pesados de consulta, inserção e atualização que estamos
acostumados a fazer? Então. O JPA faz isto por você, ou seja, ele carrega, pes-
quisa e salva objetos do modelo de dados automaticamente sem você precisar
se preocupar como isso é feito.
Mas antes de aprendermos sobre persistência com JPA, você irá estudar
e conhecer alguns conceitos sobre a API JDBC – Java Database Connectivity.
Diferentemente de JPA, JDBC não realiza persistência de dados utilizando um
objeto Java mapeado para um modelo relacional e sim, realiza a persistência utili-
zando comandos SQL. Para isso a API JDBC fornece algumas interfaces para que
essa persistência possa ser realiza como Connection, Statement, PreparedStatemen
e outros que você irá estudar a seguir. Então, vamos aprender mais?

Introdução
V

JDBC – JAVA DATABASE CONNECTIVITY

Antes de entrarmos de cabeça nos estudos sobre o JPA, vamos falar um pouco
sobre JDBC (Java Database Connectivity). JDBC trata-se de uma API para acesso
a banco de dados relacionais por meio de comandos SQL em que a programação
do sistema é a mesma para qualquer SGBD (Sistema Gerenciador de Banco de
Dados), ou seja, não há necessidade de desenvolver aplicações amarradas com
um banco específico.
Com JDBC é possível:

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
■■ Estabelecer uma conexão com um banco de dados ou com qualquer fonte
de dados tabular.
■■ Executar instruções SQL.
■■ Processar os resultados obtidos.

DRIVERS JDBC

Para que seja possível estabelecer uma conexão com um banco de dados permi-
tindo que uma aplicação Java interaja com esse banco, o JDBC utiliza drivers
específicos de acordo com cada SGDB. Por exemplo, para construir uma apli-
cação Java que realize acesso a um banco de dados MySQL é necessário utilizar
os drivers específicos desse SGDB. Normalmente, os drivers JDBC são forneci-
dos pelos seus fabricantes ou por comunidades de usuários.
Atualmente, existem quatro tipos de drivers que são classificados da maneira
a seguir.
1. Ponte JDBC-ODBC – é o mais simples, porém restrito a plataforma Win-
dows. Geralmente utilizado quando não existe para o SGDB um driver
nativo (tipo 4), sendo necessário um ODBC para se conectar ao banco
de dados.

PERSISTÊNCIA DE DADOS COM JPA


143

2. Driver API-Nativo – converte as chamadas JDBC para as chamadas da


API cliente do SGDB.
3. Driver de Protocolo de Rede – trata-se do tipo mais flexível, pois possibi-
lita criar aplicações Java indepente de banco de dados, ou seja, a mesma
aplicação pode se conectar a vários SGDBs diferentes.
4. Driver Nativo – é o mais recomendado, pois as chamadas JDBC são tra-
duzidas no protocolo do SGDB.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

CONECTANDO A UM SGDB COM CONNECTION

A primeira interface que vamos estudar é a java.sql.Connection. Um


objeto Connection representa uma sessão de conexão com um determinado
banco de dados na qual as instruções SQL são executadas e os resultados obti-
dos dentro do contexto desta sessão. Para uma aplicação, ela permite que seja
criada uma ou mais conexões com um mesmo banco de dados ou várias cone-
xões com diferentes bancos de dados.
Outro ponto interessante é que ela também permite obter informações do
banco de dados a qual ela se conectou, por exemplo:
■■ Qual o fabricante e a versão do banco de dados.
■■ O nome e versão do driver JDBC utilizado.
■■ O nome do usuário utilizado na conexão.
■■ A URL de conexão.
■■ As estruturas das tabelas do banco de dados.
■■ Qual a gramática SQL suportada.
■■ Procedimentos.

Conectando a um Sgdb com Connection


V

Estas e outras informações podem ser obtidas por meio de um objeto


DatabaseMetaData retornado pelo método getMetaData() acessado
em uma instância de Connection. Ficou confuso(a)? Não se preocupe, tudo
ficará mais claro adiante.
Você deve estar se perguntando: mas como eu crio ou obtenho uma cone-
xão com um banco de dados? A maneira mais comum de estabelecer uma
conexão com um banco de dados é por meio de uma chamada para o método
DriverManager.getConnection(). Esse método recebe como argu-
mento três Strings contendo a URL JDBC de conexão com o banco de dados, o

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
usuário e a senha, respectivamente. Veja, a seguir, um pequeno trecho de código
que representa uma conexão.

//URL JDBC de conexão


String urlConexao = "jdbc:derby://localhost:1527/ead-bd";
//obtendo um objeto Connection (uma conexão) com getConnection
Connection con = DriverManager.getConnection(urlConexao, usuario,
senha);

Quadro 37: Criando uma Connection

Quando utilizamos o DriverManager em uma aplicação para criarmos um objeto


Connection, devemos fornecer para o método getConnection uma URL JDBC
que tem a finalidade de fornecer uma maneira de identificar com qual banco de
dados determinado driver irá estabeler uma conexão. Veja, a seguir, a sintaxe de
uma URL JDBC, perceba que ela é separada em três partes utilizando dois pontos.

jdbc: <subprotocol>: <subname>

Quadro 38: Sintaxe de URL JDBC

A primeira parte jdbc indica que a URL em questão é uma URL JDBC. A segunda,
<subprotocol>, representa o nome do driver de conexão utilizado para um
determinado SGDB. O terceiro, <subname>, representa a fonte de dados a qual
será realizada a conexão. Veja, a seguir, uma relação com os principais fabrican-
tes de banco de dados e o formato de URL JDBC de conexão de cada um.

PERSISTÊNCIA DE DADOS COM JPA


145

SGDB Url de Conexão


Oracle jdbc:oracle:thin:@host:porta:nomeBanco (Porta padrão 1521)
PostgreSQL jdbc:postgresql://host:porta/nomeBanco (Porta padrão 5432)
jdbc:db2://host:porta/nomeBanco (Porta padrão 446, 6789, ou
DB2
50000)
jdbc:sqlserver://host:porta;databaseName=nomeBanco (Porta
SQL Server
padrão 1433)
MySQL jdbc:mysql://host:porta/nomeBanco (Porta padrão 3306)
jdbc:firebirdsql:host/porta:caminhoArquivo.fdb (Porta padrão
Firebird
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

3050)
Tabela 1: Formatos de URL JDBC de conexão com banco de dados

Eu sei que você já deve estar ansioso(a) para começar a ver exemplos e pôr em
prática o que estudamos até agora. Porém, você deverá executar alguns passos
antes disso. O exemplo, a seguir, cria uma conexão com um banco de dados
derby, portanto será necessário que você configure um banco de dados derby
no seu computador. O NetBeans IDE possui ferramentas para iniciar e parar
o serviço do derby e permitir criar o banco e as tabelas que iremos utilizar em
nossos exemplos a partir de agora. O link, a seguir, contém um tutorial sobre
como configurar o derby no NetBeans, siga o tutorial e para nossos estudos
crie um banco com o nome ead-bd.
<http://netbeans.org/kb/docs/ide/java-db_pt_BR.html>.
Voltando ao nosso exemplo, ele obtém informações da conexão e do banco de
dados utilizando os métodos estudados até então.

Conectando a um Sgdb com Connection


V

1
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.SQLException;
6 import javax.swing.JOptionPane;
7 import javax.swing.JTextArea;
8
9 public class ExemploConnection {
10
11 private Connection con = null;

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
12 private String usuario = null;
13 private String senha = null;
14 private String urlConexao = null;
15
16 public ExemploConnection() {
17
18 urlConexao = "jdbc:derby://localhost:1527/ead-bd";
19 usuario = "ead";
20 senha = "ead";
21
22 this.conectarBanco();
23
24 this.desconectaBanco();
25 }
26
27 public static void main(String[] args) {
28 new ExemploConnection();
29 }
30
31 private void conectarBanco() {
32 String saida = "";
33 try {
34 con = DriverManager.getConnection(urlConexao,
35 usuario, senha);
36
37 saida += "Informações de Conexão";
38 saida += "\nFabricante SGDB: "
39 + con.getMetaData().
getDatabaseProductName();

PERSISTÊNCIA DE DADOS COM JPA


147

40 saida += "\nVersão SGDB: "


41 + con.getMetaData().
getDatabaseProductVersion();
42 saida += "\nDriver SGDB: "
43 + con.getMetaData().getDriverName();
44 saida += "\nVersão Driver SGDB: "
45 + con.getMetaData().getDriverVersion();
46 saida += "\nUrl de Conexão: "
47 + con.getMetaData().getURL();
48 saida += "\nUsuário: "
49 + con.getMetaData().getUserName();
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

50
51 JTextArea saidaArea = new JTextArea();
52 saidaArea.setText(saida);
53
54 JOptionPane.showMessageDialog(null, saidaArea,
55 "Conexão realizada com Sucesso",
56 JOptionPane.INFORMATION_MESSAGE);
57 } catch ( SQLException ex) {
58 JOptionPane.showMessageDialog(null,
ex.getMessage(),
59 "Erro ao conectar no banco",
60 JOptionPane.ERROR_MESSAGE);
61 }
62 }
63
64 private void desconectaBanco() {
65 try {
66 if (!con.isClosed()) {
67 con.close();
68 }
69 } catch (SQLException ex) {
70 JOptionPane.showMessageDialog(null,
ex.getMessage(),
71 "Erro ao desconectar",
72 JOptionPane.ERROR_MESSAGE);
73 }
74 }
75 }

Quadro 39: Obtendo informações de conexão com banco de dados

Conectando a um Sgdb com Connection


V

EXECUTANDO INSTRUÇÕES SQL COM STATEMENT

Um objeto Statement tem por objetivo executar uma instrução SQL sim-
ples sem parâmetros, retornando os resultados que ela produz por meio de um
ResultSet (falaremos sobre ResultSet mais adiante, neste momento você só
precisa saber que um ResultSet contém o resultado da execução de uma instru-
ção SQL). Por padrão, cada execução de Statement retorna apenas um ResultSet
contendo todos os resultados daquela instrução SQL realizada.
Quando criamos uma conexão com um determinado banco de dados utili-

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
zando um objeto Connection, podemos utilizar esta conexão para enviar instruções
SQL neste banco por meio desse objeto. Para isso, precisamos criar um objeto
Statement a partir do método createStatement() de Connection, como
mostra o trecho de código a seguir.

//obtendo um objeto Connection (uma conexão) com getConnection


Connection con = DriverManager.getConnection(urlConexao, usuario,
senha);
//cria um objeto Statement stmt para executar instruções SQL
Statement stmt = con.createStatement();

Quadro 40: Criando um Statement

Para que seja possível executar instruções SQL com o objeto Statement obtido,
você pode utilizar alguns dos métodos execute fornecidos por ele, passando
como argumento uma String que contenha o SQL que será executado. Veja o
trecho de código a seguir.

//String SQL para seleção de dados


String sql = "SELECT * FROM TABELA";
//cria um objeto Statement stmt para executar instruções SQL
Statement stmt = con.createStatement();
//executa instrução SQL com executeQuery
ResultSet rs = stmt.executeQuery(sql);

Quadro 41: Executando uma instrução SQL com Statement

PERSISTÊNCIA DE DADOS COM JPA


149

A seguir, veja um exemplo de como é realizada a declaração e execução de uma


instrução SQL utilizando Statement. Porém, antes de prosseguir será necessá-
rio criarmos uma tabela em derby no banco de dados ead-bd. Este exemplo
e os posteriores irão inserir e selecionar registros desta tabela. Crie no banco a
seguinte estrutura de tabela.

CREATE TABLE PRODUTO (


ID INTEGER NOT NULL,
DESCRICAO VARCHAR(60),
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

PRIMARY KEY (ID)


);

Quadro 42: Instrução SQL para criar a tabela Produto

Agora que já temos a tabela criada, implemente o exemplo a seguir. Este exemplo:
inserir um registro na tabela Produtos utilizando o método executeUpdate
do objeto Statement.

1
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7 import javax.swing.JOptionPane;
8
9 public class ExemploStatement {
10
11 private Connection con = null;
12 private String usuario = null;
13 private String senha = null;
14 private String urlConexao = null;
15 private String driverJDBC = null;
16
17 public ExemploStatement() {
18 driverJDBC = "org.apache.derby.jdbc.ClientDriver";
19 urlConexao = "jdbc:derby://localhost:1527/ead-bd";

Executando Instruções Sql com Statement


V

20 usuario = "ead";
21 senha = "ead";
22
23 this.conectarBanco();
24 this.executarStatement();
25 this.desconectaBanco();
26 }
27
28 public static void main(String[] args) {
29 new ExemploStatement();
30 }

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
31
32 private void conectarBanco() {
33 try {
34 Class.forName(driverJDBC);
35 con = DriverManager.getConnection(urlConexao,
36 usuario, senha);
37 } catch (ClassNotFoundException | SQLException ex) {
38 JOptionPane.showMessageDialog(null,
ex.getMessage(),
39 "Erro ao conectar no banco",
40 JOptionPane.ERROR_MESSAGE);
41 }
42 }
43
44 private void desconectaBanco() {
45 try {
46 if (!con.isClosed()) {
47 con.close();
48 }
49 } catch (SQLException ex) {
50 JOptionPane.showMessageDialog(null,
ex.getMessage(),
51 "Erro ao desconectar",
52 JOptionPane.ERROR_MESSAGE);
53 }
54 }
55
60 Statement stmt = con.createStatement();
61 int qtdRegistrosInseridos = stmt.
executeUpdate(sql);

PERSISTÊNCIA DE DADOS COM JPA


151

62 String saida = "Quantidade de registros inseridos:


"
63 + qtdRegistrosInseridos;
64 JOptionPane.showMessageDialog(null, saida,
65 "Registro Inserido com Sucesso",
66 JOptionPane.INFORMATION_MESSAGE);
67 } catch (SQLException ex) {
68 JOptionPane.showMessageDialog(null,
ex.getMessage(),
69 "Erro ao inserir registro",
70 JOptionPane.ERROR_MESSAGE);
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

71 }
72 }
73 }

Quadro 43: Inserindo registros na tabela Produto

EXECUTANDO INSTRUÇÕES SQL COM


PREPAREDSTATEMENT

O objetivo de um objeto PreparedStatement é executar uma instrução


SQL pré-compilada, ou seja, um PreparedStatement envia a instrução SQL para
o SGDB de modo a deixá-la pareparada para receber parâmetros esperados por
esta instrução. A instrução SQL contida nesse objeto pode ter um ou mais parâ-
metros IN (entrada) em que o valor deste parâmetro não é definido quando o SQL
é criado. Ao invés disso, é definido um ponto de interrogação “?” representando
um espaço reservado para cada parâmetro. Veja o trecho de código que segue.

Executando Instruções SQL com Preparedstatement


V

//SQL contendo dois parâmetros IN representados por "?"


String sql = "INSERT INTO EAD.PRODUTO (ID, DESCRICAO) VALUES (?,
?)";
//obtendo um objeto Connection (uma conexão) com getConnection
Connection con = DriverManager.getConnection(urlConexao, usuario,
senha);
//cria um objeto PreparedStatement pstmt para executar instruções
SQL
PreparedStatement pstmt = con.prepareStatement(sql);

Quadro 44: Criando um PreparedStatement

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
Antes de uma instrução SQL ser executada com PreparedStatement você deve
definir um valor para cada ponto de interrogação. Isso pode ser feito por meio
de chamadas do método setter (setInt, setString, ...) apropriado para cada
tipo de parâmetro esperado pelo ponto de integerrogação. Por exemplo, se o
parâmetro esperado é do tipo long, então você fará uma chamado para o método
setLong passando dois argumentos para este método. O primeiro define a posi-
ção do parâmetro para qual será atribuído o valor (essa posição é iniciada por 1)
e o segundo argumento define o valor que será atribuído. Veja o código a seguir.

//cria um objeto PreparedStatement pstmt para executar instruções


SQL
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, 2000);
pstmt.setString(2, "DESCRICAO DO PRODUTO 2000");
int qtdRegistrosInseridos = pstmt.executeUpdate();

Quadro 45: Executando uma instrução SQL com PreparedStatement

O exemplo, a seguir, mostra como inserir um registro no banco de dados utili-


zando PreparedStatement.

PERSISTÊNCIA DE DADOS COM JPA


153

1
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.PreparedStatement;
6 import java.sql.SQLException;
7 import javax.swing.JOptionPane;
8
9 public class ExemploPreparedStatement {
10
11 private Connection con = null;
12 private String usuario = null;
13 private String senha = null;
14 private String urlConexao = null;
15 private String driverJDBC = null;
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

16
17 public ExemploPreparedStatement() {
18 driverJDBC = "org.apache.derby.jdbc.ClientDriver";
19 urlConexao = "jdbc:derby://localhost:1527/ead-bd";
20 usuario = "ead";
21 senha = "ead";
22
23 this.conectarBanco();
24 this.executarPreparedStatement();
25 this.desconectaBanco();
26 }
27
28 public static void main(String[] args) {
29 new ExemploPreparedStatement();
30 }
31
32 private void conectarBanco() {
33 try {
34 Class.forName(driverJDBC);
35 con = DriverManager.getConnection(urlConexao,
36 usuario, senha);
37 } catch (ClassNotFoundException | SQLException ex) {
38 JOptionPane.showMessageDialog(null,
ex.getMessage(),
39 "Erro ao conectar no banco",
40 JOptionPane.ERROR_MESSAGE);
41 }
42 }
43
44 private void desconectaBanco() {
45 try {
46 if (!con.isClosed()) {
47 con.close();
48 }

Executando Instruções SQL com Preparedstatement


V

49 } catch (SQLException ex) {


50 JOptionPane.showMessageDialog(null,
ex.getMessage(),
51 "Erro ao desconectar",
52 JOptionPane.ERROR_MESSAGE);
53 }
54 }
55
56 private void executarPreparedStatement() {
57 String sql = "INSERT INTO EAD.PRODUTO (ID, DESCRICAO) "
58 + " VALUES (?, ?)";

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
59 try {
60 PreparedStatement stmtProdutos = con.
prepareStatement(sql);
61 stmtProdutos.setInt(1, 2000);
62 stmtProdutos.setString(2, "DESCRICAO DO PRODUTO
2000");
63 int qtdRegistrosInseridos = stmtProdutos.
executeUpdate();
64 String saida = "Quantidade de registros inseridos:
"
65 + qtdRegistrosInseridos;
66 JOptionPane.showMessageDialog(null, saida,
67 "Registro Inserido com Sucesso",
68 JOptionPane.INFORMATION_MESSAGE);
69 } catch (SQLException ex) {
70 JOptionPane.showMessageDialog(null,
ex.getMessage(),
71 "Erro ao inserir registro",
72 JOptionPane.ERROR_MESSAGE);
73 }
74 }
75 }

Quadro 46: Inserindo um registro no banco com PreparedStatement

PERSISTÊNCIA DE DADOS COM JPA


155

RECUPERANDO E UTILIZANDO DADOS DE UM


RESULTSET

Um ResultSet consiste em uma tabela que representa um conjunto de dados


obtidos de um banco de dados por meior de uma instrução SQL executada por
Statement ou PreparedStatement.
Um objeto de ResultSet mantém um cursor para a linha corrente dos dados
selecionados. Inicialmente, este cursor fica posicionado antes da primeira linha e
para mover este cursor para a próxima linha você pode utilizar o método next
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

retornando false quando não existir mais linhas para serem percorridas no
objeto. O trecho de código a seguir obtém um ResultSet a partir da execução de
uma instrução SQL com Statement.

String sql = "select ID, DESCRICAO from EAD.PRODUTO";


Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);

ResultSet dados = stmt.executeQuery(sql);

Quadro 47: Obtendo um ResultSet

Para recuperar os valores da coluna da linha atual, você pode utilizar os méto-
dos getter fornecidos pelo objeto de ResultSet como getBoolean, getLong etc.
Para isso, você pode utilizar o número do índice (mais eficiente) da coluna ou
nome da coluna. Quando você utiliza métodos getter, o driver JDBC tenta con-
verter os dados ao tipo Java especificado no método getter retornando um valor
Java adequado. Por exemplo, se você utilizar o método getString, será retor-
nado um valor do tipo String. Veja o exemplo a seguir.

Recuperando e Utilizando Dados de um RESULTSET


V

ResultSet dados = stmt.executeQuery(sql);


dados.first();
while (!dados.isAfterLast()) {
saida += "\n" + dados.getInt(1)
+ "\t" + dados.getString(2);
dados.next();
}

Quadro 48: Recuperando informações de um ResultSet

O exemplo, a seguir, mostra como percorrer os registros obtidos do banco de


dados com Statement utilizando ResultSet.

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
1 package br.uem.ead.exemplos.jdbc.resultset;
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.sql.Statement;
8 import javax.swing.JOptionPane;
9 import javax.swing.JTextArea;
10
11 public class ExemploResultSet {
12
13 private Connection con = null;
14 private String usuario = null;
15 private String senha = null;
16 private String urlConexao = null;
17 private String driverJDBC = null;
18
19 public ExemploResultSet() {
20 driverJDBC = "org.apache.derby.jdbc.ClientDriver";
21 urlConexao = "jdbc:derby://localhost:1527/ead-bd";
22 usuario = "ead";
23 senha = "ead";
24
25 this.conectarBanco();
26 this.recuperarResultSet();
27 this.desconectaBanco();
28 }
29

PERSISTÊNCIA DE DADOS COM JPA


157

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


31 new ExemploResultSet();
32 }
33
34 private void conectarBanco() {
35 try {
36 Class.forName(driverJDBC);
37 con = DriverManager.getConnection(urlConexao,
38 usuario, senha);
39 } catch (ClassNotFoundException | SQLException ex) {
40 JOptionPane.showMessageDialog(null,
ex.getMessage(),
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

41 "Erro ao conectar no banco",


42 JOptionPane.ERROR_MESSAGE);
43 }
44 }
45
46 private void desconectaBanco() {
47 try {
48 if (!con.isClosed()) {
49 con.close();
50 }
51 } catch (SQLException ex) {
52 JOptionPane.showMessageDialog(null,
ex.getMessage(),
53 "Erro ao desconectar",
54 JOptionPane.ERROR_MESSAGE);
55 }
56 }
57
58 private void recuperarResultSet() {
59 String saida = "";
60 String sql = "select ID, DESCRICAO from EAD.PRODUTO";
61 try {
62 Statement stmt = con.createStatement(
63 ResultSet.TYPE_SCROLL_INSENSITIVE,
64 ResultSet.CONCUR_READ_ONLY);
65
66 ResultSet dados = stmt.executeQuery(sql);
67
68 if (!dados.next()) {
69 saida = "Nenhum registro cadastrado";
70 } else {
71 saida = "Recuperando pelo índice da coluna";
72 saida += "\nCódigo\tDescrição";
73

Recuperando e Utilizando Dados de um RESULTSET


V

74 dados.first();
75 while (!dados.isAfterLast()) {
76 saida += "\n" + dados.getInt(1)
77 + "\t" + dados.getString(2);
78 dados.next();
79 }
80
81 saida += "\n\nRecuperando pelo nome da
coluna";
82 saida += "\nCódigo\tDescrição";
83 dados.first();

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
84 while (!dados.isAfterLast()) {
85 saida += "\n" + dados.getInt("ID")
86 + "\t" + dados.
getString("DESCRICAO");
87 dados.next();
88 }
89 }
90
91 JTextArea saidaArea = new JTextArea();
92 saidaArea.setText(saida);
93 JOptionPane.showMessageDialog(null, saidaArea,
94 "Recuperando com ResultSet",
95 JOptionPane.INFORMATION_MESSAGE);
96 } catch (SQLException ex) {
97 JOptionPane.showMessageDialog(null,
ex.getMessage(),
98 "Erro ao recuperar registros",
99 JOptionPane.ERROR_MESSAGE);
100 }
101 }
102 }

Quadro 49: Percorrendo registros obtidos com Statement por meio de um ResultSet

O JPA – JAVA PERSISTENCE API

Bem, caro(a) aluno(a), até o momento você estudou e aprendeu como se conectar
a um banco de dados relacional e interagir com ele a fim de realizar consultas e

PERSISTÊNCIA DE DADOS COM JPA


159

persistências de dados utilizando a API JDBC. Você aprendeu a utilizar Connection


para se conectar a um banco, Statement e PreparedStatement para consultar e
atualizar informações de acordo com métodos apropriados para cada situação
e utilizou ResultSet para criar um cursor de dados e navegar por ele a fim de ler
as informações obtidas por uma consulta com Statement e PreparedStatement.
Sabe o que isto significa? Significa que você escreveu muito código que não escre-
veria se utilizasse o JPA.
O JPA ou Java Persistence API é um framework de persistência no qual per-
mite que um desenvolvedor Java realize mapeamentos objetos/relacionais para
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

o gerenciamento de dados entre uma aplicação Java e um banco de dados rela-


cional. JPA permite que o desenvolvendor trabalhe diretamente com objetos e
não com a execução de instruções SQL. Estamos falando de uma abstração de
alto nível sobre JDBC que basicamente consiste em três áreas.
■■ A API de persistência.
■■ A linguagem de consulta.
■■ Mapeamento objeto/relacional.

ENTIDADES

A partir deste momento vamos estudar os principais conceitos sobre JPA e ire-
mos aplicá-los em exemplos práticos no decorrer do nosso estudo.
O primeiro conceito que vamos estudar é o de entidades. Uma Entity (ou
em português, entidade) em JPA se refere a uma classe de entidade no qual
representa uma tabela em um banco de dados e cada instância dessa classe é
um objeto que se refere a um registro armazenado nesta tabela. Na programa-
ção em Java, o principal artefato que representa uma entidade é a Entity
Class. Entity Class é uma classe também conhecida por Classe de Entidade
em que o estado de persistência desta classe se dá pelos atributos com anota-
ções que representam um mapeamento objeto/relacional para uma tabela de
um banco de dados.

O Jpa – Java Persistence Api


V

Para que uma classe possa ser considerada uma Entity Class, ela deve seguir
os seguintes requisitos:
■■ A classe deve ser anotada como @Entity (javax.persistence.
Entity).
■■ A classe deve possuir uma chave primária podendo ser um campo único
ou uma combinação de campos.

■■ A classe deve ter o mesmo nome da tabela quando não anotada como @
Table (javax.persistence.Table). Essa anotação define o

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
nome da tabela que a Entity Class representa.
■■ A classe deve possuir um construtor público ou protegido sem argumen-
tos havendo a possibilidade de declarar outros construtores.
■■ Tanto a classe como os métodos ou atributos de persistência não podem
ser declarados com o modificador final.
■■ Uma classe de entidade pode estender outras classes de entidades e clas-
ses que não são entidades podem estender classes de entidades.
■■ Uma classe de entidade deve implementar a interface java.io.Serializable.
■■ As variáveis de instâncias devem ser declaradas com os modificadores
de acesso private ou protected permitindo ser acessados direta-
mente pelos métodos da classe.

Veja, a seguir, uma classe anotada com a anotação javax.persistence.Entity.

1 package br.uem.ead.exemplos.jpa.entidades;
2
3 import java.io.Serializable;
4 import java.math.BigDecimal;
5 import java.util.Date;
6 import javax.persistence.Entity;
7 import javax.persistence.Id;
8 import javax.persistence.Table;
9 import javax.persistence.Temporal;
10

PERSISTÊNCIA DE DADOS COM JPA


161

11 @Entity
12 @Table(name="PRODUTO")
13 public class Produto implements Serializable {
14
15 @Id
16 private long id;
17 private String descricao;
18 @Temporal(javax.persistence.TemporalType.DATE)
19 private Date dataCadastro;
20 private BigDecimal quantidadeEstoque;
21
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

22 public Produto() {
23 }
24
25 public long getId() {
26 return id;
27 }
28
29 public void setId(long id) {
30 this.id = id;
31 }
32
33 public String getDescricao() {
34 return descricao;
35 }
36
37 public void setDescricao(String descricao) {
38 this.descricao = descricao;
39 }
40
41 public Date getDataCadastro() {
42 return dataCadastro;
43 }
44
45 public void setDataCadastro(Date dataCadastro) {
46 this.dataCadastro = dataCadastro;
47 }
48
49 public BigDecimal getQuantidadeEstoque() {
50 return quantidadeEstoque;
51 }
52

O Jpa – Java Persistence Api


V

53 public void setQuantidadeEstoque(BigDecimal


quantidadeEstoque) {
54 this.quantidadeEstoque = quantidadeEstoque;
55 }
56 }

Quadro 50: Classe anotada com @Entity

Vamos analisar a classe anterior. Perceba que na linha 10 foi declarada a anotação
@Entity de javax.persistence.Entity. Quando declaramos esta anotação, a classe

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
tornou-se uma Entity Class ou Classe de Entidade e, a partir desta linha passou
a representar uma tabela em um banco de dados. Note agora que os campos ou
atributos desta classe, definidos da linha 14 a 18, são todos privados podendo ser
acessados mediante os métodos públicos da classe. Repare na linha 20, o cons-
trutor da classe também é público. Com base nestas características podemos
dizer que esta classe se trata de um POJO.
Um POJO (Plain Old Java Object) – que em português significa Velho
e Simples Objeto Java – é uma classe que realiza referência a objetos
que não dependem de herança ou quaisquer outras classes externas. São obje-
tos que seguem uma estrutura simplificada onde os construtores são default
sem argumentos e os métodos seguem o padrão getter e setter para aces-
sar os atributos privados da classe.

PRINCIPAIS ANOTAÇÕES JPA

Você já deve ter percebido até o momento que para definirmos uma classe como
entidade e os atributos desta classe como atributos de persistência foram utili-
zadas várias annotations (em português, anotações) JPA. A seguir, você vai
conhecer as principais anotações JPA e suas funcionalidades. Essas anotações
estão no pacote javax.persistence.
■■ @Entity – define que a classe em questão é uma entidade a ser persistida
em uma tabela no banco de dados. Caso esta tabela não exista o JPA cria
ela para você.

PERSISTÊNCIA DE DADOS COM JPA


163

■■ @Id – define qual atributo da classe representa uma chave primária no


banco de dados.
■■ @GeneratedValue – define estratégias para a geração automática de uma
chave primária simples.
■■ @Table – quando anotada na classe, define o nome da tabela do banco
de dados que a entidade representa. Se você não anotar a classe com @
Table(name=”nome_tabela”) o JPA irá definir o nome da tabela com o
nome da classe.
■■ @Transient – define quais atributos da classe não serão mapeados para
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

o banco de dados.
■■ @Temporal – define qual atributo será mapeado para uma coluna do tipo
temporal que pode ser Date (data), Time (tempo) ou Timestamp (carimbo
de tempo).
■■ @Enumerated – mapeia um atributo para um campo enumerado de uma
tabela onde a informação é persistida como uma string.
■■ @Column – define quais atributos da classe representam colunas de uma
tabela.
■■ @Embeddable – uma entidade com esta anotação pode ser embutida em
outra entidade.
■■ @Embedded – embuti uma entidade dentro de outra.
■■ @JoinColumn – indica que o atributo é um relacionamento para uma
outra entidade (outra tabela).
■■ @ManyToMany – define uma associação com multiplicidade de muitos
para muitos.
■■ @ManyToOne – define uma associação com valor único para outra enti-
dade com multiplicidade de muitos para um.
■■ @MappedSuperclass – os mapeamentos realizados em uma entidade com
esta anotação podem ser aplicados às entidades que herdam dela.

Veja, a seguir, uma classe mapeada com algumas das anotações vistas anterior-
mente. Memorize bem esta classe, pois mais adiante você verá um exemplo de
persistência com uma instância desta entidade.

O Jpa – Java Persistence Api


V

1 package br.uem.ead.exemplos.jpa.entidades;
2
3 import java.io.Serializable;
4 import java.util.Date;
5 import javax.persistence.Column;
6 import javax.persistence.Entity;
7 import javax.persistence.EnumType;
8 import javax.persistence.Enumerated;
9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
12 import javax.persistence.Temporal;
13 import javax.persistence.TemporalType;
14 import javax.persistence.Transient;
15
16 @Entity
17 public class Pessoa implements Serializable {
18
19 @Id
20 @GeneratedValue(strategy = GenerationType.AUTO)
21 private long id;
22 @Column(name = "nome", nullable = false, length = 60)
23 private String nomePessoa;
24 @Enumerated(EnumType.STRING)
25 @Column(name = "fis_jur", nullable = false, length = 1)
26 private TipoFisicaJuridicaEnum
27 tpFisicaJuridica = TipoFisicaJuridicaEnum.F;
28 @Temporal(TemporalType.DATE)
29 private Date dataCadastro;
30 @Transient
31 private String endereco;
32
33 public Pessoa() {
34 }
35
36 public long getId() {
37 return id;
38 }
39
40 public void setId(long id) {
41 this.id = id;
42 }
43

PERSISTÊNCIA DE DADOS COM JPA


165

44 public String getNomePessoa() {


45 return nomePessoa;
46 }
47
48 public void setNomePessoa(String nomePessoa) {
49 this.nomePessoa = nomePessoa;
50 }
51
52 public TipoFisicaJuridicaEnum getTpFisicaJuridica() {
53 return tpFisicaJuridica;
54 }
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

55
56 public void setTpFisicaJuridica(
57 TipoFisicaJuridicaEnum tpFisicaJuridica) {
58 this.tpFisicaJuridica = tpFisicaJuridica;
59 }
60
61 public Date getDataCadastro() {
62 return dataCadastro;
63 }
64
65 public void setDataCadastro(Date dataCadastro) {
66 this.dataCadastro = dataCadastro;
67 }
68
69 public String getEndereco() {
70 return endereco;
71 }
72
73 public void setEndereco(String endereco) {
74 this.endereco = endereco;
75 }
76 }

Quadro 51: Exemplo de uma EntityClass

O Jpa – Java Persistence Api


V

RELACIONAMENTOS JPA

Bem, caro(a) aluno(a), até agora você aprendeu como “dizer” para uma classe que
ela é uma entidade e como definir os atributos desta entidade como atributos de
persistência. Mas, como criamos relacionamentos entre estas entidades, assim
como é feito em um banco relacional? Ora, é simples. Para isso também existem
anotações que definem que uma determinada entidade se relaciona com outra
e vice-versa. Para ser mais preciso as anotações que definem relações ou asso-
ciações entre as entidades são quatro de acordo com a sua cardinalidade. Estas

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
associações mantêm uma forma de relação entre os objetos associados permi-
tindo que eles se comuniquem mantendo uma relação estática. As anotações de
que estamos falando são as seguintes:
@OneToOne (Um para Um) – define uma associação de um único valor
para outra entidade que possui multiplicidade de um para um. Por exemplo,
uma Cidade é governada por apenas um Prefeito e um Prefeito governa ape-
nas uma cidade.

Figura 76: Relacionamento @OneToOne

@OneToMany (Um para Muitos) – define uma associação polivalente (muitos


valores) com multiplicidade de um para muitos. Por exemplo, um veículo é diri-
gido por muitos motoristas e um motorista dirige apenas um veículo.

Figura 77: Relacionamento @OneToMany

@ManyToOne (Muitos para Um) – define uma associação com valor único
para outra entidade com multiplicidade de muitos para um. Por exemplo, um
título a pagar pertence a uma pessoa e uma pessoa possui muitos títulos a pagar.

PERSISTÊNCIA DE DADOS COM JPA


167

Figura 78: Relacionamento @ManyToOne

@ManyToMany (Muitos para Muitos) – define uma associação com multiplici-


dade de muitos para muitos. Por exemplo, uma venda possui muitos vendedores
e um vendedor realiza muitas vendas.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

Figura 79: Relacionamento @ManyToMany

Unidades de persistência (persistence unit)


A partir deste tópico você vai aprender a configurar Unidades de
Persistência em JPA. Uma unidade de persistência é um agrupamento
lógico na qual são definidas as classes de persistência como classes de entidade,
classes incorporáveis e superclasses mapeadas, assim como as configurações per-
tinentes de cada classe.
Em geral, as unidades de persistência são definidas em um arquivo .XML de
persistência chamado de persistence.xml, no qual podem ser definidas
uma ou mais unidades de persistência. Este arquivo deve ser salvo em uma pasta
chamada META-INF. Este diretório é chamado de raiz da unidade de
persistência. Veja abaixo um exemplo de configuração do persistence.xml.

O Jpa – Java Persistence Api


V

<?xml version="1.0" encoding="UTF-8"?>


<persistence version="2.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_2_0.xsd">
<persistence-unit name="UEM-EADPU" transaction-type="RESOURCE_
LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</
provider>
<class>br.uem.ead.exemplos.jpa.entidades.Produto</class>
<class>br.uem.ead.exemplos.jpa.entidades.Pessoa</class>

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
<properties>
<property name="javax.persistence.jdbc.url"
value="jdbc:derby://localhost:1527/ead-bd"/>
<property name="javax.persistence.jdbc.password"
value="ead"/>
<property name="javax.persistence.jdbc.driver" value="org.
apache.derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.user" value="ead"/>
<property name="eclipselink.ddl-generation" value="drop-
and-create-tables"/>
</properties>
</persistence-unit>
</persistence>

Quadro 52: Exemplo de um arquivo persistence.xml

Note que no exemplo acima foram adicionadas algumas informações como con-
figurações para conexão com o banco de dados. Perceba que estas configurações
definidas dentro da tag <properties></properties> pedem as mesmas infor-
mações que utilizamos quando configuramos uma conexão utilizando JDBC.
Outro ponto que você já deve ter notado é o mapeamento das classes de per-
sistência utilizando a tag <class></class>. Sempre que você anotar uma classe
com @Entity não se esqueça de mapear esta classe neste arquivo, caso contrário
ela não fará parte do contexto de persistência e não será possível realizar ope-
rações com esta entidade.

PERSISTÊNCIA DE DADOS COM JPA


169

GESTOR DE ENTIDADE (ENTITY MANAGER)

Pertencente ao pacote javax.persistence, a instância de um


EntityManager é responsável por praticamente todas as operações de persis-
tência de objetos. Esta instância está associada a um contexto de persistência que se
refere a um conjunto de instâncias de entidades administradas pelo EntityManager.
A interface EntityManager define operações que permitem interagir com o contexto
de persistência como, incluir, alterar, excluir e consultar instâncias de entidades
dentro deste contexto. Ficou confuso? Veja o exemplo a seguir.
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

1
2
3 import br.uem.ead.exemplos.jpa.entidades.Pessoa;
4 import br.uem.ead.exemplos.jpa.entidades.
TipoFisicaJuridicaEnum;
5 import java.util.Date;
6 import javax.persistence.EntityManager;
7 import javax.persistence.EntityManagerFactory;
8 import javax.persistence.Persistence;
9 import javax.swing.JOptionPane;
10
11 public class ExemploEntityManager {
12
13 public static void main(String[] args) {
14 EntityManagerFactory factory =
15 Persistence.createEntityManagerFactory("UEM-
EADPU");
16 EntityManager manager = factory.createEntityManager();
17
18 Pessoa pessoa = new Pessoa();
19 pessoa.setNomePessoa("Joao da Silva");
20 pessoa.setDataCadastro(new Date());
21 pessoa.setTpFisicaJuridica(TipoFisicaJuridicaEnum.J);
22 pessoa.setEndereco("Rua das Pedras, 101");
23
24 manager.getTransaction().begin();
25 manager.persist(pessoa);
26 manager.getTransaction().commit();
27
28 String textoSaida = "Código Pessoa: " + pessoa.getId();

O Jpa – Java Persistence Api


V

29
30 manager.close();
31 factory.close();
32
33 JOptionPane.showMessageDialog(null, textoSaida,
34 "Persistindo uma Pessoa com EntityManager",
35 JOptionPane.INFORMATION_MESSAGE);
36 }
37 }

Quadro 53: Criando um EntityManager

Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.
No exemplo anterior criamos um objeto do tipo Pessoa. Se você recordar nos
nossos exemplos anteriores, você vai lembrar que criamos uma classe Pessoa e
a anotamos com a anotação @Entity. Pois bem, utilizamos uma instância dessa
entidade e a partir de uma instância de um EntityManager nós persistimos o
objeto no banco de dados. Mas como criamos uma instância de EntityManager?
Para isso, antes precisamos criar um EntityManagerFactory relacionado
a uma Persistence Unit. Perceba na linha 14 do nosso exemplo que criamos uma
variável factory do tipo EntityManagerFactory e a ela atribuímos uma referên-
cia de EntityManagerFactory obtida por meio da expressão Pesistence.
createEntityManagerFactory("UEM-EADPU"). Note que passamos
como referência o nome da unidade de persistência criada na sessão Unidades
de Persistência (Persistence Unit) mediante uma String com
o texto UEM-EADPU. Bem, caro(a) aluno(a), agora nós já temos um fábrica
de EntityManager associado à unidade de persistência UEM-EADPU, portanto
já podemos obter um EntityManager como mostra a linha 16 do nosso exem-
plo. Perceba que utilizamos factory para criar um EntityManager por meio da
expressão factory.createEntityManager() e atribuímos o objeto
criado à variável manager do tipo EntityManager. A persistência do objeto
pessoa do tipo Pessoa ocorre na linha 25 mediante a expressão manager.
persiste(pessoa).

PERSISTÊNCIA DE DADOS COM JPA


171

CONSIDERAÇÕES FINAIS

Caro(a) aluno(a), nesta unidade você aprendeu como realizar persistência de


informações em um banco de dados relacional utilizando instruções SQL com
a API JDBC e também viu que podemos realizar de maneira diferente a persis-
tência destas mesmas informações utilizando o JPA.
Você aprendeu que nas duas situações, para se conectar a um banco de
dados, é necessário utilizar um driver JDBC de acordo com o banco utilizado
na sua aplicação e que normalmente estes drivers são fornecidos pelo próprio
Reprodução proibida. Art. 184 do Código Penal e Lei 9.610 de 19 de fevereiro de 1998.

fabricante do banco de dados.


Entre outros, os pontos mais importantes a serem considerados neste estudo
são a forma como a comunicação com o banco de dados é feita, assim como a per-
sistência das informações são realizadas utilizando JDBC e JPA. Para se conectar
a um banco de dados utilizando JDBC nós utilizamos um objeto Connection para
o qual fornecemos a URL de conexão com o banco de dados, usuário e senha
para a conexão. Já com JPA, nós podemos criar uma ou mais unidades de per-
sistências que nos possibilita configurar diversas conexões com banco de dados
distintos, também fornecendo a URL de conexão, usuário e senha, por meio de
um arquivo chamado persistence.xml. A grande diferença é que neste arquivo
também podemos definir quais são as classes de persistência para o JPA e utili-
zar os objetos destas classes para a persistência por meio de um EntityManager.

Considerações Finais
1. Como atividade de autoestudo, vamos criar um pequeno projeto e aplicar os
conceitos estudados em exemplos simples e práticos. Como IDE de desenvolvi-
mento para este projeto vamos utilizar o Netbeans. Você pode realizar o down-
load do Netbeans no seguinte endereço:
<http://netbeans.org/downloads/7.0.1/start.html?platform=windows&lang=pt_
BR&option=all>.
Agora que você realizou o download da IDE, vamos ao projeto. Abra o Netbeans e
crie um novo projeto em Arquivo => Novo Projeto. Na tela que se abre, escolha Java
na guia Categorias e Aplicação Java na guia Projetos como mostra a imagem abaixo.

Figura 80: Criando Aplicação Java

Clique em Próximo e na tela, a seguir, defina o nome do projeto como EstudoJPA e


clique em Finalizar. Ao realizar estas etapas, você deverá ter uma estrutura de proje-
to semelhante à imagem a seguir.

Figura 81: Projeto EstudoJPA criado


173

Agora que já temos um projeto criado precisamos definir um banco de dados para
nossos estudos e para isso vamos utilizar o já conhedico Derby. No Netbeans sele-
cione a aba Serviços e na estrutura de árvores selecione Banco de Dados => Java DB
e com o botão contrário do mouse clique em Iniciar Servidor. Após iniciar o servidor,
clique novamente com o botão contrário do mouse em JavaDB clique em Criar Ban-
co de Dados.

Figura 82: Iniciando servidor de banco de dados

Na tela que se abre, você irá definir o nome do banco de dados como exemplo-jpa e
o usuário e senha como jpa e clique em OK como mostra a imagem a seguir.

Figura 83: Acessando banco de dados


Neste momento seu projeto de banco de dados deve ter uma estrutura parecida
com a seguinte.

Figura 84: Estrutura do banco de dados

Agora que temos o banco de dados criado, será necessário adicionar no projeto o
Driver JDBC para o Derby. Você pode realizar o download do Driver JDBC Derby-
Client no link a seguir:
<http://repo1.maven.org/maven2/org/apache/derby/derbyclient/10.9.1.0/derby-
client-10.9.1.0.jar>.
Com o download do Driver efetuado, vamos adicioná-lo ao nosso projeto. Para isso,
selecione a aba Projetos e na pasta Bibliotecas clique com o botão contrário do mou-
se e, em seguina, na opção Adicionar JAR/Pasta... como mostra a imagem a seguir.
175

Figura 85: Adicionando arquivo JAR ao projeto

Ainda na pasta biblioteca devemos adicionar a biblioteca do JPA, para isso clique
com o botão contrário do mouse em Bibliotecas e vá em Adicionar Biblioteca...
como na imagem abaixo.

Figura 86: Adicionando bibliotecas ao projeto

Na tela que se abre, navegue pela listagem Bibliotecas Disponíveis e selecione a


biblioteca Persistência (JPA 2.0) e clique em Adicionar Biblioteca.
Após adicionar o jar do Driver JDBC Derby e a biblioteca do JPA, seu projeto deve
possuir a seguinte estrutura.
Figura 87: Adicionando driver de conexão ao Derby

Agora que já temos nosso projeto devidamente configurado, vamos criar algumas
classes de entidade? Bem, para isso precisamos definir o que nossa aplicação vai
fazer. Para nosso estudo vamos realizar o cadastro de um Estado, das Cidades deste
Estado e do Governador do Estado. Ora, então você já deve imaginar que teremos
que criar três Entity Class onde uma delas – neste caso, Estado – possuirá um mape-
amento @OneToMany para uma lista de Cidades e outro mapeamento @OneToOne
para o Governador do Estado como mostra o diagrama de classes a seguir.

Figura 88: Entidades do estudo de JPA


177

A primeira entidade que vamos criar é a Entity Class Governador. No Netbens, clique
com o botão direito do mouse e crie um pacote chamado entidades.

Figura 89: Criando Pacote Java

Agora clique com o botão contrário do mouse no pacote entidades e crie uma clas-
se Governador de acordo com a classe vista anteriormente no diagrama de classes.

Figura 90: Criando Classe Java

Veja agora como ficou a classe Governador já mapeada.


1 package estudojpa.entidades;
2
3 import javax.persistence.Column;
4 import javax.persistence.Entity;
5 import javax.persistence.GeneratedValue;
6 import javax.persistence.GenerationType;
7 import javax.persistence.Id;
8 import javax.persistence.Table;
9
10 @Entity
11 @Table(name = "governador")
12 public class Governador implements Serializable {
13
14 @Id
15 @GeneratedValue(strategy= GenerationType.AUTO)
16 private long id;
17 @Column(name="nome", nullable=false, length=60)
18 private String nome;
19
20 public Governador() {
21 }
22
23 public long getId() {
24 return id;
25 }
26
27 public void setId(long id) {
28 this.id = id;
29 }
30
31 public String getNome() {
32 return nome;
33 }
34
35 public void setNome(String nome) {
36 this.nome = nome;
37 }
38 }

Quadro 54: A classe Governador


179

Repita o mesmo processo para a classe Cidades.

1 package estudojpa.entidades;
2
3 import java.io.Serializable;
4 import javax.persistence.Column;
5 import javax.persistence.Entity;
6 import javax.persistence.GeneratedValue;
7 import javax.persistence.GenerationType;
8 import javax.persistence.Id;
9 import javax.persistence.Table;
10
11 @Entity
12 @Table(name = "cidades")
13 public class Cidades implements Serializable {
14
15 @Id
16 @GeneratedValue(strategy= GenerationType.AUTO)
17 private long id;
18 @Column(name="nome", nullable=false, length=60)
19 private String nome;
20
21 public Cidades() {
22 }
23
24 public long getId() {
25 return id;
26 }
27
28 public void setId(long id) {
29 this.id = id;
30 }
31
32 public String getNome() {
33 return nome;
34 }
35
36 public void setNome(String nome) {
37 this.nome = nome;
38 }
39 }

Quadro 55: A classe Cidades


Por último, vamos criar a classe Estados.

1 package estudojpa.entidades;
2
3 import java.io.Serializable;
4 import java.util.List;
5 import javax.persistence.CascadeType;
6 import javax.persistence.Column;
7 import javax.persistence.Entity;
8 import javax.persistence.GeneratedValue;
9 import javax.persistence.GenerationType;
10 import javax.persistence.Id;
11 import javax.persistence.OneToMany;
12 import javax.persistence.OneToOne;
13 import javax.persistence.Table;
14
15 @Entity
16 @Table(name = "estados")
17 public class Estados implements Serializable {
18
19 @Id
20 @GeneratedValue(strategy = GenerationType.AUTO)
21 private long id;
22 @Column(name = "uf", nullable = false, length = 2)
23 private String unidade_federativa;
24 @Column(name = "nome", nullable = false, length = 60)
25 private String nome;
26 @OneToMany(cascade= CascadeType.ALL)
27 private List<Cidades> cidades = new ArrayList<Cidades>();
28 @OneToOne(cascade= CascadeType.ALL)
29 private Governador governador;
30
31 public Estados() {
32 }
33
34 public long getId() {
35 return id;
36 }
37
38 public void setId(long id) {
39 this.id = id;

Quadro 56: A classe Estados


181

Neste momento seu projeto deve possuir uma estrutura parecida com a seguir.

Figura 91: Classes Java criadas

Depois de todas as classes de persistência criadas, precisamos definir a unidade de


persistência ou Persistence Unit para nossas entidades. Para isso, no Netbeans sele-
cione o projeto, clique com o botão contrário do mouse e vá em Novo => Outros.
Na tela que se abre selecione Persistência em Categorias e, em seguida, Unidade de
Persistência em Tipos de Arquivos.

Figura 92: Criando uma Unidade de Persistência


Na próxima tela, defina o nome da unidade de persistência, a biblioteca de persis-
tência e selecione o banco de dados que nós criamos no início da configuração do
nosso projeto e clique em Finalizar. Veja a imagem a seguir.

Figura 93: Nomeando a Unidade de Persistência

Após clicar em Finalizar, seu projeto deve possuir a seguinte estrutura.

Figura 94: Unidade de Persistência criada

Perceba que seu projeto agora possui uma pasta META-INF e dentro dela está o
arquivo de persistência persistence.xml. Em cima deste arquivo dê um duplo cli-
que para abri-lo, a fim de adicionarmos nele as classes de persistência que criamos
anteriormente. Perceba que será aberta uma aba com o nome do arquivo como
183

mostrado a seguir. Clique em Adicionar Classe.

Figura 95: Adicionando classes para mapeamento

Na tela que se abre, selecione as três classes e cliente em OK. Agora, você deverá ter
algo semelhante a isto.

Figura 96: Selecionando classes para mapeamento

Veja, a seguir, como ficou o XML gerado para o arquivo persistence.xml.


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="EstudoJPAPU" transaction-type="RESOURCE_
LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</
provider>
<class>estudojpa.entidades.Cidades</class>
<class>estudojpa.entidades.Estados</class>
<class>estudojpa.entidades.Governador</class>
<properties>
<property name="javax.persistence.jdbc.url"
value="jdbc:derby://localhost:1527/exemplo-jpa"/>
<property name="javax.persistence.jdbc.password"
value="jpa"/>
<property name="javax.persistence.jdbc.driver" value="org.
apache.
derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.user" value="jpa"/>
<property name="eclipselink.ddl-generation" value="create-
tables"/>
</properties>
</persistence-unit>
</persistence>

Quadro 57: Criando uma Persistence Unit

Perceba que no arquivo gerado estão mapeadas as três classes que criamos por
meio da tag <class>. E em <properties> foi configurado o banco que criamos ante-
riormente.
Agora, vamos colocar o JPA para trabalhar por nós. Para isso, vamos programar na
classe principal do projeto as regras para inserir um Estado, duas cidades e um go-
vernador para o Estado. A classe principal do nosso projeto é aquela que definimos
no início da configuração do nosso projeto, no nosso caso ela se chama EstudoJPA.
185

1 package estudojpa;
2
3 import estudojpa.entidades.Cidades;
4 import estudojpa.entidades.Estados;
5 import estudojpa.entidades.Governador;
6 import java.util.List;
7 import javax.persistence.EntityManager;
8 import javax.persistence.EntityManagerFactory;
9 import javax.persistence.Persistence;
10 import javax.swing.JOptionPane;
11
12 public class EstudoJPA {
13
14 private static final String
15 NOME_UNIDADE_PERSISTENCIA = "EstudoJPAPU";
16
17 public static void main(String[] args) {
18 String saida = "";
19 EntityManagerFactory factory =
20 Persistence.
21 createEntityManagerFactory(NOME_UNIDADE_
PERSISTENCIA);
22 EntityManager manager =
23 factory.createEntityManager();
24
25 Cidades cidLondrina = new Cidades();
26 cidLondrina.setNome("São Paulo");
27
28 Cidades cidMaringa = new Cidades();
29 cidMaringa.setNome("Maringá");
30
31 Governador gov = new Governador();
32 gov.setNome("Beto Richa");
33
34 Estados ufPR = new Estados();
35 ufPR.setUnidade_federativa("PR");
36 ufPR.setGovernador(gov);
37 ufPR.setNome("Paraná");
38 ufPR.getCidades().add(cidMaringa);
39 ufPR.getCidades().add(cidLondrina);
40
41 manager.getTransaction().begin();
42 manager.persist(ufPR);
43 manager.getTransaction().commit();
44
45 saida += "Dados do Estado:";
46 saida += " \nId: " + ufPR.getId();
47 saida += " \nNome: " + ufPR.getNome();
48 saida += " \nUF: " + ufPR.getUnidade_federativa();
49 saida += " \nId Governador: " + ufPR.getGovernador().
getId();
50 saida += " \nNome Governador: " +
51 ufPR.getGovernador().getNome();
52 saida += " \n\nCidades do Estado : " + ufPR.getNome();
53
54 List<Cidades> listaCidades = ufPR.getCidades();
55
56 for (int i = 0; i < listaCidades.size(); i++) {
57 Cidades cidades = listaCidades.get(i);
58
59 saida += " \nId: " + cidades.getId()
60 + " - Nome: " + cidades.getNome();
61
62 }
63
64 manager.close();
65 factory.close();
66
67 JOptionPane.showMessageDialog(null, saida,
68 "Estudo JPA", JOptionPane.INFORMATION_MESSAGE);
69 }
70 }

Quadro 58: A classe EstudoJPA

Na classe acima nós obtemos na linha 22 um EntityManager a partir de uma factory


obtida por um EntityManagerFactory. Em seguida, criamos duas cidades nas linhas
25 a 29 e na linha 31 a 32 definimos um governador. A criação do estado está sendo
realizada entre as linhas 34 e 39. Perceba que na linha 36 vinculamos o governador
ao estado e nas linhas 38 a 39 as cidades. Note que na linha 42 realizamos a persis-
tência apenas do objeto ufPR e não realizamos a persistência dos demais objetos.
Bem, na verdade realizamos sim. Quando realizamos o mapeamento da classe Es-
187

tados foi definido a expressão cascade= CascadeType.ALL nas associações @OneTo-


Many e @OneToOne e então a mágica foi feita. O que aconteceu foi que ao persistir
o objeto ufPR, está ação também foi realizada em cascata para todos os objetos
relacionados com estado, no nosso foi realizada a persistência das duas cidades e a
do governador. Veja, a seguir, a execução da nossa aplicação.

Figura 97: Saída do exemplo de Estudo JPA

Agora veja como ficou a estrutura do banco de dados depois que o JPA entrou em
ação. Você se lembra de ter criado alguma instrução SQL para criar as tabelas? Eu
também não lembro e mesmo assim elas estão lá.
Figura 98: Estrutura do banco de dados do Estudo JPA
MATERIAL COMPLEMENTAR

Introdução ao JPA – Parte 1


Fonte: <http://www.youtube.com/watch?v=51hLBSp6tF0>.
Introdução ao JPA – Parte 2
Fonte: <http://www.youtube.com/watch?v=A68WjOFOyzE>.
Introdução ao JPA – Parte 3
Fonte: <http://www.youtube.com/watch?v=IbbpXZU97bM>.
Introdução ao JPA – Parte 4
Fonte: <http://www.youtube.com/watch?v=e78Jb4naNQA>.
Introdução ao JPA – Parte 5
Fonte: <http://www.youtube.com/watch?v=O03ialWcZJc>.

Quando necessitar de agilidade no desenvolvimento de aplicações com


acesso a banco de dados, não tenha dúvidas em escolher JPA ao invés de
JDBC. Com JPA não há necessidade de criar instruções SQL, seja para consul-
ta ou persistência de informações em um banco de dados.

Introdução à Java Persistence API (JPA)


Por Wendell M. Sacramento
O JPA é um framework utilizado na camada de persistência para o desenvolvedor ter uma maior
produtividade, com impacto principal em um modo para controlarmos a persistência dentro
de Java. Pela primeira vez, nós, desenvolvedores temos um modo “padrão” para mapear nossos
objetos para os do Banco de Dados. Persistência é uma abstração de alto-nível sobre JDBC.
Saiba mais sobre o assunto no artigo completo.
Fonte: <http://www.devmedia.com.br/introducao-a-java-persistence-api-jpa/4590>. Acesso em:
03 abr. 2013

Material Complementar
CONCLUSÃO

Neste livro busquei mostrar a você conceitos mais avançados em programação com
a linguagem Java. A fim de possibilitar o seu entendimento, a unidade I apresentou
os conceitos de sobreposição e sobrecarga, muito úteis na estruturação do projeto
OO Java e futuras manutenções.
Na unidade II, trabalhamos classes abstratas e interfaces por meio do conceito de
programação por interfaces e contratos. Esses conceitos são muito poderosos para
resolver um grande número de padrões de projeto existentes.
A unidade III foi dedicada exclusivamente a arrays e coleções Java. Várias coleções
como List, Set e Map foram tratadas, bem como os conceitos essenciais sobre arrays
Java.
Na unidade IV apresentei os principais conceitos sobre a criação de interfaces gráfi-
cas com o cliente e tratamento de exceções. Interfaces gráficas foram implementa-
das por meio da biblioteca Swing e respectivos eventos.
E, para finalizar, vimos na unidade V os conceitos sobre persistência de objetos Java
por meio das APIs JDBC e JPA. JPA é uma poderosa biblioteca que permite o mape-
amento objeto-relacional entre objetos Java e um sistema gerenciador de banco
de dados relacional ou objeto-relacional, a fim de facilitar o desenvolvimento do
modelo de dados de uma aplicação.
Espero ter alcançado o objetivo inicial deste livro, que era apresentar conceitos mais
avançados em programação Java. Desejo que você seja muito feliz profissionalmen-
te utilizando os conceitos apresentados aqui e se puder ajudar de alguma forma,
estou a sua disposição.
Prof. Dr. Edson A. Oliveira Junior
191
GABARITO

UNIDADE I
1. O exercício tem seu escopo bastante aberto. Dentro desse exercício são possí-
veis diversas implementações corretas. O conceito a ser firmado com ele era a
possibilidade que a linguagem JAVA oferece de termos mais de um método com
o mesmo nome, desde que com assinaturas (retorno e sequência de parâme-
tros) diferentes.
Aproveitei para, na solução passada, utilizar os métodos de forma com que eles
pudessem ser reaproveitados dentro da própria resolução. Pensem nisso!

package br.edu.unicesumar.gabaritojavaii.unidade1.exercicio3;

public class ValidaImpostos {


public static double calculaImpostos(double valorBase,
String nomeImposto){
double taxaBase = calculaImpostos(nomeImposto);
double valorImposto = (valorBase*taxaBase/100);

return valorImposto;
}

public static double calculaImpostos(String nomeImposto){


double impostoRetorno = 0;
switch (nomeImposto.toUpperCase()){
case "INSS":
impostoRetorno = 8;
break;
case "IR":
impostoRetorno = 20;
break;
}

return impostoRetorno;
}
}
GABARITO

Também montei uma classe de exemplo para testarmos nosso código. No exem-
plo a seguir, tomei como base o cálculo dos impostos no salário:
package br.edu.unicesumar.gabaritojavaii.unidade1.exercicio3;

public class TestaImposto {


public static void main (String[] args){
//Calcula o imposto com base no meu salário
double taxaBaseINSS = ValidaImpostos.calculaImpos-
tos("INSS");
double valorImpostoINSS = ValidaImpostos.calculaImpos-
tos(2000, "INSS");

System.out.println("A taxa base para o INSS *" + taxa-


BaseINSS + "*");
System.out.println("O INSS para um valor de 2000 é de:
*" + valorImpostoINSS + "*");
}
}
193
GABARITO

2. Nesse exercício, podemos perceber que os construtores, como os outros méto-


dos, também podem sofrer sobreposição, desde que não haja mais de um cons-
trutor com a mesma assinatura.

package br.edu.unicesumar.gabaritojavaii.unidade1.exercicio4;

public class Fornecedor {


private int _codigo;
private String _razaoSocial;

public Fornecedor(){

public Fornecedor (int codigo, String razaoSocial){


_codigo = codigo;
_razaoSocial = razaoSocial;
}

public int getCodigo() {


return _codigo;
}
public void setCodigo(int codigo) {
this._codigo = codigo;
}
public String getRazaoSocial() {
return _razaoSocial;
}
}
GABARITO

Testando o código anterior:

package br.edu.unicesumar.gabaritojavaii.unidade1.exercicio4;

public class TestaFornecedor {


public static void main (String[] args){
Fornecedor fornecedor1 = new Fornecedor();

Fornecedor fornecedor2 = new Fornecedor(1, "Fornecedor


especial");

System.out.println("O código é: *" + fornecedor1.getCo-


digo() + "* para o fonecedor: *"
+ fornecedor1.getRazaoSocial() + "*");
System.out.println("O código é: *" + fornecedor2.getCo-
digo() + "* para o fonecedor: *"
+ fornecedor2.getRazaoSocial() + "*");
}
}

3. Resposta: a. O código não compila, pois o conteúdo da linha 6 não pode estar
entre o bloco de try{} e de catch{}.

4. Resposta: sim. Não compila, pois Arithimetic Exception estende Exception, por-
tanto, colocando-o depois o código nunca seria executado.
195
GABARITO

UNIDADE II
1. A proposta deste exercício era julgar algumas assertivas com base no código
proposto. Irei detalhar cada uma delas na sequência:
a) O código será compilado sem alterações.
VERDADEIRA. O código não apresenta nenhum problema de sintaxe que im-
possibilite a publicação.
b) A classe MiniCarro criará uma declaração abstract do metodo2() ou imple-
mentará esse método para permitir que o código seja compliado.
FALSA. Não há a necessidade de que o metodo2() seja implementado na resolu-
ção apresentada do código.
c) É válido, mas não necessário que a classe MiniCarro crie uma declaração abs-
trata do método metodo2() ou implemente esse método para permitir que o
código seja compilado.
FALSA. Não há necessidade de executar nenhum dos procedimentos sugeridos
para que o código compile.
d) Já que a linha 8 existe, a classe Automovel deve declarar o método metodo1()
de alguma maneira.
FALSA. Nesse caso, o método abstrato não precisa ser implementado na classe
“Minicarro”, pois a classe também é abstrata.
e) Se a linha 6 fosse substituída por “MiniCarro extends Automovel { “ o código
seria compilado.
FALSA. O código já é compilado, portanto não é necessário fazer a mudança. Se
fizermos a mudança sugerida, iremos perceber que o código irá parar de com-
pilar, pois ao deixar de ser abstrata, a classe “Minicarro” precisaria implementar
o metodo1().
f ) Se a classe Automovel não fosse abstrata e o método metodo1() da linha 2
fosse implementado, o código não seria compilado.
FALSA. Se a classe não fosse abstrata ao implementar o método 1, o sistema não
apresentaria nenhum erro.
GABARITO

2. Marque somente as verdadeiras:


( ) Toda classe que possui um método abstrato é obrigatoriamente uma classe
abstrata.
VERDADEIRO. O inverso porém não é verdadeiro, classes abstratas podem con-
ter métodos não abstratos, porém não terão utilidade.
( ) Uma classe abstrata pode ter métodos não abstratos (não marcados com a
palavra-chave abstract).
VERDADEIRO.
( ) Para se evitar erros de compilação, todo método de uma interface necessita
ser marcado com a palavra-chave abstract.
FALSO. Métodos abstratos são exclusividade de classes abstratas.
( ) Tanto classes abstratas quanto interfaces necessitam possuir um método ou
variável.
FALSO. O fato de não possuir variáveis ou métodos não irá causar nenhum erro
de compilação, porém não irá ter utilidade no seu código.
( ) Uma classe não abstrata que herda de uma classe abstrata obrigatoriamente
deve implementar todos seus métodos herdados.
VERDADEIRO. Caso seja uma outra classe abstrata, essa obrigatoriedade não é
verdadeira.

3. Três das opções são assinaturas de métodos válidos em uma interface. Quais?
(Selecione três).
Resposta: b, c, e.
a) private int getArea( );
Métodos privados não podem conter assinatura privada.
d) public static void main (String [ ] args);
Assinaturas não aceitam o modificador static.

4. Interfaces devem conter apenas assinaturas de método e o exemplo possui um


método implementado.
197
GABARITO

UNIDADE III
1. Três das declarações de Arrays são válidas. Selecione quais.
Resposta: a, c, d.
b) [ ] int idade;
e) [ ] threads Thread;
Essas opções são inválidas. JAVA não aceita a declaração de [] na frente do tipo
de variável.

2. Linha 13. Quando ele tenta acessar texto[10], o sistema aciona uma exceção de
que a posição acessada não existe. Quando declaramos “String[] texto = new
String[10];” ele irá criar somente até o indíce 9.

3. Segundo o pacote java.util.*, quais as interfaces que implementam diretamente


a interface Collection?
Resposta: a, c, d, e.
Nesse link, temos um guia completo sobre a classe collection em JAVA.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html

UNIDADE IV
1. Apenas criar a GUI como a imagem.
REFERÊNCIAS

BAUER, Christian; KING, Gavin. Java Persistence com Hibernate. Ciência Moderna,
2007.
CORNELL, Gary; HORSTMANN, Cay S. Core Java. V. 2 – Advanced Features. Prentice
Hall, 2008.
DEITEL, Harvey M. Java – Como Programar. 8. ed. Prentice Hall Brasil, 2010.
GAMMA, Erich; JOHNSON, Ralph; VLISSIDES, John. Padrões de Projeto. Bookman,
2005.
HORSTMANN, Cay S; CORNELL, Gary. Core Java. V. 1 – Fundamentos. 8. ed. Pearson,
2010.
SIERRA, Kathy; BATES, Bert. Use A Cabeça! – Java. 2. ed. Alta Books, 2008.
199
ANOTAÇÕES
ANOTAÇÕES

Você também pode gostar