Você está na página 1de 118

D EPARTAMENTO DE E NGENHARIA DE C OMPUTAO E AUTOMAO I NDUSTRIAL

FACULDADE DE E NGENHARIA E LTRICA E

DE

C OMPUTAO

U NIVERSIDADE E STADUAL DE C AMPINAS

Programao Orientada a Objetos:


Uma Abordagem com Java

Ivan Luiz Marques Ricarte

2001

Sumrio
1 Fundamentos da programao orientada a objetos
1.1 Classes . . . . . . . . . . . . . . . . . . . . .
1.2 Objetos . . . . . . . . . . . . . . . . . . . . .
1.3 Herana . . . . . . . . . . . . . . . . . . . . .
1.4 Polimorfismo . . . . . . . . . . . . . . . . . .

.
.
.
.

2 Princpios da programao na linguagem Java


2.1 Tipos primitivos . . . . . . . . . . . . . . . . . .
2.2 Identificadores . . . . . . . . . . . . . . . . . . .
2.3 Expresses . . . . . . . . . . . . . . . . . . . .
2.3.1 Expresses retornando valores numricos
2.3.2 Expresses retornando valores booleanos
2.3.3 Outros tipos de expresses . . . . . . . .
2.3.4 Controle do fluxo de execuo . . . . . .
2.3.5 Comentrios . . . . . . . . . . . . . . .
2.4 Operaes sobre objetos . . . . . . . . . . . . .
2.4.1 Arranjos . . . . . . . . . . . . . . . . . .
2.4.2 Strings . . . . . . . . . . . . . . . . . .
2.5 Classes em Java . . . . . . . . . . . . . . . . . .
2.5.1 Pacotes . . . . . . . . . . . . . . . . . .
2.5.2 Definio de classes em Java . . . . . . .
2.5.3 O mtodo main . . . . . . . . . . . . .
2.5.4 Visibilidade da classe e seus membros . .
2.5.5 Classes derivadas . . . . . . . . . . . . .
2.5.6 Classes abstratas e finais . . . . . . . . .
2.5.7 Interfaces . . . . . . . . . . . . . . . . .
2.6 Excees . . . . . . . . . . . . . . . . . . . . .
2.6.1 Tratamento de excees . . . . . . . . .
2.6.2 Erros e excees de runtime . . . . . . .
2.6.3 Propagando excees . . . . . . . . . . .
2.6.4 Definindo e gerando excees . . . . . .
2.7 O ambiente de Java . . . . . . . . . . . . . . . .
2.7.1 Ferramentas do Java SDK . . . . . . . .
2.7.2 Gerao de cdigo porttil . . . . . . . .

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

3
3
4
6
6

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

8
8
10
11
11
12
13
13
15
16
18
19
20
20
21
24
25
25
27
28
29
30
31
32
32
33
34
34

Programao orientada a objetos com Java

2.7.3

Sumrio

Desenvolvimento de aplicaes . . . . . . . . . . . . . . . . . . . . . . . .

3 Uso das classes da API padro de Java


3.1 Funcionalidades bsicas . . . . . .
3.2 Entrada e sada . . . . . . . . . .
3.2.1 Transferncia de texto . .
3.2.2 Transferncia de bytes . .
3.2.3 Manipulao de arquivos .
3.2.4 Serializao . . . . . . . .
3.3 Framework de colees . . . . . .
3.4 Extenses padronizadas . . . . . .

35

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

37
37
38
39
40
41
42
43
45

4 Desenvolvimento de aplicaes grficas


4.1 Apresentao grfica . . . . . . . .
4.2 Interfaces grficas com usurios . .
4.2.1 Eventos da interface grfica
4.2.2 Componentes grficos . . .
4.2.3 Containers . . . . . . . . .
4.2.4 Janelas . . . . . . . . . . .
4.2.5 Gerenciadores de layout . .
4.3 Desenvolvimento de applets . . . .
4.3.1 Criao de applet . . . . . .
4.3.2 Execuo de applets . . . .
4.3.3 Passagem de parmetros . .
4.3.4 Contexto de execuo . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

46
46
47
47
50
54
55
57
65
66
67
68
69

5 Desenvolvimento de aplicaes distribudas


5.1 Programao cliente-servidor . . . . . . . .
5.1.1 Conceitos preliminares . . . . . . .
5.1.2 Aplicaes TCP/IP . . . . . . . . .
5.1.3 Aplicaes UDP . . . . . . . . . .
5.1.4 Aplicaes HTTP . . . . . . . . . .
5.2 Acesso a bancos de dados . . . . . . . . . .
5.2.1 Bancos de dados relacionais . . . .
5.2.2 SQL . . . . . . . . . . . . . . . . .
5.2.3 JDBC . . . . . . . . . . . . . . . .
5.3 Servlets . . . . . . . . . . . . . . . . . . .
5.3.1 Ciclo de vida de um servlet . . . . .
5.3.2 Fundamentos da API de servlets . .
5.4 Programao com objetos distribudos . . .
5.4.1 Arquiteturas de objetos distribudos
5.4.2 Java RMI . . . . . . . . . . . . . .
5.4.3 Java IDL . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

72
. 72
. 73
. 75
. 79
. 81
. 83
. 84
. 85
. 87
. 90
. 91
. 92
. 94
. 94
. 96
. 113

A Palavras chaves de Java

c 2001 FEEC/UNICAMP

117

Captulo 1

Fundamentos da programao orientada


a objetos
Neste captulo so apresentados os conceitos bsicos que permeiam o uso das tcnicas de orientao a objetos na programao, sempre utilizando a linguagem Java como motivador.
Objetos so instncias de classes, que determinam qual informao um objeto contm e como ele
pode manipul-la.
Um dos grandes diferenciais da programao orientada a objetos em relao a outros paradigmas
de programao que tambm permitem a definio de estruturas e operaes sobre essas estruturas
est no conceito de herana, mecanismo atravs do qual definies existentes podem ser facilmente
estendidas. Juntamente com a herana deve ser enfatizada a importncia do polimorfismo, que permite selecionar funcionalidades que um programa ir utilizar de forma dinmica, durante sua execuo.

1.1

Classes

A definio de classes e seus inter-relacionamentos o principal resultado da etapa de projeto de


software. Em geral, esse resultado expresso em termos de alguma linguagem de modelagem, tal
como UML.
Uma classe um gabarito para a definio de objetos. Atravs da definio de uma classe,
descreve-se que propriedades ou atributos o objeto ter.
Alm da especificao de atributos, a definio de uma classe descreve tambm qual o comportamento de objetos da classe, ou seja, que funcionalidades podem ser aplicadas a objetos da classe.
Essas funcionalidades so descritas atravs de mtodos. Um mtodo nada mais que o equivalente
a um procedimento ou funo, com a restrio que ele manipula apenas suas variveis locais e os
atributos que foram definidos para a classe.
Uma vez que estejam definidas quais sero as classes que iro compor uma aplicao, assim
como qual deve ser sua estrutura interna e comportamento, possvel criar essas classes em Java.
Na Unified Modeling Language (UML), a representao para uma classe no diagrama de classes
tipicamente expressa na forma grfica, como mostrado na Figura 1.1.
Como se observa nessa figura, a especificao de uma classe composta por trs regies: o nome
da classe, o conjunto de atributos da classe e o conjunto de mtodos da classe.

Programao orientada a objetos com Java

1.2. Objetos

NomeClasse

vi si bili dade nomeAtri buto : ti po = val or def aul t


...
vi si bili dade nomeAtri buto : ti po = val or def aul t
vi si bili dade nomeMtodo(li staArgumentos) : ti poRetorno
...
vi si bili dade nomeMtodo(li staArgumentos) : ti poRetorno

Figura 1.1: Uma classe em UML.

O nome da classe um identificador para a classe, que permite referenci-la posteriormente


por exemplo, no momento da criao de um objeto.
O conjunto de atributos descreve as propriedades da classe. Cada atributo identificado por
um nome e tem um tipo associado. Em uma linguagem de programao orientada a objetos pura, o
tipo o nome de uma classe. Na prtica, a maior parte das linguagens de programao orientada a
objetos oferecem um grupo de tipos primitivos, como inteiro, real e carter, que podem ser usados na
descrio de atributos. O atributo pode ainda ter um valor_default opcional, que especifica um valor
inicial para o atributo.
Os mtodos definem as funcionalidades da classe, ou seja, o que ser possvel fazer com objetos
dessa classe. Cada mtodo especificado por uma assinatura, composta por um identificador para
o mtodo (o nome do mtodo), o tipo para o valor de retorno e sua lista de argumentos, sendo cada
argumento identificado por seu tipo e nome.
Atravs do mecanismo de sobrecarga (overloading), dois mtodos de uma classe podem ter o
mesmo nome, desde que suas assinaturas sejam diferentes. Tal situao no gera conflito pois o
compilador capaz de detectar qual mtodo deve ser escolhido a partir da anlise dos tipos dos
argumentos do mtodo. Nesse caso, diz-se que ocorre a ligao prematura (early binding) para o
mtodo correto.
O modificador de visibilidade pode estar presente tanto para atributos como para mtodos. Em
princpio, trs categorias de visibilidade podem ser definidas:
pblico, denotado em UML pelo smbolo +: nesse caso, o atributo ou mtodo de um objeto dessa
classe pode ser acessado por qualquer outro objeto (visibilidade externa total);
privativo, denotado em UML pelo smbolo -: nesse caso, o atributo ou mtodo de um objeto dessa
classe no pode ser acessado por nenhum outro objeto (nenhuma visibilidade externa);
protegido, denotado em UML pelo smbolo #: nesse caso, o atributo ou mtodo de um objeto dessa
classe poder ser acessado apenas por objetos de classes que sejam derivadas dessa atravs do
mecanismo de herana (ver Seo 1.3).

1.2

Objetos

Objetos so instncias de classes. atravs deles que (praticamente) todo o processamento ocorre
em sistemas implementados com linguagens de programao orientadas a objetos. O uso racional de
c 2001 FEEC/UNICAMP

Programao orientada a objetos com Java

1.2. Objetos

objetos, obedecendo aos princpios associados sua definio conforme estabelecido no paradigma
de desenvolvimento orientado a objetos, chave para o desenvolvimento de sistemas complexos e
eficientes.
Um objeto um elemento que representa, no domnio da soluo, alguma entidade (abstrata ou
concreta) do domnio de interesse do problema sob anlise. Objetos similares so agrupados em
classes.
No paradigma de orientao a objetos, tudo pode ser potencialmente representado como um
objeto. Sob o ponto de vista da programao orientada a objetos, um objeto no muito diferente de
uma varivel normal. Por exemplo, quando define-se uma varivel do tipo int em uma linguagem
de programao como C ou Java, essa varivel tem:




um espao em memria para registrar o seu estado (valor);


um conjunto de operaes que podem ser aplicadas a ela, atravs dos operadores definidos na
linguagem que podem ser aplicados a valores inteiros.

Da mesma forma, quando se cria um objeto, esse objeto adquire um espao em memria para
armazenar seu estado (os valores de seu conjunto de atributos, definidos pela classe) e um conjunto
de operaes que podem ser aplicadas ao objeto (o conjunto de mtodos definidos pela classe).
Um programa orientado a objetos composto por um conjunto de objetos que interagem atravs
de trocas de mensagens. Na prtica, essa troca de mensagem traduz-se na aplicao de mtodos a
objetos.
As tcnicas de programao orientada a objetos recomendam que a estrutura de um objeto e a
implementao de seus mtodos devem ser to privativos como possvel. Normalmente, os atributos
de um objeto no devem ser visveis externamente. Da mesma forma, de um mtodo deve ser suficiente conhecer apenas sua especificao, sem necessidade de saber detalhes de como a funcionalidade
que ele executa implementada.
Encapsulao o princpio de projeto pelo qual cada componente de um programa deve agregar
toda a informao relevante para sua manipulao como uma unidade (uma cpsula). Aliado ao
conceito de ocultamento de informao, um poderoso mecanismo da programao orientada a
objetos.
Ocultamento da informao o princpio pelo qual cada componente deve manter oculta sob
sua guarda uma deciso de projeto nica. Para a utilizao desse componente, apenas o mnimo
necessrio para sua operao deve ser revelado (tornado pblico).
Na orientao a objetos, o uso da encapsulao e ocultamento da informao recomenda que a
representao do estado de um objeto deve ser mantida oculta. Cada objeto deve ser manipulado exclusivamente atravs dos mtodos pblicos do objeto, dos quais apenas a assinatura deve ser revelada.
O conjunto de assinaturas dos mtodos pblicos da classe constitui sua interface operacional.
Dessa forma, detalhes internos sobre a operao do objeto no so conhecidos, permitindo que o
usurio do objeto trabalhe em um nvel mais alto de abstrao, sem preocupao com os detalhes internos da classe. Essa facilidade permite simplificar a construo de programas com funcionalidades
complexas, tais como interfaces grficas ou aplicaes distribudas.

c 2001 FEEC/UNICAMP

Programao orientada a objetos com Java

1.3

1.3. Herana

Herana

O conceito de encapsular estrutura e comportamento em um tipo no exclusivo da orientao a


objetos; particularmente, a programao por tipos abstratos de dados segue esse mesmo conceito. O
que torna a orientao a objetos nica o conceito de herana.
Herana um mecanismo que permite que caractersticas comuns a diversas classes sejam fatoradas em uma classe base, ou superclasse. A partir de uma classe base, outras classes podem ser
especificadas. Cada classe derivada ou subclasse apresenta as caractersticas (estrutura e mtodos) da
classe base e acrescenta a elas o que for definido de particularidade para ela.
H vrias formas de relacionamentos em herana:
Extenso: a subclasse estende a superclasse, acrescentando novos membros (atributos e/ou mtodos). A superclasse permanece inalterada, motivo pelo qual este tipo de relacionamento
normalmente referenciado como herana estrita.
Especificao: a superclasse especifica o que uma subclasse deve oferecer, mas no implementa nenhuma funcionalidade. Diz-se que apenas a interface (conjunto de especificao dos mtodos
pblicos) da superclasse herdada pela subclasse.
Combinao de extenso e especificao: a subclasse herda a interface e uma implementao padro de (pelo menos alguns de) mtodos da superclasse. A subclasse pode ento redefinir
mtodos para especializar o comportamento em relao ao que oferecido pela superclasse,
ou ter que oferecer alguma implementao para mtodos que a superclasse tenha declarado
mas no implementado. Normalmente, este tipo de relacionamento denominado herana
polimrfica.
A ltima forma , sem dvida, a que mais ocorre na programao orientada a objetos.
Algumas modelagens introduzem uma forma de herana conhecida como contrao. Contrao
uma uma variante de herana onde a subclasse elimina mtodos da superclasse com o objetivo de
criar uma classe mais simples. A eliminao pode ocorrer pela redefinio de mtodos com corpo
vazio. O problema com este mecanismo que ele viola o princpio da substituio, segundo o qual
uma subclasse deve poder ser utilizada em todos os pontos onde a superclasse poderia ser utilizada.
Se a contrao parece ser uma soluo adequada em uma hierarquia de classes, provavelmente a
hierarquia deve ser re-analisada para deteco de inconsistncias (problema pssaros-pinguins). De
modo geral, o mecanismo de contrao deve ser evitado.

1.4

Polimorfismo

Polimorfismo o princpio pelo qual duas ou mais classes derivadas de uma mesma superclasse
podem invocar mtodos que tm a mesma identificao (assinatura) mas comportamentos distintos,
especializados para cada classe derivada, usando para tanto uma referncia a um objeto do tipo da
superclasse. Esse mecanismo fundamental na programao orientada a objetos, permitindo definir
funcionalidades que operem genericamente com objetos, abstraindo-se de seus detalhes particulares
quando esses no forem necessrios.

c 2001 FEEC/UNICAMP

Programao orientada a objetos com Java

1.4. Polimorfismo

Para que o polimorfismo possa ser utilizado, necessrio que os mtodos que estejam sendo
definidos nas classes derivadas tenham exatamente a mesma assinatura do mtodo definido na superclasse; nesse caso, est sendo utilizado o mecanismo de redefinio de mtodos (overriding). Esse
mecanismo de redefinio muito diferente do mecanismo de sobrecarga de mtodos, onde as listas
de argumentos so diferentes.
No caso do polimorfismo, o compilador no tem como decidir qual o mtodo que ser utilizado
se o mtodo foi redefinido em outras classes afinal, pelo princpio da substituio um objeto de
uma classe derivada pode estar sendo referenciado como sendo um objeto da superclasse. Se esse for
o caso, o mtodo que deve ser selecionado o da classe derivada e no o da superclasse.
Dessa forma, a deciso sobre qual dos mtodos mtodo que deve ser selecionado, de acordo com
o tipo do objeto, pode ser tomada apenas em tempo de execuo, atravs do mecanismo de ligao
tardia. O mecanismo de ligao tardia tambm conhecido pelos termos em ingls late binding,
dynamic binding ou ainda run-time binding.

c 2001 FEEC/UNICAMP

Captulo 2

Princpios da programao na linguagem


Java
No restante deste texto, os princpios da programao orientada a objetos so exercitados atravs
de exemplos na linguagem de programao Java. Como qualquer linguagem de programao, Java
tem regras estritas indicando como programas devem ser escritos. bom ter familiaridade com
essa sintaxe da linguagem, aprendendo a reconhecer e definir os tipos primitivos, identificadores e
expresses em Java.
Merece ateno parte, para quem no tem familiaridade com o conceito de excees, o estudo
deste mecanismo oferecido por Java para detectar e tratar situaes de erro segundo os princpios da
orientao a objetos.

2.1

Tipos primitivos

Em Java, so oferecidos tipos literais primitivos (no objetos) para representar valores booleanos,
caracteres, numricos inteiros e numricos em ponto flutuante.
Variveis do tipo boolean podem assumir os valores true ou false. O valor default para um
atributo booleano de uma classe, se no especificado, false. Uma varivel do tipo boolean
ocupa 1 bit de armazenamento.
Variveis booleanas e variveis inteiras, ao contrrio do que ocorre em C e C++, no so compatveis em Java. Assim, no faz sentido atribuir uma varivel booleana a uma varivel inteira ou usar
um valor inteiro no contexto de uma condio de teste.
Exemplo de declarao e uso:
boolean deuCerto;
deuCerto = true;
Combinando definio e inicializao,
boolean deuCerto = true;
Uma varivel do tipo char contm um carter Unicode1 , ocupando 16 bits de armazenamento
1

Unicode um padro internacional para a representao unificada de caracteres de diversas linguagens; para maiores
informaes, http://www.unicode.org/.

Programao orientada a objetos com Java

2.1. Tipos primitivos

em memria. O valor default de um atributo de classe do tipo char, se no especificado, o carter


NUL (cdigo hexadecimal 0000).
Um valor literal do tipo carter representado entre aspas simples (apstrofes), como em:
char umCaracter = A;
Nesse caso, a varivel ou atributo umCaracter recebe o carter A, correspondente ao cdigo
hexadecimal 0041 ou valor decimal 65.
Valores literais de caracteres podem tambm ser representados por seqncias de escape, como
em \n (o carter newline). A lista de seqncias de escape reconhecidas em Java apresentada
na Tabela 2.1.
\b
\t
\n
\f
\r
\"
\
\\
\xxx
\uxxxx

backspace
tabulao horizontal
newline
form feed
carriage return
aspas
aspas simples
contrabarra
o carter com cdigo de valor octal xxx, que pode assumir valores entre 000 e 377 na representao octal
o carter Unicode com cdigo de valor hexadecimal xxxx, onde
xxxx pode assumir valores entre 0000 e ffff na representao
hexadecimal.

Tabela 2.1: Caracteres representados por seqncias de escape.

Seqncias de escape Unicode (precedidas por \u) so processadas antes das anteriores, podendo
aparecer no apenas em variveis caracteres ou strings (como as outras seqncias) mas tambm em
identificadores da linguagem Java.
Valores numricos inteiros em Java podem ser representados por variveis do tipo byte, short,
int ou long. Todos os tipos contm valores inteiros com sinal, com representao interna em complemento de dois. O valor default para atributos desses tipos 0.
Cada um desses tipos de dados tem seu espao de armazenamento definido na especificao da
linguagem, no sendo dependente de diferentes implementaes. Variveis do tipo byte ocupam 8
bits de armazenamento interno. Com esse nmero de bits, possvel representar valores na faixa de 128 a +127. Variveis do tipo short ocupam 16 bits, podendo assumir valores na faixa de -32.768 a
+32.767. Variveis do tipo int ocupam 32 bits, podendo assumir valores na faixa de -2.147.483.648
a +2.147.483.647. Finalmente, variveis do tipo long ocupam 64 bits, podendo assumir valores na
faixa de -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807.
Constantes literais do tipo long podem ser identificadas em cdigo Java atravs do sufixo l ou L,
como em
long valorQuePodeCrescer = 100L;
c 2001 FEEC/UNICAMP

Programao orientada a objetos com Java

2.2. Identificadores

Ao contrrio do que ocorre em C, no h valores inteiros sem sinal (unsigned) em Java. Adicionalmente, as combinaes da forma long int ou short int so invlidas em Java.
Valores reais, com representao em ponto flutuante, podem ser representados por variveis de
tipo float ou double. Em qualquer situao, a representao interna desses valores segue o padro de
representao IEEE 754, sendo 0.0 o valor default para tais atributos.
Como para valores inteiros, o espao de armazenamento e conseqentemente a preciso de valores associados a esses tipos de dados so definidos na especificao da linguagem. Variveis do tipo
a
float ocupam 32 bits, podendo assumir valores na faixa de
, com nove dgitos significativos de preciso. Variveis do tipo double ocupam 64 bits, podendo assumir valores de
a
,
com 18 dgitos significativos de preciso.
Constantes literais do tipo float podem ser identificadas no cdigo Java pelo sufixo f ou F; do tipo
double, pelo sufixo d ou D.



    

  


!#"%$

2.2

&'(

 ) ) * 
)
+, -"%./ 01
  2*   2*) +3 !#"%4%$

Identificadores

Identificadores so seqncias de caracteres Unicode, que devem obedecer s seguintes regras:

Um nome pode ser composto por letras, por dgitos e pelos smbolos _ e $.

Um nome no pode ser iniciado por um dgito (0 a 9).

Letras maisculas so diferenciadas de letras minsculas.


Uma palavra-chave da linguagem Java (veja Apndice A) no pode ser um identificador.
Java diferencia as letras minsculas da maisculas. Assim, as duas variveis
int socorro;
int soCorro;

so variveis diferentes.
Alm dessas regras obrigatrias, o uso da conveno padro para identificadores Java torna a
codificao mais uniforme e pode facilitar o entendimento de um cdigo. Embora no seja obrigatrio, o conhecimento e uso da seguinte conveno padro para atribuir nomes em Java pode facilitar
bastante a manuteno de um programa:




Nomes de classes so iniciados por letras maisculas.

Nomes de mtodos, atributos e variveis so iniciados por letras minsculas.


Em nomes compostos, cada palavra do nome iniciada por letra maiscula as palavras no
so separadas por nenhum smbolo.

Detalhes sobre as convenes de codificao sugeridas pelos projetistas da linguagem Java podem
ser encontrados no documento Code Conventions for the JavaTM Programming Language2 .
2

http://www.dca.fee.unicamp.br/projects/sapiens/calm/References/Java/codeconv/
CodeConventions.doc8.html

c 2001 FEEC/UNICAMP

10

Programao orientada a objetos com Java

2.3

2.3. Expresses

Expresses

Expresses so sentenas da linguagem Java terminadas pelo smbolo ;. Essas sentenas podem
denotar expresses envolvendo uma operao aritmtica, uma operao lgica inteira, uma operao
lgica booleana, uma avaliao de condies, uma atribuio, um retorno de mtodo, ou ainda operaes sobre objetos.

2.3.1

Expresses retornando valores numricos

Expresses aritmticas envolvem atributos, variveis e/ou constantes numricas (inteiras ou reais). Os operadores aritmticos definidos em Java incluem:
soma, operador binrio infixo denotado pelo smbolo +;
subtrao, operador binrio infixo denotado pelo smbolo -. O mesmo smbolo pode ser utilizado
como operador unrio prefixo, denotando a complementao (subtrao de 0) do valor;
multiplicao, operador binrio infixo denotado pelo smbolo *;
diviso, operador binrio infixo denotado pelo smbolo /;
resto da diviso, operador binrio infixo denotado pelo smbolo % e que pode ser aplicado apenas
para operandos inteiros;
incremento, operador unrio denotado pelo smbolo ++ que definido apenas para operandos inteiros, podendo ocorrer na forma prefixa (pr-incremento) ou posfixa (ps-incremento); e
decremento, operador unrio denotado pelo smbolo -- que tambm definido apenas para operandos inteiros, podendo ocorrer na forma prefixa (pr-decremento) ou posfixa (ps-decremento).
Operaes lgicas sobre valores inteiros atuam sobre a representao binria do valor armazenado, operando internamente bit a bit. Operadores desse tipo so:
complemento, operador unrio prefixo denotado pelo smbolo ~ que complementa cada bit na representao interna do valor;
OR bit-a-bit, operador binrio infixo denotado pelo smbolo | que resulta no bit 1 se pelo menos
um dos bits na posio correspondente na representao interna dos operandos era 1;
AND bit-a-bit, operador binrio infixo denotado pelo smbolo & que resulta no bit 0 se pelo menos
um dos bits na posio correspondente na representao interna dos operandos era 0;
XOR bit-a-bit, operador binrio infixo denotado pelo smbolo ^ que resulta no bit 1 se os bits na
posio correspondente na representao interna dos operandos eram diferentes;
deslocamento esquerda, operador binrio infixo denotado pelo smbolo << que desloca a representao interna do primeiro operando para a esquerda pelo nmero de posies indicado pelo
segundo operando;

c 2001 FEEC/UNICAMP

11

Programao orientada a objetos com Java

2.3. Expresses

deslocamento direita, operador binrio infixo denotado pelo smbolo >> que desloca a representao interna do primeiro operando para a direita pelo nmero de posies indicado pelo
segundo operando. Os bits inseridos esquerda tero o mesmo valor do bit mais significativo
da representao interna;
deslocamento direita com extenso 0, operador binrio infixo denotado pelo smbolo >>> que
desloca a representao interna do primeiro operando para a direita pelo nmero de posies
indicado pelo segundo operando. Os bits inseridos esquerda tero o valor 0.

2.3.2

Expresses retornando valores booleanos

As operaes lgicas booleanas operam sobre valores booleanos. Operadores booleanos incluem:
complemento lgico, operador unrio prefixo denotado pelo smbolo ! que retorna true se o argumento false ou retorna false se o argumento true;
OR lgico booleano, operador binrio infixo denotado pelo smbolo | que retorna true se pelo menos um dos dois argumentos true;
OR lgico condicional, operador binrio infixo denotado pelo smbolo || que opera como o correspondente booleano; porm, se o primeiro argumento j true, o segundo argumento no
nem avaliado;
AND lgico booleano, operador binrio infixo denotado pelo smbolo & que retorna false se pelo
menos um dos dois argumentos false;
AND lgico condicional, operador binrio infixo denotado pelo smbolo && que opera como o correspondente booleano; porm, se o primeiro argumento j false, o segundo argumento no
nem avaliado;
XOR booleano, operador binrio infixo denotado pelo smbolo ^ que retorna true quando os dois
argumentos tm valores lgicos distintos.
Condies permitem realizar testes baseados nas comparaes entre valores numricos. Operadores condicionais incluem:
maior, operador binrio infixo denotado pelo smbolo > que retorna true se o primeiro valor for
exclusivamente maior que o segundo;
maior ou igual, operador binrio infixo denotado pelo smbolo >= que retorna true se o primeiro
valor for maior que ou igual ao segundo;
menor, operador binrio infixo denotado pelo smbolo < que retorna true se o primeiro valor for
exclusivamente menor que o segundo;
menor ou igual, operador binrio infixo denotado pelo smbolo <= que retorna true se o primeiro
valor for menor que ou igual ao segundo;
igual, operador binrio infixo denotado pelo smbolo == que retorna true se o primeiro valor for
igual ao segundo;
c 2001 FEEC/UNICAMP

12

Programao orientada a objetos com Java

2.3. Expresses

diferente, operador binrio infixo denotado pelo smbolo != que retorna true se o primeiro valor
no for igual ao segundo.

2.3.3

Outros tipos de expresses

Assim como C e C++, Java oferece o operador condicional ternrio denotado pelos smbolos
? : . Na expresso b ? s1 : s2, b uma expresso que resulta em um valor booleano (varivel ou expresso). O resultado da expresso ser o resultado da expresso (ou varivel) s1 se b
for verdadeiro, ou o resultado da expresso (ou varivel) s2 se b for falso.
O operador binrio = atribui o valor da expresso do lado direito varivel esquerda do operador. Os tipos da expresso e da varivel devem ser compatveis. O operador de atribuio pode ser
combinado com operadores aritmticos e lgicos, como em C e C++. Assim, a expresso
a += b
equivale a
a = a + b
Mtodos em Java tm sua execuo encerrada de duas maneiras possveis. A primeira vlida
quando um mtodo no tem um valor de retorno (o tipo de retorno void): a execuo encerrada
quando o bloco do corpo do mtodo chega ao final. A segunda alternativa encerra a execuo do
mtodo atravs do comando return. Se o mtodo tem tipo de retorno void, ento o comando
usado sem argumentos:
return;
Caso o mtodo tenha um valor de retorno especificado, ento a expresso assume a forma
return expresso;
onde o valor de retorno o resultado da expresso, que deve ser compatvel com o tipo de retorno
especificado para o mtodo.

2.3.4

Controle do fluxo de execuo

A ordem de execuo normal de comandos em um mtodo Java seqencial. Comandos de fluxo


de controle permitem modificar essa ordem natural de execuo atravs dos mecanismos de escolha
ou de iterao.
A estrutura if permite especificar um comando (ou bloco de comandos, uma seqncia de expresses delimitada por chaves, { e }) que deve apenas ser executado quando uma determinada condio
for satisfeita:
if (condio) {
bloco_comandos
}
Quando o bloco de comandos composto por uma nica expresso, as chaves que delimitam o
corpo do bloco podem ser omitidas:
c 2001 FEEC/UNICAMP

13

Programao orientada a objetos com Java

2.3. Expresses

if (condio)
expresso;
Embora a indentao do cdigo no seja mandatria, uma recomendao de boa prtica de
programao que o bloco subordinado a uma expresso de controle de fluxo seja representada com
maior indentao que aquela usada no nvel da prpria expresso.
A forma if. . . else permite expressar duas alternativas de execuo, uma para o caso da condio
ser verdadeira e outra para o caso da condio ser falsa:
if (condio) {
bloco_comandos_caso_verdade
}
else {
bloco_comandos_caso_falso
}
O comando switch. . . case tambm expressa alternativas de execuo, mas nesse caso as condies esto restritas comparao de uma varivel inteira com valores constantes:
switch (varivel) {
case valor1:
bloco_comandos
break;
case valor2:
bloco_comandos
break;
...
case valorn:
bloco_comandos
break;
default:
bloco_comandos
}
O comando while permite expressar iteraes que devem ser executadas se e enquanto uma condio for verdadeira:
while (condio) {
bloco_comandos
}
O comando do. . . while tambm permite expressar iteraes, mas neste caso pelo menos uma
execuo do bloco de comandos garantida:
do {
bloco_comandos
} while (condio);

c 2001 FEEC/UNICAMP

14

Programao orientada a objetos com Java

2.3. Expresses

O comando for permite expressar iteraes combinando uma expresso de inicializao, um teste
de condio e uma expresso de incremento:
for (inicializao; condio; incremento) {
bloco_comandos
}
Embora Java no suporte o operador , (vrgula) presente em C e C++, no comando for mltiplas
expresses de inicializao e de incremento podem ser separadas por vrgulas.
Os comandos continue e break permitem expressar a quebra de um fluxo de execuo. O
uso de break j foi utilizado juntamente com switch para delimitar bloco de comandos de cada
case. No corpo de uma iterao, a ocorrncia do comando break interrompe a iterao, passando
o controle para o prximo comando aps o comando de iterao. O comando continue tambm
interrompe a execuo da iterao, mas apenas da iterao corrente. Como efeito da execuo de
continue, a condio de iterao reavaliada e, se for verdadeira, o comando de iterao continua
executando.
Em situaes onde h diversos comandos de iterao aninhados, os comandos break e continue transferem o comando de execuo para o ponto imediatamente aps o bloco onde ocorrem. Se
for necessrio especificar transferncia para o fim de outro bloco de iterao, os comandos break e
continue rotulados podem ser utilizados:
label: {
for (...; ...; ...) {
...
while (...) {
...
if (...)
break label;
...
}
...
}
...
}

2.3.5

Comentrios

Comentrios em Java podem ser expressos em trs formatos distintos. Na primeira forma, uma
barra dupla // marca o incio do comentrio, que se estende at o fim da linha. A segunda forma
o comentrio no estilo C tradicional, onde o par de smbolos /* marca o incio de comentrio,
que pode se estender por diversas linhas at encontrar o par de smbolos */, que delimita o fim do
comentrio.
O outro estilo de comentrio especfico de Java e est associado gerao automtica de documentao do software desenvolvido. Nesse caso, o incio de comentrio delimitado pelas seqncias de incio /** e de trmino */. O texto entre essas seqncias ser utilizado pela ferramenta
javadoc (ver Seo 2.7.1) para gerar a documentao do cdigo em formato hipertexto.
c 2001 FEEC/UNICAMP

15

Programao orientada a objetos com Java

2.4. Operaes sobre objetos

Para gerar esse tipo de documentao, os comentrios devem estar localizados imediatamente
antes da definio da classe ou membro (atributo ou mtodo) documentado. Cada comentrio pode
conter uma descrio textual sobre a classe ou membro, possivelmente incluindo tags HTML, e
diretrizes para o programa javadoc. As diretrizes para javadoc so sempre precedidas por @,
como em
@see nomeClasseOuMembro
que gera na documentao um link para a classe ou membro especificado, precedido pela frase See
also .
A documentao de uma classe pode incluir as diretrizes @author, que inclui o texto na seqncia como informao sobre o autor do cdigo na documentao; e @version, que inclui na documentao informao sobre a verso do cdigo.
A documentao de um mtodo pode incluir as diretrizes @param, que apresenta o nome e uma
descrio de cada argumento do mtodo; @return, que apresenta uma descrio sobre o valor de
retorno; e @exception, que indica que excees podem ser lanadas pelo mtodo (ver Seo 2.6.1).
Para maiores informaes, veja o texto How to Write Doc Comments for Javadoc3 .

2.4

Operaes sobre objetos

A criao de um objeto d-se atravs da aplicao do operador new. Dada uma classe Cls,
possvel (em princpio) criar um objeto dessa classe usando esse operador:
Cls obj = new Cls();
O mtodo direita do operador new um construtor da classe Cls. Um construtor um
(pseudo-)mtodo especial, definido para cada classe. O corpo desse mtodo determina as atividades
associadas inicializao de cada objeto criado. Assim, o construtor apenas invocado no momento
da criao do objeto atravs do operador new.
A assinatura de um construtor diferencia-se das assinaturas dos outros mtodos por no ter nenhum tipo de retorno nem mesmo void. Alm disto, o nome do construtor deve ser o prprio
nome da classe.
O construtor pode receber argumentos, como qualquer mtodo. Usando o mecanismo de sobrecarga, mais de um construtor pode ser definido para uma classe.
Toda classe tem pelo menos um construtor sempre definido. Se nenhum construtor for explicitamente definido pelo programador da classe, um construtor default, que no recebe argumentos,
criado pelo compilador Java. No entanto, se o programador da classe criar pelo menos um mtodo
construtor, o construtor default no ser criado automaticamente se ele o desejar, dever criar um
construtor sem argumentos explicitamente.
No momento em que um construtor invocado, a seguinte seqncia de aes executada para a
criao de um objeto:
1. O espao para o objeto alocado e seu contedo inicializado (bitwise) com zeros.
2. O construtor da classe base invocado.
3

urlhttp://java.sun.com/products/jdk/javadoc/writingdoccomments.html

c 2001 FEEC/UNICAMP

16

Programao orientada a objetos com Java

2.4. Operaes sobre objetos

3. Os membros da classe so inicializados para o objeto, seguindo a ordem em que foram declarados na classe.
4. O restante do corpo do construtor executado.
Seguir essa seqncia uma necessidade de forma a garantir que, quando o corpo de um construtor esteja sendo executado, o objeto j ter disposio as funcionalidades mnimas necessrias,
quais sejam aquelas definidas por seus ancestrais. O primeiro passo garante que nenhum campo do
objeto ter um valor arbitrrio, que possa tornar erros de no inicializao difceis de detectar. Esse
passo que determina os valores default para atributos de tipos primitivos, descritos na Seo 2.1.
Uma vez que um objeto tenha sido criado e haja uma referncia vlida para ele, possvel solicitar
que ele execute mtodos que foram definidos para objetos dessa classe. A aplicao de um mtodo
meth(int), definido em uma classe Cls, a um objeto obj, construdo a partir da especificao de
Cls, se d atravs da construo
obj.meth(varint);
onde varint uma expresso ou varivel inteira anteriormente definida.
Em uma linguagem tradicional, a forma correspondente seria invocar uma funo ou procedimento passando como argumento a estrutura de dados sobre a qual as operaes teriam efeito:
meth(obj, varint);
Esse atributo implcito a referncia para o prprio objeto que est ativando o mtodo
pode ser utilizado no corpo dos mtodos quando for necessrio faz-lo explicitamente. Para tanto, a
palavra-chave this utilizada.
Quando se declara uma varivel cujo tipo o nome de uma classe, como em
String nome;
no est se criando um objeto dessa classe, mas simplesmente uma referncia para um objeto da
classe String, a qual inicialmente no faz referncia a nenhum objeto vlido.
Quando um objeto dessa classe criado, obtm-se uma referncia vlida, que armazenada na
varivel cujo tipo o nome da classe do objeto. Por exemplo, quando cria-se uma string como em
nome = new String("POO/Java");
nome uma varivel que armazena uma referncia vlida para um objeto especfico da classe
String o objeto cujo contedo a string POO/Java. importante ressaltar que a varivel
nome mantm apenas a referncia para o objeto e no o objeto em si. Assim, uma atribuio como
String outroNome = nome;
no cria outro objeto, mas simplesmente uma outra referncia para o mesmo objeto.
A linguagem Java permite que o programador crie e manipule objetos explicitamente. Porm, a
remoo de objetos em Java manipulada automaticamente pelo sistema, usando um mecanismo de
coleta de lixo (garbage collector). O coletor de lixo um processo de baixa prioridade que permanece
verificando quais objetos no tm nenhuma referncia vlida, retomando o espao despendido para

c 2001 FEEC/UNICAMP

17

Programao orientada a objetos com Java

2.4. Operaes sobre objetos

cada um desses objetos. Dessa forma, o programador no precisa se preocupar com a remoo
explcita de objetos.
Outra operao que pode envolver um objeto sua verificao de tipo. Dado um objeto obj
e uma classe Cls, possvel verificar dinamicamente (durante a execuo do mtodo) se o objeto
pertence ou no classe usando o operador instanceof. Este retorna true se o objeto esquerda
do operador da classe especificada direita do operador. Assim,
obj instanceof Cls
retornaria true se obj fosse da classe Cls.

2.4.1

Arranjos

Arranjos so agregados homogneos de valores que podem agrupar literais ou objetos.


A declarao de um arranjo, como
int array1[];
apenas cria uma referncia para um arranjo de inteiros porm o arranjo no foi criado. Assim
como objetos, arranjos so criados com o operador new:
array1 = new int[100];
Essa expresso cria espao para armazenar 100 inteiros no arranjo array1.
As duas expresses poderiam ter sido combinadas em uma sentena incluindo a declarao e a
criao de espao:
int array1[] = new int[100];
Arranjos podem ser alternativamente criados com a especificao de algum contedo:
int array2[] = {2, 4, 5, 7, 9, 11, 13};
O acesso a elementos individuais de um arranjo especificado atravs de um ndice inteiro. O
elemento inicial, assim como em C e C++, tem ndice 0. Assim, do exemplo acima, a expresso
int x = array2[3];
faz com que a varivel x receba o valor 7, o contedo da quarta posio.
O acesso a elementos do arranjo alm do ltimo ndice permitido por exemplo, a array2[7]
gera um erro em tempo de execuo, ou uma exceo (ver Seo 2.6.1).
A dimenso de um arranjo pode ser obtida atravs da propriedade length presente em todos os
arranjos. Assim, a expresso
int y = array2.length;
faz com que y receba o valor 7, o nmero de elementos no arranjo array2.

c 2001 FEEC/UNICAMP

18

Programao orientada a objetos com Java

2.4.2

2.4. Operaes sobre objetos

Strings

Ao contrrio do que ocorre em C e C++, strings em Java no so tratadas como seqncias de


caracteres terminadas por NUL. So objetos, instncias da classe java.lang.String.
Uma string pode ser criada como em:
String s = "abc";
O operador + pode ser utilizado concatenar strings:
System.out.println("String s: " + s);
Se, em uma mesma expresso, o operador + combinar valores numricos e strings, os valores numricos sero convertidos para strings e ento concatenados.
A classe String define um conjunto de funcionalidades para manipular strings atravs de seus
mtodos.
Para obter o nmero de caracteres em uma string, o mtodo int length() usado. Assim, a
expresso
s.length();
retornaria o valor 3.
Para criar uma nova string a partir da concatenar duas strings, o mtodo String concat(String
outro) pode ser usado. Por exemplo,
String t = s.concat(".java");
faria com que a string t tivesse o contedo abc.java.
Para comparar o contedo de duas strings h trs formas bsicas. O mtodo equals(String
outro) compara as duas strings, retornando verdadeiro se seus contedos forem exatamente iguais.
Assim,
t.equals(s);
retornaria falso, mas
s.equals("abc");
retornaria verdadeiro. O mtodo equalsIgnoreCase(String outro) tem a mesma funcionalidade mas ignora se as letras so maisculas ou minsculas. Assim,
s.equalsIgnoreCase("ABC");
tambm retornaria verdadeiro. A terceira forma atravs do mtodo compareTo(String outro), que retorna um valor inteiro igual a zero se as duas strings forem iguais, negativo se a string
qual o mtodo for aplicado preceder lexicograficamente a string do argumento (baseado nos valores
Unicode dos caracteres) ou positivo, caso contrrio. H tambm um mtodo compareToIgnoreCase(String str).
Para extrair caracteres individuais de uma string, pode-se utilizar o mtodo charAt(int pos),
que retorna o carter na posio especificada no argumento (0 a primeira posio). Para obter substrings de uma string, o mtodo substring() pode ser utilizado. Esse mtodo tem duas assinaturas:
c 2001 FEEC/UNICAMP

19

Programao orientada a objetos com Java

2.5. Classes em Java

String substring(int pos_inicial);


String substring(int pos_inicial, int pos_final);
A localizao de uma substring dentro de uma string pode ocorrer de diversas formas. O mtodo
indexOf(), com quatro assinaturas distintas, retorna a primeira posio na string onde o carter
ou substring especificada no argumento ocorre. possvel tambm especificar uma posio diferente
da inicial a partir de onde a busca deve ocorrer. Similarmente, lastIndexOf() busca pela ltima
ocorrncia do carter ou substring a partir do final ou da posio especificada.
possvel tambm verificar se uma string comea com um determinado prefixo ou termina com
um sufixo atravs respectivamente dos mtodos startsWith() e endsWith(). Ambos recebem
como argumento uma string e retornam um valor booleano.

2.5

Classes em Java

Como descrito na Seo 1.1, a definio de classes a base da programao orientada a objetos.
Em Java, classes so definidas em arquivos fonte (extenso .java) e compiladas para arquivos de
classes (extenso .class). Classes so organizadas em pacotes.

2.5.1

Pacotes

No desenvolvimento de pequenas atividades ou aplicaes, vivel manter o cdigo da aplicao


e suas classes associadas em um mesmo diretrio detrabalho em geral, o diretrio corrente. No
entanto, para grandes aplicaes preciso organizar as classes de maneira a evitar problemas com
nomes duplicados de classes e permitir a localizao do cdigo da classe de forma eficiente.
Em Java, a soluo para esse problema est na organizao de classes e interfaces em pacotes.
Um pacote uma unidade de organizao de cdigo que congrega classes, interfaces e excees
relacionadas. O cdigo-base de Java est todo estruturado em pacotes e as aplicaes desenvolvidas
em Java tambm devem ser assim organizadas.
Essencialmente, uma classe Xyz que pertence a um pacote nome.do.pacote tem um nome
completo que nome.do.pacote.Xyz. Assim, se outra aplicao tiver uma classe de mesmo
nome no haver conflitos de resoluo, pois classes em pacotes diferentes tm nomes completos
distintos.
A organizao das classes em pacotes tambm serve como indicao para o compilador Java
para encontrar o arquivo que contm o cdigo da classe. O ambiente Java normalmente utiliza a
especificao de uma varivel de ambiente CLASSPATH, a qual define uma lista de diretrios que
contm os arquivos de classes Java. No entanto, para no ter listas demasiadamente longas, os nomes
dos pacotes definem subdiretrios de busca a partir dos diretrios em CLASSPATH.
No mesmo exemplo, ao encontrar no cdigo uma referncia para a classe Xyz, o compilador dever procurar o arquivo com o nome Xyz.class; como essa classe faz parte do pacote
nome.do.pacote, ele ir procurar em algum subdiretrio nome/do/pacote. Se o arquivo
Xyz.class estiver no diretrio /home/java/nome/do/pacote, ento o diretrio /home/
java deve estar includo no caminho de busca de classes definido por CLASSPATH.
Para indicar que as definies de um arquivo fonte Java fazem parte de um determinado pacote,
a primeira linha de cdigo deve ser a declarao de pacote:

c 2001 FEEC/UNICAMP

20

Programao orientada a objetos com Java

2.5. Classes em Java

package nome.do.pacote;
Caso tal declarao no esteja presente, as classes faro parte do pacote default, que est mapeado
para o diretrio corrente.
Para referenciar uma classe de um pacote no cdigo fonte, possvel sempre usar o nome completo da classe; no entanto, possvel tambm usar a declarao import. Por exemplo, se no incio
do cdigo estiver presente a declarao
import nome.do.pacote.Xyz;
ento a classe Xyz pode ser referenciada sem o prefixo nome.do.pacote no restante do cdigo.
Alternativamente, a declarao
import nome.do.pacote.*;
indica que quaisquer classes do pacote especificado podem ser referenciadas apenas pelo nome no
restante do cdigo fonte.
A nica exceo para essa regra refere-se s classes do pacote java.lang essas classes
so consideradas essenciais para a interpretao de qualquer programa Java e, por este motivo, o
correspondente import implcito na definio de qualquer classe Java.

2.5.2

Definio de classes em Java

Em Java, classes so definidas atravs do uso da palavra-chave class. Para definir uma classe,
utiliza-se a construo:
[modif]

class NomeDaClasse {
// corpo da classe...

}
A primeira linha um comando que inicia a declarao da classe. Aps a palavra-chave class,
segue-se o nome da classe, que deve ser um identificador vlido para a linguagem (ver Seo 2.2). O
modificador modif opcional; se presente, pode ser uma combinao de public e abstract ou final.
A definio da classe propriamente dita est entre as chaves { e }, que delimitam blocos na
linguagem Java. Este corpo da classe usualmente obedece seguinte seqncia de definio:
1. As variveis de classe (definidas como static), ordenadas segundo sua visibilidade: iniciando pelas public, seguidos pelas protected, pelas com visibilidade padro (sem modificador)
e finalmente pelas private.
2. Os atributos (ou variveis de instncia) dos objetos dessa classe, seguindo a mesma ordenao
segundo a visibilidade definida para as variveis de classe.
3. Os construtores de objetos dessa classe.
4. Os mtodos da classe, geralmente agrupados por funcionalidade.
A definio de atributos de uma classe Java reflete de forma quase direta a informao que estaria
contida na representao da classe em um diagrama UML. Para tanto, a sintaxe utilizada para definir
um atributo de um objeto :
c 2001 FEEC/UNICAMP

21

Programao orientada a objetos com Java

[modificador]

tipo

2.5. Classes em Java

nome [ = default];

onde

o modificador opcional, especificando a visibilidade diferente da padro (public, protected ou private), alterao da modificabilidade (final) e se o atributo est associado
classe (static).

o tipo deve ser um dos tipos primitivos da linguagem Java ou o nome de uma classe;

o nome deve ser um identificador vlido da linguagem Java;

o valor default opcional; se presente, especifica um valor inicial para a varivel.

Mtodos so essencialmente procedimentos que podem manipular atributos de objetos para os


quais o mtodo foi definido. Alm dos atributos de objetos, mtodos podem definir e manipular
variveis locais; tambm podem receber parmetros por valor atravs da lista de argumentos. A
forma genrica para a definio de um mtodo em uma classe
[modificador] tipo nome(argumentos) {
corpo do mtodo
}
onde




o modificador (opcional) uma combinao de: public, protected ou private; abstract ou final; e static.

o tipo um indicador do valor de retorno, sendo void se o mtodo no tiver um valor de


retorno;

o nome do mtodo deve ser um identificador vlido na linguagem Java;


os argumentos so representados por uma lista de parmetros separados por vrgulas, onde para
cada parmetro indicado primeiro o tipo e depois (separado por espao) o nome.

Uma boa prtica de programao manter a funcionalidade de um mtodo simples, desempenhando uma nica tarefa. O nome do mtodo deve refletir de modo adequado a tarefa realizada. Se a
funcionalidade do mtodo for simples, ser fcil encontrar um nome adequado para o mtodo.
Como ocorre para a definio de atributos, a definio de mtodos reflete de forma quase direta a
informao que estaria presente em um diagrama de classes UML, a no ser por uma diferena vital:
o corpo do mtodo.
Mtodos de mesmo nome podem co-existir em uma mesma classe desde que a lista de argumentos
seja distinta, usando o mecanismo de sobrecarga.
O exemplo a seguir ilustra a definio de uma classe de nome Ponto2D:
public class Ponto2D {
private int x;
private int y;

c 2001 FEEC/UNICAMP

22

Programao orientada a objetos com Java

2.5. Classes em Java

public Ponto2D(int x, int y) {


this.x = x;
this.y = y;
}
public Ponto2D( ) {
this(0,0);
}
public double distancia(Ponto2D p) {
double distX = p.x - x;
double distY = p.y - y;
return Math.sqrt(distX*distX + distY*distY);
}
}
Um objeto dessa classe tem dois atributos privativos que definem as coordenadas do ponto bidimensional, x e y nesse caso, as coordenadas so valores inteiros.
A classe tem dois construtores. O primeiro deles recebe dois argumentos, tambm de nome x e y,
que definem as coordenadas do ponto criado. Para diferenciar no corpo do construtor os parmetros
dos atributos, estes tm seu nome prefixado pela palavra-chave this.
O segundo construtor ilustra outro uso da palavra-chave this. Esse construtor no recebe argumentos e assume portanto o ponto tem como cordenadas a origem, ou seja, o ponto (0,0). O corpo
desse construtor poderia ser simplesmente
x = 0;
y = 0;
A alternativa apresentada usa a forma
this(0,0);
que equivale a use o construtor desta mesma classe que recebe dois argumentos inteiros, passando
os valores aqui especificados.
Finalmente, a classe define um mtodo pblico para calcular a distncia entre o ponto que invocou
o mtodo (this) e outro ponto especificado como o argumento p. Nesse caso, como no h risco
de confuso, no preciso usar a palavra-chave this antes dos atributos da coordenada do objeto.
Assim, as expresses que calculam distX e distY equivalem a
double distX = p.x - this.x;
double distY = p.y - this.y;
A expresso de retorno ilustra ainda a utilizao de um mtodo esttico da classe Math do pacote java.lang para o cmputo da raiz quadrada. Usualmente, mtodos definidos em uma so
aplicados a objetos daquela classe. H no entanto situaes nas quais um mtodo pode fazer uso
dos recursos de uma classe para realizar sua tarefa sem necessariamente ter de estar associado a um
objeto individualmente.
c 2001 FEEC/UNICAMP

23

Programao orientada a objetos com Java

2.5. Classes em Java

Para lidar com tais situaes, Java define os mtodos da classe, cuja declarao deve conter o
modificador static. Um mtodo esttico pode ser aplicado classe e no necessariamente a um
objeto.
Exemplos de mtodos estticos em Java incluem os mtodos para manipulao de tipos primitivos
definidos nas classes Character, Integer e Double, todas elas do pacote java.lang, assim
como todos os mtodos definidos para a classe Math.

2.5.3

O mtodo main

Toda classe pode tambm ter um mtodo main associado, que ser utilizado pelo interpretador
Java para dar incio execuo de uma aplicao. Ao contrrio do que acontece em C e C++, onde
apenas uma funo main deve ser definida para a aplicao como um todo, toda e qualquer classe
Java pode ter um mtodo main definido. Apenas no momento da interpretao o main a ser executado
definido atravs do primeiro argumento (o nome da classe) para o programa interpretador.
O mtodo main um mtodo associado classe e no a um objeto especfico da classe
assim, ele definido como um mtodo esttico. Adicionalmente, deve ser um mtodo pblico para
permitir sua execuo a partir da mquina virtual Java. No tem valor de retorno, mas recebe como
argumento um arranjo de strings que corresponde aos parmetros que podem ser passados para a
aplicao a partir da linha de comando. Essas caractersticas determinam a assinatura do mtodo:
public static void main(String[] args)
ou
static public void main(String[] args)
Mesmo que no seja utilizado, o argumento de main deve ser especificado. Por exemplo, a
definio da classe Ponto2D poderia ser complementada com a incluso de um mtodo para testar
sua funcionalidade:
public class Ponto2D {
...
public static void main(String[] args) {
Ponto2D ref2 = new Ponto2D();
Ponto2D p2 = new Ponto2D(1,1);
System.out.println("Distancia: " + p2.distancia(ref2));
}
}
O nome do parmetro (args) obviamente poderia ser diferente, mas os demais termos da assinatura devem obedecer ao formato especificado. Esse argumento um parmetro do tipo arranjo de
objetos da classe String. Cada elemento desse arranjo corresponde a um argumento passado para
o interpretador Java na linha de comando que o invocou. Por exemplo, se a linha de comando for
java Xyz abc 123 def
o mtodo main(String[] args) da classe Xyz vai receber, nessa execuo, um arranjo de
trs elementos na varivel args com os seguintes contedos:
c 2001 FEEC/UNICAMP

24

Programao orientada a objetos com Java

2.5. Classes em Java

em args[0], o objeto String com contedo "abc";




em args[1], o objeto String com contedo "123";


em args[2], o objeto String com contedo "def".

Como o mtodo main do tipo void, ele no tem valor de retorno. No entanto, assim como
programas desenvolvidos em outras linguagens, preciso algumas vezes obter uma indicao se o
programa executou com sucesso ou no. Isto principalmente til quando o programa invocado no
contexto de um script do sistema operacional.
Em Java, o mecanismo para fornecer essa indicao o mtodo System.exit(int). A
invocao desse mtodo provoca o fim imediato da execuo do interpretador Java. Tipicamente, o
argumento de exit() obedece conveno de que 0 indica execuo com sucesso, enquanto um
valor diferente de 0 indica a ocorrncia de algum problema.

2.5.4

Visibilidade da classe e seus membros

Em Java, a visibilidade padro de classes, atributos e mtodos est restrita a todos os membros
que fazem parte de um mesmo pacote. A palavra-chave public modifica essa visibilidade de forma a
ampli-la, deixando-a sem restries.
Uma classe definida como pblica pode ser utilizada por qualquer objeto de qualquer pacote.
Em Java, uma unidade de compilao (um arquivo fonte com extenso .java) pode ter no mximo
uma classe pblica, cujo nome deve ser o mesmo do arquivo (sem a extenso). As demais classes na
unidade de compilao, no pblicas, so consideradas classes de suporte para a classe pblica e tm
a visibilidade padro.
Um atributo pblico de uma classe pode ser diretamente acessado e manipulado por objetos de
outras classes.
Um mtodo pblico de uma classe pode ser aplicado a um objeto dessa classe a partir de qualquer
outro objeto de outra classe. O conjunto de mtodos pblicos de uma classe determina o que pode
ser feito com objetos da classe, ou seja, determina o seu comportamento.
A palavra-chave protected restringe a visibilidade do membro modificado, atributo ou mtodo, apenas prpria classe e quelas derivada desta.
A palavra-chave private restringe a visibilidade do membro modificado, mtodo ou atributo,
exclusivamente a objetos da prpria classe que contm sua definio.

2.5.5

Classes derivadas

Sendo uma linguagem de programao orientada a objetos, Java oferece mecanismos para definir
classes derivadas a partir de classes existentes. fundamental que se tenha uma boa compreenso
sobre como objetos de classes derivadas so criados e manipulados, assim como das restries de
acesso que podem se aplicar a membros de classes derivadas. Tambm importante para uma completa
compreenso da utilizao desse mecanismo em Java entender como relacionam-se interfaces e
herana (Seo 2.5.7).
A forma bsica de herana em Java a extenso simples entre uma superclasse e sua classe
derivada. Para tanto, utiliza-se na definio da classe derivada a palavra-chave extends seguida pelo
nome da superclasse.

c 2001 FEEC/UNICAMP

25

Programao orientada a objetos com Java

2.5. Classes em Java

A hierarquia de classes de Java tem como raiz uma classe bsica, Object. Quando no for
especificada uma superclasse na definio de uma classe, o compilador assume que a superclasse
Object. Assim, definir a classe Ponto2D como em
class Ponto2D {
// ...
}
equivalente a defini-la como
class Ponto2D extends Object {
// ...
}
por esse motivo que todos os objetos podem invocar os mtodos da classe Object, tais como
equals() e toString(). O mtodo equals permite comparar objetos por seus contedos. A
implementao padro desse mtodo realiza uma comparao de contedo bit a bit; se um comportamento distinto for desejado para uma classe definida pelo programador, o mtodo deve ser redefinido.
O mtodo toString() permite converter uma representao interna do objeto em uma string que
pode ser apresentada ao usurio.
Outros mtodos da classe Object incluem clone(), um mtodo protegido que permite criar
uma duplicata de um objeto, e getClass(), que retorna um objeto que representa a classe qual o
objeto pertence. Esse objeto ser da classe Class; para obter o nome da classe, pode-se usar o seu
mtodo esttico getName(), que retorna uma string.
Para criar uma classe Ponto3D a partir da definio da classe que representa um ponto em duas
dimenses, a nova classe deve incluir um atributo adicional para representar a terceira coordenada:
public class Ponto3D extends Ponto2D {
private int z;
public Ponto3D(int x, int y, int z) {
super(x, y);
this.z = z;
}
public Ponto3D( ) {
z = 0;
}
public static void main(String[] args) {
Ponto2D ref2 = new Ponto2D();
Ponto3D p3 = new Ponto3D(1,2,3);
System.out.println("Distancia: " + p3.distancia(ref2));
}
}

c 2001 FEEC/UNICAMP

26

Programao orientada a objetos com Java

2.5. Classes em Java

Nesse exemplo, o mtodo distancia que utilizado em main aquele que foi definido para
a classe Ponto2D que, por herana, um mtodo da classe Ponto3D.
Esse exemplo ilustra, na definio do primeiro construtor, o uso da palavra-chave super para
invocar um construtor especfico da superclasse. Se presente, essa expresso deve ser a primeira
do construtor, pois o incio da construo do objeto a construo da parte da superclasse. Caso
no esteja presente, est implcita uma invocao para o construtor padro, sem argumentos, da
superclasse, equivalente forma super().

2.5.6

Classes abstratas e finais

Uma classe abstrata no pode ser instanciada, ou seja, no h objetos que possam ser construdos
diretamente de sua definio. Por exemplo, a compilao do seguinte trecho de cdigo
abstract class AbsClass {
public static void main(String[] args) {
AbsClass obj = new AbsClass();
}
}
geraria a seguinte mensagem de erro:
AbsClass.java:3: class AbsClass is an abstract class.
It cant be instantiated.
AbsClass obj = new AbsClass();
^
1 error
Em geral, classes abstratas definem um conjunto de funcionalidades das quais pelo menos uma
est especificada mas no est definida ou seja, contm pelo menos um mtodo abstrato, como em
abstract class AbsClass {
public abstract int umMetodo();
}
Um mtodo abstrato no cria uma definio, mas apenas uma declarao de um mtodo que dever
ser implementado em uma classe derivada. Se esse mtodo no for implementado na classe derivada,
esta permanece como uma classe abstrata mesmo que no tenha sido assim declarada explicitamente.
Assim, para que uma classe derivada de uma classe abstrata possa gerar objetos, os mtodos
abstratos devem ser definidos em classes derivadas:
class ConcClass extends AbsClass {
public int umMetodo() {
return 0;
}
}
Uma classe final, por outro lado, indica uma classe que no pode ser estendida. Assim, a compilao do arquivo Reeleicao.java com o seguinte contedo:
c 2001 FEEC/UNICAMP

27

Programao orientada a objetos com Java

2.5. Classes em Java

final class Mandato {


}
public class Reeleicao extends Mandato {
}
ocasionaria um erro de compilao:
caolho:Exemplos[39] javac Reeleicao.java
Reeleicao.java:4: Cant subclass final classes: class Mandato
public class Reeleicao extends Mandato {
^
1 error
A palavra-chave final pode tambm ser aplicada a mtodos e a atributos de uma classe. Um
mtodo final no pode ser redefinido em classes derivadas.
Um atributo final no pode ter seu valor modificado, ou seja, define valores constantes. Apenas
valores de tipos primitivos podem ser utilizados para definir constantes. O valor do atributo deve ser
definido no momento da declarao, pois no permitida nenhuma atribuio em outro momento.
A utilizao de final para uma referncia a objetos permitida. Como no caso de constantes,
a definio do valor (ou seja, a criao do objeto) tambm deve ser especificada no momento da
declarao. No entanto, preciso ressaltar que o contedo do objeto em geral pode ser modificado
apenas a referncia fixa. O mesmo vlido para arranjos.
A partir de Java 1.1, possvel ter atributos de uma classe que sejam final mas no recebem
valor na declarao, mas sim nos construtores da classe. (A inicializao deve obrigatoriamente
ocorrer em uma das duas formas.) So os chamados blank finals, que introduzem um maior grau
de flexibilidade na definio de constantes para objetos de uma classe, uma vez que essas podem
depender de parmetros passados para o construtor.
Argumentos de um mtodo que no devem ser modificados podem ser declarados como final,
tambm, na prpria lista de parmetros.

2.5.7

Interfaces

Java tambm oferece outra estrutura, denominada interface, com sintaxe similar de classes mas
contendo apenas a especificao da funcionalidade que uma classe deve conter, sem determinar como
essa funcionalidade deve ser implementada. Uma interface Java uma classe abstrata para a qual
todos os mtodos so implicitamente abstract e public, e todos os atributos so implicitamente
static e final. Em outros termos, uma interface Java implementa uma classe abstrata pura.
A sintaxe para a declarao de uma interface similar quela para a definio de classes, porm
seu corpo define apenas assinaturas de mtodos e constantes. Por exemplo, para definir uma interface
Interface1 que declara um mtodo met1 sem argumentos e sem valor de retorno, a sintaxe :
interface Interface1 {
void met1();
}

c 2001 FEEC/UNICAMP

28

Programao orientada a objetos com Java

2.6. Excees

A diferena entre uma classe abstrata e uma interface Java que a interface obrigatoriamente no
tem um corpo associado. Para que uma classe seja abstrata basta que ela seja assim declarada, mas a
classe pode incluir atributos de objetos e definio de mtodos, pblicos ou no. Na interface, apenas
mtodos pblicos podem ser declarados mas no definidos. Da mesma forma, no possvel
definir atributos apenas constantes pblicas.
Enquanto uma classe abstrata estendida (palavra chave extends) por classes derivadas, uma
interface Java implementada (palavra chave implements) por outras classes.
Uma interface estabelece uma espcie de contrato que obedecido por uma classe. Quando uma
classe implementa uma interface, garante-se que todas as funcionalidades especificadas pela interface
sero oferecidas pela classe.
Outro uso de interfaces Java para a definio de constantes que devem ser compartilhadas por
diversas classes. Neste caso, a recomendao implementar interfaces sem mtodos, pois as classes
que implementarem tais interfaces no precisam tipicamente redefinir nenhum mtodo:
interface Coins {
int
PENNY = 1,
NICKEL = 5,
DIME = 10,
QUARTER = 25,
DOLAR = 100;
}
class SodaMachine implements Coins {
int price = 3*QUARTER;
// ...
}

2.6

Excees

Uma exceo um sinal que indica que algum tipo de condio excepcional ocorreu durante a
execuo do programa. Assim, excees esto associadas a condies de erro que no tinham como
ser verificadas durante a compilao do programa.
As duas atividades associadas manipulao de uma exceo so:
gerao: a sinalizao de que uma condio excepcional (por exemplo, um erro) ocorreu, e
captura: a manipulao (tratamento) da situao excepcional, onde as aes necessrias para a recuperao da situao de erro so definidas.
Para cada exceo que pode ocorrer durante a execuo do cdigo, um bloco de aes de tratamento (um exception handler) deve ser especificado. O compilador Java verifica e enfora que toda
exceo no-trivial tenha um bloco de tratamento associado.
O mecanismo de manipulao de excees em Java, embora apresente suas particularidades, teve
seu projeto inspirado no mecanismo equivalente de C++, que por sua vez foi inspirado em Ada.
c 2001 FEEC/UNICAMP

29

Programao orientada a objetos com Java

2.6. Excees

um mecanismo adequado manipulao de erros sncronos, para situaes onde a recuperao do


erro possvel.
A sinalizao da exceo propagada a partir do bloco de cdigo onde ela ocorreu atravs de
toda a pilha de invocaes de mtodos at que a exceo seja capturada por um bloco manipulador
de exceo. Eventualmente, se tal bloco no existir em nenhum ponto da pilha de invocaes de
mtodos, a sinalizao da exceo atinge o mtodo main(), fazendo com que o interpretador Java
apresente uma mensagem de erro e aborte sua execuo.

2.6.1

Tratamento de excees

A captura e o tratamento de excees em Java se d atravs da especificao de blocos try,


catch e finally, definidos atravs destas mesmas palavras reservadas da linguagem.
A estruturao desses blocos obedece seguinte sintaxe:
try {
// cdigo que inclui comandos/invocaes de mtodos
// que podem gerar uma situao de exceo.
}
catch (XException ex) {
// bloco de tratamento associado condio de
// exceo XException ou a qualquer uma de suas
// subclasses, identificada aqui pelo objeto
// com referncia ex
}
catch (YException ey) {
// bloco de tratamento para a situao de exceo
// YException ou a qualquer uma de suas subclasses
}
finally {
// bloco de cdigo que sempre ser executado aps
// o bloco try, independentemente de sua concluso
// ter ocorrido normalmente ou ter sido interrompida
}
onde XException e YException deveriam ser substitudos pelo nome do tipo de exceo. Os
blocos no podem ser separados por outros comandos um erro de sintaxe seria detectado pelo
compilador Java neste caso. Cada bloco try pode ser seguido por zero ou mais blocos catch, onde
cada bloco catch refere-se a uma nica exceo.
O bloco finally, quando presente, sempre executado. Em geral, ele inclui comandos que
liberam recursos que eventualmente possam ter sido alocados durante o processamento do bloco try
e que podem ser liberados, independentemente de a execuo ter encerrado com sucesso ou ter sido
interrompida por uma condio de exceo. A presena desse bloco opcional.
Alguns exemplos de excees j definidas no pacote java.lang incluem:
ArithmeticException: indica situaes de erros em processamento aritmtico, tal como uma diviso
inteira por 0. A diviso de um valor real por 0 no gera uma exceo (o resultado o valor
infinito);
c 2001 FEEC/UNICAMP

30

Programao orientada a objetos com Java

2.6. Excees

NumberFormatException: indica que tentou-se a converso de uma string para um formato numrico, mas seu contedo no representava adequadamente um nmero para aquele formato.
uma subclasse de IllegalArgumentException;
IndexOutOfBounds: indica a tentativa de acesso a um elemento de um agregado aqum ou alm dos
limites vlidos. a superclasse de ArrayIndexOutOfBoundsException, para arranjos,
e de StringIndexOutOfBounds, para strings;
NullPointerException: indica que a aplicao tentou usar uma referncia a um objeto que no foi
ainda definida;
ClassNotFoundException: indica que a mquina virtual Java tentou carregar uma classe mas no
foi possvel encontr-la durante a execuo da aplicao.
Alm disso, outros pacotes especificam suas excees, referentes s suas funcionalidades. Por
exemplo, no pacote java.io define-se IOException, que indica a ocorrncia de algum tipo de
erro em operaes de entrada e sada. a superclasse para condies de exceo mais especficas desse pacote, tais como EOFException (fim de arquivo ou stream), FileNotFoundException
(arquivo especificado no foi encontrado) e InterruptedIOException (operao de entrada
ou sada foi interrompida).
Uma exceo contm pelo menos uma string que a descreve, que pode ser obtida pela aplicao do mtodo getMessage(), mas pode eventualmente conter outras informaes. Por exemplo,
InterruptedIOException inclui um atributo pblico do tipo inteiro, bytesTransferred,
para indicar quantos bytes foram transferidos antes da interrupo da operao ocorrer. Outra informao que pode sempre ser obtida de uma exceo a seqncia de mtodos no momento da
exceo, obtenvel a partir do mtodo printStackTrace().
Como excees fazem parte de uma hierarquia de classes, excees mais genricas (mais prximas do topo da hierarquia) englobam aquelas que so mais especficas. Assim, a forma mais genrica
de um bloco try-catch
try { ... }
catch (Exception e) { ... }
pois todas as excees so derivadas de Exception. Se dois blocos catch especificam excees
em um mesmo ramo da hierarquia, a especificao do tratamento da exceo derivada deve preceder
aquela da mais genrica.

2.6.2

Erros e excees de runtime

Excees consistem de um caso particular de um objeto da classe Throwable. Apenas objetos


dessa classe ou de suas classes derivadas podem ser gerados, propagados e capturados atravs do
mecanismo de tratamento de excees.
Alm de Exception, outra classe derivada de Throwable a classe Error, que a raiz
das classes que indicam situaes que a aplicao no tem como ou no deve tentar tratar. Usualmente indica situaes anormais, que no deveriam ocorrer. Entre os erros definidos em Java, no
pacote java.lang, esto StackOverflowError e OutOfMemoryError. So situaes onde no possvel uma correo a partir de um tratamento realizado pelo prprio programa que est
executando.
c 2001 FEEC/UNICAMP

31

Programao orientada a objetos com Java

2.6. Excees

H tambm excees que no precisam ser explicitamente capturadas e tratadas. So aquelas


derivadas de RuntimeException, uma classe derivada diretamente de Exception. So excees que podem ser geradas durante a operao normal de uma aplicao para as quais o compilador
Java no ir exigir que o programador proceda a algum tratamento (ou que propague a exceo, como
descrito na Seo 2.6.3). Entre essas incluem-se ArithmeticException, IllegalArgumentException, IndexOutOfBoundsException e NullPointerException.

2.6.3

Propagando excees

Embora toda exceo que no seja derivada de RuntimeException deva ser tratada, nem
sempre possvel tratar uma exceo no mesmo escopo do mtodo cuja invocao gerou a exceo.
Nessas situaes, possvel propagar a exceo para um nvel acima na pilha de invocaes.
Para tanto, o mtodo que est deixando de capturar e tratar a exceo faz uso da clusula throws
na sua declarao:
void mtodoQueNoTrataExceo() throws Exception {
invoca.mtodoQuePodeGerarExceo();
}
Nesse caso, mtodoQueNoTrataExceo() reconhece que em seu corpo h a possibilidade de haver a gerao de uma exceo mas no se preocupa em realizar o tratamento dessa exceo
em seu escopo. Ao contrrio, ele repassa essa responsabilidade para o mtodo anterior na pilha de
chamadas.
Eventualmente, tambm o outro mtodo pode repassar a exceo adiante. Porm, pelo menos no
mtodo main() as excees devero ser tratadas ou o programa pode ter sua interpretao interrompida.

2.6.4

Definindo e gerando excees

Excees so classes. Assim, possvel que uma aplicao defina suas prprias excees atravs
do mecanismo de definio de classes.
Por exemplo, considere que fosse importante para uma aplicao diferenciar a condio de diviso por zero de outras condies de excees artimticas. Neste caso, uma classe DivideByZeroException poderia ser criada:
public class DivideByZeroException
extends ArithmeticException {
public DivideByZeroException() {
super("O denominador na diviso inteira tem valor zero");
}
}
Neste caso, o argumento para o construtor da superclasse especifica a mensagem que seria impressa quando o mtodo getMessage() fosse invocado para essa exceo. Essa a mesma mensagem que apresentada para um RuntimeException que no capturado e tratado.

c 2001 FEEC/UNICAMP

32

Programao orientada a objetos com Java

2.7. O ambiente de Java

Para gerar uma condio de exceo durante a execuo de um mtodo, um objeto dessa classe
deve ser criado e, atravs do comando throw, propagado para os mtodos anteriores na pilha de
execuo:
public double calculaDivisao (double numerador, int denominador)
throws DivideByZeroException {
if (denominador == 0)
throw new DivideByZeroException();
return numerador / denominador;
}
O mesmo comando throw pode ser utilizado para repassar uma exceo aps sua captura por
exemplo, aps um tratamento parcial da condio de exceo:
public void usaDivisao()
throws DivideByZeroException {
...
try {
d = calculaDivisao(x, y);
}
catch (DivideByZeroException dbze) {
...
throw dbze;
}
...
}
Nesse caso, a informao associada exceo (como o seu ponto de origem, registrado internamente
no atributo do objeto que contm a pilha de invocaes) preservada. Caso fosse desejado mudar
essa informao, uma nova exceo poderia ser gerada ou, caso a exceo seja a mesma, o mtodo
fillInStackTrace() poderia ser utilizado, como em
throw dbze.fillInStackTrace();

2.7

O ambiente de Java

O ambiente de desenvolvimento de software Java, Java SDK (Software Development Kit antigamente, denominado JDK), formado essencialmente pelas classes fundamentais da linguagem
Java e por um conjunto de aplicativos que permite, entre outras tarefas, realizar a compilao e a execuo de programas escritos na linguagem Java. No um ambiente integrado de desenvolvimento,
no oferecendo editores ou ambientes de programao visual. No entanto, so suas funcionalidades
que permitem a operao desses ambientes.
O Java SDK contm um amplo conjunto de APIs que compem o ncleo de funcionalidades
da linguagem Java. Uma API (Application Programming Interface) uma biblioteca formada por
cdigo pr-compilado, pronto para ser utilizado no desenvolvimento de suas aplicaes.
c 2001 FEEC/UNICAMP

33

Programao orientada a objetos com Java

2.7.1

2.7. O ambiente de Java

Ferramentas do Java SDK

As ferramentas essenciais do ambiente de desenvolvimento de sofware Java so: o compilador


Java, javac; o interpretador de aplicaes Java, java; e o interpretador de applets Java, appletviewer.
Um programa fonte em Java pode ser desenvolvido usando qualquer editor que permita gravar
textos sem caracteres de formatao. Um arquivo contendo cdigo Java constitui uma unidade de
compilao, podendo incluir comentrios, declarao relacionadas a pacotes e pelo menos uma definio de classe ou interface.
O resultado dessa execuo, se o programa fonte estiver sem erros, ser a criao de um arquivo
Hello.class contendo o bytecode que poder ser executado em qualquer mquina.
Alm das ferramentas essenciais, o Java SDK oferece os aplicativos de desenvolvimento javadoc,
um gerador de documentao para programas Java; jar, um manipulador de arquivos comprimidos no
formato Java Archive, que opera juntamente com extcheck, o verificador de arquivos nesse formato;
jdb, um depurador de programas Java; javap, um disassembler de classes Java; e javah, um gerador
de arquivos header para integrao a cdigo nativo em C.
Java oferece tambm aplicativos para o desenvolvimento e execuo de aplicaes Java em plataformas de objetos distribudos (ver Captulo 5). H tambm ferramentas para permitir o desenvolvimento de aplicaes distribudas, incorporando tambm o conceito de assinaturas digitais. A
ferramenta keytool gerencia chaves e certificados; jarsigner gera e verifica assinaturas associadas a
arquivos Java; e policytool uma interface grfica para gerenciar arquivos que determinam a poltica
de segurana do ambiente de execuo.

2.7.2

Gerao de cdigo porttil

Um dos grandes atrativos da plataforma tecnolgica Java a portabilidade do cdigo gerado.


Esta portabilidade atingida atravs da utilizao de bytecodes. Bytecode um formato de cdigo
intermedirio entre o cdigo fonte, o texto que o programador consegue manipular, e o cdigo de
mquina, que o computador consegue executar.
Na plataforma Java, o bytecode interpretado por uma mquina virtual Java. A portabilidade
do cdigo Java obtida medida que mquinas virtuais Java esto disponveis para diferentes plataformas. Assim, o cdigo Java que foi compilado em uma mquina pode ser executado em qualquer
mquina virtual Java, independentemente de qual seja o sistema operacional ou o processador que
executa o cdigo.
A Mquina Virtual Java (JVM) , alm de um ambiente de execuo independente de plataforma,
uma mquina de computao abstrata. Programas escritos em Java e que utilizem as funcionalidades
definidas pelas APIs dos pacotes da plataforma Java executam nessa mquina virtual.
Uma das preocupaes associadas a execues nessas mquinas virtuais oferecer uma arquitetura de segurana para prevenir que applets e aplicaes distribudas executem fora de seu ambiente seguro (sandbox) a no ser quando assim habilitados. Um framework de segurana estabelecido atravs de funcionalidades dos pacotes java.security e seus subpacotes java.security.acl,
java.security.cert, java.security.interfaces e java.security.spec.
A mquina virtual Java opera com o carregamento dinmico de classes, ou seja, bytecodes so
carregados pela mquina virtual Java medida que so solicitados pela aplicao.
Em uma aplicao operando localmente, o carregador de classes da mquina virtual procura
por essas classes nos (sub-)diretrios especificados a partir da varivel do sistema CLASSPATH. Se

c 2001 FEEC/UNICAMP

34

Programao orientada a objetos com Java

2.7. O ambiente de Java

encontrada, a classe carregada para a mquina virtual e a operao continua. Caso contrrio, a
exceo ClassNotFoundException gerada.
O carregamento do cdigo de uma classe para a JVM realizado pelo class loader da mquina
virtual. O class loader, em si uma classe Java que prov essa funcionalidade, deve obedecer a uma
poltica de segurana estabelecida para aquela mquina virtual.
O estabelecimento de uma poltica de segurana deve obedecer a um modelo de segurana especfico. No modelo de segurana estabelecido a partir do JDK 1.2 (JDK security specification), todo
cdigo sendo carregado para uma mquina virtual Java requer o estabelecimento de uma poltica de
segurana, visando evitar que algum objeto realize operaes no-autorizadas na mquina local. Com
a incluso do conceito de poltica de segurana, possvel estabelecer permisses diferenciadas para
as aplicaes.
A poltica de segurana padro estabelecida em um arquivo do sistema, java.policy,
localizado no diretrio <java_home>/lib/security/. Cada usurio pode estabelecer adies a essa poltica atravs da criao de um arquivo particular de estabelecimento de poltica,
.java.policy, em seu diretrio home. Por exemplo, para permitir conexes soquete de qualquer
mquina com origem no domnio unicamp.br a portas no-notveis, o arquivo .java.policy
deveria incluir
grant {
permission java.net.SocketPermission
"*.unicamp.br:1024-", "accept,connect";
};
A sintaxe para o arquivo de polticas (Policy files syntax) permite estabelecer domnios de permisso com base na origem do cdigo ou na sua assinatura. A ferramenta policytool permite
criar um arquivo de polticas atravs de uma interface grfica.
Para enforar essas polticas alternativas de segurana, um SecurityManager deve ser criado. Applets, por default, utilizam um SecurityManager estabelecido pelo navegador em cujo
contexto esto executando. Outras aplicaes devem criar explicitamente esse objeto. Por exemplo,
para criar um SecurityManager padro para aplicaes usando RMI (Seo 5.4.2), a seguinte
linha de cdigo deveria ser includa antes de executar qualquer operao envolvendo classes remotas:
System.setSecurityManager(new RMISecurityManager());
Se o cliente RMI estiver em um applet, ento no necessrio criar um SecurityManager,
uma vez que o prprio navegador estabelece a poltica de segurana para applets remotos.

2.7.3

Desenvolvimento de aplicaes

Aplicaes Java so programas autnomos, cujo cdigo gerado a partir de um programa fonte
pode ser interpretado diretamente pela Mquina Virtual Java. Como tudo em Java est estruturado
atravs de classes e objetos, para desenvolver uma aplicao preciso desenvolver pelo menos uma
classe que contenha um mtodo denominado main.
Assim, uma classe que v estabelecer o ponto de partida para a execuo de uma aplicao
na JVM deve conter pelo menos esse mtodo. Esse exemplo clssico define uma aplicao que
simplesmente envia uma string para a sada padro, identificada pelo objeto pblico System.out:

c 2001 FEEC/UNICAMP

35

Programao orientada a objetos com Java

1
2
3
4
5
6

2.7. O ambiente de Java

public class Hello {


public static void main(String[] args) {
System.out.println("Oi!");
System.exit(0);
}
}
Uma vez que o programa tenha sido salvo em um arquivo com extenso .java, preciso
compil-lo. Para compilar um programa Java, a ferramenta oferecida pelo kit de desenvolvimento
Java o compilador Java, javac. Na forma mais bsica de execuo, o javac invocado da linha
de comando tendo por argumento o nome do arquivo com o cdigo Java a ser compilado:
> javac Hello.java
A unidade de compilao o arquivo com extenso .java; esse arquivo pode conter a definio
de vrias classes, mas apenas uma delas pode ser pblica. A classe pblica em um arquivo fonte
define o nome desse arquivo, que obrigatoriamente deve ter o mesmo nome dessa classe.
Para cada definio de classe na unidade de compilao, o compilador Java ir gerar um arquivo
com bytecodes com a extenso .class, tendo como nome o prprio nome da classe.
Uma vez que um programa Java tenha sido compilado e esteja pronto para ser executado, isto
se d atravs do comando java o interpretador Java, que ativa a mquina virtual Java, carrega a
classe especificada e ativa seu mtodo main.
Por exemplo, para interpretar o arquivo Hello.class contendo o bytecode correspondente ao
cdigo fonte do arquivo Hello.java, utiliza-se a linha de comando
> java Hello
Observe que a extenso .class no includa nessa linha de comando se o for, uma mensagem de erro ser gerada, pois para a mquina virtual Java o carter . est associado definio de
uma hierarquia de pacotes.
Se a mquina virtual Java do interpretador no encontrar um mtodo de nome main com a
assinatura correta (public, static, void e com um argumento do tipo String[]) na classe
especificada, uma exceo ser gerada em tempo de execuo:
Exception in thread "main" java.lang.NoSuchMethodError: main
Essa mensagem pode ser emitida pela ausncia completa de um mtodo main na classe ou por uma
declarao incorreta para o mtodo.
Se um programa Java for desenvolvido como applet (ver Seo 4.3), ele no poder ser executado
diretamente atravs do interpretador Java mas sim atravs da ativao de uma pgina HTML. Para
executar esse tipo de aplicao pode-se utilizar um navegador; porm, o ambiente de desenvolvimento
Java oferece a aplicao appletviewer que extrai da pgina HTML apenas o espao de exibio
do applet e permite controlar sua execuo atravs de comandos em sua interface grfica.

c 2001 FEEC/UNICAMP

36

Captulo 3

Uso das classes da API padro de Java


Um dos grandes atrativos da programao orientada a objetos a possibilidade de adaptar funcionalidades oferecidas em classes existentes s necessidades de cada aplicao. Java, no diferentemente, oferece essa facilidade, aliando-a ao oferecimento de um amplo conjunto de classes organizadas
nos pacotes da API padro.
As classes que compem o ncleo de funcionalidades Java esto organizadas em pacotes, grupos
de classes, interfaces e excees afins ou de uma mesma aplicao. Entre os principais pacotes
oferecidos como parte do ncleo Java esto: java.lang, java.util, java.io, java.awt,
java.applet e java.net.
Observe que esses nomes seguem a conveno Java, pela qual nomes de pacotes (assim como
nomes de mtodos) so grafados em letras minsculas, enquanto nomes de classes tm a primeira
letra (de cada palavra, no caso de nomes compostos) grafada com letra maiscula.

3.1

Funcionalidades bsicas

O pacote java.lang contm as classes que constituem recursos bsicos da linguagem, necessrios
execuo de qualquer programa Java.
A classe Object expressa o conjunto de funcionalidades comuns a todos os objetos Java, sendo
a raiz da hierarquia de classes Java.
As classes Class e ClassLoader representam, respectivamente classes Java e o mecanismo
para carreg-las dinamicamente para a Mquina Virtual Java.
A classe String permite a representao e a manipulao de strings cujo contedo no pode ser
modificado. Para manipular string modificveis por exemplo, atravs da insero de um carter
na string a classe StringBuffer oferecida.
A classe Math contm a definio de mtodos para clculo de funes matemticas (trigonomtricas, logartimicas, exponenciais, etc.) e de constantes, tais como E e PI. Todos os mtodos
e constantes definidos nessa classe so estticos, ou seja, para utiliz-los basta usar como prefixo o
nome da classe.
O pacote oferece tambm um conjunto de classes wrappers. Um objeto de uma classe wrapper
contm um nico valor de um tipo primitivo da linguagem, permitindo assim estabelecer uma ponte
entre valores literais e objetos. Essas classes so Boolean, Character, Byte, Short, Integer, Long, Float e Double. Alm dos mtodos para obter o valor associado ao objeto de cada

37

Programao orientada a objetos com Java

3.2. Entrada e sada

uma dessas classes, mtodos auxiliares como a converso de e para strings so suportados.
As classes System, Runtime e Process permitem interao da aplicao Java com o ambiente de execuo. Por exemplo, a classe System tem trs atributos pblicos e estticos associados
aos arquivos padro de um sistema operacional: System.in, para a entrada padro; System.out,
para a sada padro; e System.err, para a sada padro de erros. Adicionalmente, as classes Thread e ThreadGroup, assim como a interface Runnable, do suporte execuo de mltiplas
linhas de execuo que podem ser associadas a um processo.
As classes que definem erros e excees, respectivamente Error e Exception, so tambm
definidas nesse pacote. A classe Error a raiz para condies de erro no-tratveis, tais como OutOfMemoryError. J a classe Exception est associada hierarquia de condies que podem
ser detectados e tratados pelo programa, como ArithmeticException (diviso inteira por zero)
e ArrayIndexOutOfBoundsException (acesso a elemento de arranjo alm da ltima posio
ou antes da primeira posio). Ambas as classes so derivadas de Throwable, tambm definida
nesse pacote.
Sub-pacotes relacionados java.lang incluem java.lang.ref, de referncias a objetos,
e o pacote java.lang.reflect, que incorpora funcionalidades para permitir a manipulao do
contedo de classes, ou seja, identificao de seus mtodos e campos.
Deve-se ressaltar ainda que funes matemticas so definidas em java.lang.Math. Outro
pacote, java.math, contm funcionalidades para manipular nmeros inteiros e reais de preciso
arbitrria.

3.2

Entrada e sada

Por entrada e sada subentende-se o conjunto de mecanismos oferecidos para que um programa
executando em um computador consiga respectivamente obter e fornecer informao de dispositivos
externos ao ambiente de execuo, composto pelo processador e memria principal.
De forma genrica, havendo um dispositivo de entrada de dados habilitado, o programa obtm
dados deste dispositivo atravs de uma operao read(). Similarmente, um dado pode ser enviado
para um dispositivo de sada habilitado atravs de uma operao write().
A manipulao de entrada e sada de dados em Java suportada atravs de classes do pacote java.io. Essas classes oferecem as funcionalidades para manipular a entrada e sada de bytes,
adequadas para a transferncia de dados binrios, e para manipular a entrada e sada de caracteres,
adequadas para a transferncia de textos.
Fontes de dados manipuladas como seqncias de bytes so tratadas em Java pela classe InputStream e suas classes derivadas. Similarmente, sadas de seqncias de bytes so tratadas por
OutputStream e suas classes derivadas.
Aplicaes tpicas de entrada e sada envolvem a manipulao de arquivos contendo caracteres.
Em Java, a especificao de funcionalidades para manipular esse tipo de arquivo esto contidas nas
classes abstratas Reader (e suas classes derivadas) e Writer (e suas classes derivadas), respectivamente para leitura e para escrita de caracteres.

c 2001 FEEC/UNICAMP

38

Programao orientada a objetos com Java

3.2.1

3.2. Entrada e sada

Transferncia de texto

A classe Reader oferece as funcionalidades para obter caracteres de alguma fonte de dados
que fonte de dados essa vai depender de qual classe concreta, derivada de Reader, est sendo
utilizada. A classe Reader apenas discrimina funcionalidades genricas, como o mtodo read(),
que retorna um int representando o carter lido, e ready(), que retorna um boolean indicando,
se verdadeiro, que o dispositivo est pronto para disponibilizar o prximo carter.
Como Reader uma classe abstrata, no possvel criar diretamente objetos dessa classe.
preciso criar objetos de uma de suas subclasses concretas para ter acesso funcionalidade especificada por Reader.
BufferedReader incorpora um buffer a um objeto Reader. Como a velocidade de operao de dispositivos de entrada e sada vrias ordens de grandeza mais lenta que a velocidade
de processamento, buffers so tipicamente utilizados para melhorar a eficincia dessas operaes de
leitura e escrita. Adicionalmente, na leitura de texto a classe BufferedReader adiciona um mtodo readLine() para ler uma linha completa. LineNumberReader estende essa classe para
adicionalmente manter um registro do nmero de linhas processadas.
CharArrayReader e StringReader permitem fazer a leitura de caracteres a partir de arranjos de caracteres e de objetos String, respectivamente. Assim, possvel usar a memria principal como uma fonte de caracteres da mesma forma que se usa um arquivo.
FilterReader uma classe abstrata para representar classes que implementam algum tipo de
filtragem sobre o dado lido. Sua classe derivada, PushbackReader, incorpora a possibilidade de
retornar um carter lido de volta sua fonte.
InputStreamReader implementa a capacidade de leitura a partir de uma fonte que fornece
bytes, traduzindo-os adequadamente para caracteres. Sua classe derivada, FileReader, permite
associar essa fonte de dados a um arquivo.
PipedReader faz a leitura a partir de um objeto PipedWriter, estabelecendo um mecanismo de comunicao inter-processos no caso de Java, entre threads de uma mesma mquina
virtual.
As funcionalidades de escrita de texto esto associadas classe abstrata Writer e suas classes
derivadas. Entre as funcionalidades genricas definidas em Writer esto o mtodo write(int),
onde o argumento representa um carter, sua variante write(String) e o mtodo flush(), que
fora a sada de dados pendentes para o dispositivo sendo acessado para escrita.
Assim como para a classe Reader, as funcionalidades da classe Writer so implementadas
atravs de suas subclasses concretas.
BufferedWriter incorpora um buffer a um objeto Writer, permitindo uma melhoria de
eficincia de escrita ao combinar vrias solicitaes de escrita de pequenos blocos em uma solicitao
de escrita de um bloco maior.
CharArrayWriter e StringWriter permitem fazer a escrita em arranjos de caracteres e
em objetos StringBuffer, respectivamente.
FilterWriter uma classe abstrata para representar classes que implementam algum tipo de
filtragem sobre o dado escrito.
OutputStreamWriter implementa a capacidade de escrita tendo como destino uma seqncia de bytes, traduzindo-os adequadamente desde os caracteres de entrada. Sua classe derivada,
FileWriter, permite associar esse destino de dados a um arquivo.

c 2001 FEEC/UNICAMP

39

Programao orientada a objetos com Java

3.2.2

3.2. Entrada e sada

Transferncia de bytes

A classe abstrata InputStream oferece a funcionalidade bsica para a leitura de um byte ou


de uma seqncia de bytes a partir de alguma fonte. Os principais mtodos dessa classe incluem
available(), que retorna o nmero de bytes disponveis para leitura, e read(), que retorna o
prximo byte do dispositivo de entrada.
Como para a leitura de texto, InputStream usado de fato atravs de uma de suas classes
derivadas. ByteArrayInputStream permite ler valores originrios de um arranjo de bytes, permitindo assim tratar uma rea de memria como uma fonte de dados.
Outra funcionalidade associada transferncia de dados est relacionada converso de formatos, tipicamente entre texto e o formato interno de dados binrios. Essa e outras funcionalidades
so suportadas atravs do oferecimento de filtros, classes derivadas de FilterInputStream, que
podem ser agregados aos objetos que correspondem aos mecanismos elementares de entrada e sada.
FileInputStream l bytes que so originrios de um arquivo em disco. Usualmente, um
objeto dessa classe usado em combinao com os filtros BufferedInputStream e DataInputStream. Outro exemplo de filtro PushbackInputStream, que oferece mtodos unread() que permitem repor um ou mais bytes de volta sua fonte, como se eles no tivessem sido
lidos.
A classe BufferedInputStream l mais dados que aqueles solicitados no momento da operao read() para um buffer interno, melhorando a eficincia das operaes subseqentes para essa
mesma fonte de dados.
DataInputStream permite a leitura de representaes binrias dos tipos primitivos de Java, oferecendo mtodos tais como readBoolean(), readChar(), readDouble() e readInt(). uma implementao da interface DataInput. Essa interface, tambm implementada pela classe RandomAccessFile, especifica mtodos que possibilitam a interpretao de uma
seqncia de bytes como um tipo primitivo da linguagem Java. Adicionalmente, tambm possvel
interpretar a seqncia de bytes como um objeto String. Em geral, mtodos dessa interface geram uma exceo EOFException se for solicitada a leitura alm do final do arquivo. Em outras
situaes de erro de leitura, a exceo IOException gerada.
A classe SequenceInputStream oferece a funcionalidade para concatenar dois ou mais objetos InputStream; o construtor especifica os objetos que sero concatenados e, automaticamente,
quando o fim do primeiro objeto alcanado os bytes passam a ser obtidos do segundo objeto.
A classe abstrata OutputStream oferece a funcionalidade bsica para a transferncia seqencial de bytes para algum destino. Os mtodos desta classe incluem write(int) e flush(),
suportados por todas suas classes derivadas.
ByteArrayOutputStream oferece facilidades para escrever para um arranjo de bytes interno, que cresce de acordo com a necessidade e pode ser acessado posteriormente atravs dos mtodos
toByteArray() ou toString().
FileOutputStream oferece facilidades para escrever em arquivos, usualmente utilizadas em
conjuno com as classes BufferedOutputStream e DataOutputStream.
FilterOutputStream define funcionalidades bsicas para a filtragem de sada de dados,
implementadas em alguma de suas classes derivadas: BufferedOutputStream armazena bytes
em um buffer interno at que este esteja cheio ou at que o mtodo flush() seja invocado. DataOutputStream uma implementao da interface DataOutput que permite escrever valores
de variveis de tipos primitivos de Java em um formato binrio porttil. A classe PrintStream

c 2001 FEEC/UNICAMP

40

Programao orientada a objetos com Java

3.2. Entrada e sada

oferece mtodos para apresentar representaes textuais dos valores de tipos primitivos Java, atravs
das vrias assinaturas dos mtodos print() (impresso sem mudana de linha) e println()
(impresso com mudana de linha).
A classe ObjectInputStream oferece o mtodo readObject() para a leitura de objetos
que foram serializados para um ObjectOutputStream. Atravs desse mecanismo de serializao
possvel gravar e recuperar objetos de forma transparente.
PipedInputStream oferece a funcionalidade de leitura de um pipe de bytes cuja origem est
associada a um objeto PipedOutputStream. J PipedOutputStream implementa a origem
de um pipe de bytes, que sero lidos a partir de um objeto PipedInputStream. Juntos, objetos dessas classes oferecem um mecanismo de comunicao de bytes entre threads de uma mesma
mquina virtual.

3.2.3

Manipulao de arquivos

Outro dispositivo de entrada e sada de vital importncia disco, manipulado pelo sistema operacional e por linguagens de programao atravs do conceito de arquivos. Um arquivo uma abstrao
utilizada por sistemas operacionais para uniformizar a interao entre o ambiente de execuo e os
dispositivos externos a ele em um computador. Tipicamente, a interao de um programa com um
dispositivo atravs de arquivos passa por trs etapas: abertura ou criao de um arquivo; transferncia
de dados; e fechamento do arquivo.
Em Java, a classe File permite representar arquivos nesse nvel de abstrao. Um dos construtores desta classe recebe como argumento uma string que pode identificar, por exemplo, o nome de um
arquivo em disco. Os mtodos desta classe permitem obter informaes sobre o arquivo. Por exemplo, exists() permite verificar se o arquivo especificado existe ou no; os mtodos canRead()
e canWrite() verificam se o arquivo concede a permisso para leitura e escrita, respectivamente;
length() retorna o tamanho do arquivo e lastModified(), o tempo em que ocorreu a ltima
modificao (em milissegundos desde primeiro de janeiro de 1970). Outros mtodos permitem ainda
realizar operaes sobre o arquivo como um todo, tais como delete() e deleteOnExit().
Observe que as funcionalidades de transferncia seqencial de dados a partir de ou para um
arquivo no suportada pela classe File, mas sim pelas classes FileInputStream, FileOutputStream, FileReader e FileWriter. Todas estas classes oferecem pelo menos um
construtor que recebe como argumento um objeto da classe File e implementam os mtodos bsicos de transferncia de dados suportados respectivamente por InputStream, OutputStream,
Reader e Writer.
Para aplicaes que necessitam manipular arquivos de forma no seqencial (ou direta), envolvendo avanos ou retrocessos arbitrrios na posio do arquivo onde ocorrer a transferncia, Java
oferece a classe RandomAccessFile. Esta no derivada de File, mas oferece um construtor
que aceita como argumento de especificao do arquivo um objeto dessa classe. Outro construtor
recebe a especificao do arquivo na forma de uma string. Para ambos construtores, um segundo
argumento uma string que especifica o modo de operao, r para leitura apenas ou rw para
leitura e escrita.
Os mtodos para a manipulao da posio corrente do ponteiro no arquivo so seek(long
pos), que seleciona a posio em relao ao incio do arquivo para a prxima operao de leitura ou
escrita, e getFilePointer(), que retorna a posio atual do ponteiro do arquivo. Alm disso, o
mtodo length() retorna o tamanho do arquivo em bytes.
c 2001 FEEC/UNICAMP

41

Programao orientada a objetos com Java

3.2. Entrada e sada

Para a manipulao de contedo do arquivo, todos os mtodos especificados pelas interfaces


DataInput e DataOutput so implementados por essa classe. Assim, possvel por exemplo
usar os mtodos readInt() e writeInt() para ler e escrever valores do tipo primitivo int,
respectivamente.

3.2.4

Serializao

Sendo Java uma linguagem de programao orientada a objetos, seria de se esperar que, alm
das funcionalidades usuais de entrada e sada, ela oferecesse tambm alguma funcionalidade para
transferncia de objetos. O mecanismo de serializao suporta essa funcionalidade.
O processo de serializao de objetos permite converter a representao de um objeto em memria para uma seqncia de bytes que pode ento ser enviada para um ObjectOutputStream, que
por sua vez pode estar associado a um arquivo em disco ou a uma conexo de rede, por exemplo.
Por exemplo, para serializar um objeto da classe Hashtable, definida no pacote java.util,
armazenando seu contudo em um arquivo em disco, a seqncia de passos :
// criar/manipular o objeto
Hashtable dados = new Hashtable();
...
// definir o nome do arquivo
String filename = ...;
// abrir o arquivo de sada
File file = new File(filename);
if(!file.exists()){
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file);
// associar ao arquivo o ObjectOutputStream
ObjectOutputStream s = new ObjectOutputStream(out);
// serializar o objeto
s.writeObject(dados);
O processo inverso, a desserializao, permite ler essa representao de um objeto a partir de um
ObjectInputStream usando o mtodo readObject():
FileInputStream in = new FileInputStream(file);
ObjectInputStream s = new ObjectInputStream(in);
dados = (Hashtable) s.readObject();
Objetos de classes para os quais so previstas serializaes e desserializaes devem implementar
a interface Serializable, do pacote java.io. Essa interface no especifica nenhum mtodo
ou campo um exemplo de uma interface marker, servindo apenas para registrar a semntica de
serializao.
Serializao um processo transitivo, ou seja, subclasses serializveis de classes serializveis
so automaticamente incorporadas representao serializada do objeto raiz. Para que o processo
de desserializao possa operar corretamente, todas as classes envolvidas no processo devem ter um
construtor default (sem argumentos).
c 2001 FEEC/UNICAMP

42

Programao orientada a objetos com Java

3.3

3.3. Framework de colees

Framework de colees

Estruturas de dados so mecanismos para manipular colees de elementos em um programa.


O pacote java.util oferece algumas classes definidas na API padro de Java que implementam
funcionalidades associadas a estruturas de dados.
As classes de colees da API Java compem o chamado framework de colees, que foi completamente redefinido a partir da verso 1.2 de Java. As classes at ento existentes para a manipulao
de conjuntos de objetos Vector, Stack e Hashtable, atualmente denominadas as classes de
coleo histricas foram totalmente reprojetadas para se adequar ao novo framework. Elas foram
mantidas por motivos de compatibilidade, embora a recomendao seja utilizar as novas classes de
colees.
Todas essas estruturas manipulam colees de objetos, ou seja, qualquer objeto de qualquer classe
de Java pode ser elemento de uma dessas colees. No entanto, no possvel criar diretamente uma
coleo de tipos primitivos, como int ou double. Para manipular colees de tipos primitivos
necessrio utilizar as classes wrappers (Seo 3.1).
O framework de colees tem por raiz duas interfaces bsicas, Map e Collection.
A interface Map especifica as funcionalidades necessrias para manipular um grupo de objetos
mapeando chaves a valores. Entre outros, os seguintes mtodos so especificados nessa interface:




Object put(Object key, Object value): associa um novo valor associado chave especificada, retornando o valor antigo (ou null se no havia valor associado chave).

Object get(Object key): retorna o valor associado chave especificada.

boolean containsKey(Object key): indica se a chave especificada est presente na


coleo.
int size(): retorna a quantidade de elementos na coleo.

Se adicionalmente deseja-se que esse grupo de objetos seja manipulado de acordo com alguma
ordem especfica, a interface derivada SortedMap pode ser utilizada. Assim, alm das funcionalidades acima, esta interface especifica mtodos tais como:




Object firstKey() para retornar o elemento da coleo com a chave de menor valor.

Object lastKey() para retornar o elemento da coleo com a chave de maior valor.
SortedMap subMap(Object fromKey, Object toKey) para obter o subconjunto
dos elementos compreendidos entre as chaves especificadas.

Para essas interfaces, duas implementaes bsicas so tambm oferecidas nesse mesmo pacote
java.util. A classe HashMap implementa o mecanismo bsico de mapeamento entre chaves e
valores. A classe TreeMap oferece a funcionalidade adicional de associar uma ordem aos elementos
da coleo. Para alguns tipos de objetos, tais como Integer, Double ou String, uma ordem
natural j pr-estabelecida. Para objetos de classes da aplicao, a classe dever implementar a
interface Comparable.
Um objeto que implementa a interface Collection representa um grupo de objetos genrico,
onde duplicaes so permitidas. Entre os mtodos bsicos especificados nessa interface esto:
c 2001 FEEC/UNICAMP

43

Programao orientada a objetos com Java

3.3. Framework de colees

boolean add(Object element) para adicionar o elemento especificado coleo.

boolean remove(Object element) para remover o elemento especificado da coleo.

boolean contains(object element) para verificar se a coleo contm o elemento


especificado.

int size() para obter a quantidade de elementos na coleo.


Iterator iterator() para obter um objeto que permite varrer todos os elementos da
coleo.

Duas outras interfaces, Set e List, so derivadas diretamente de Collection.


Set uma extenso de Collection que no permite duplicaes de objetos nenhum mtodo novo introduzido, mas apenas a necessidade de garantir essa restrio. A interface SortedSet
uma extenso de Set que agrega o conceito de ordenao ao conjunto, introduzindo a especificao
de mtodos tais como first(), para obter o primeiro elemento do conjunto; last(), para obter
o ltimo elemento do conjunto; e subSet(), para obter o subconjunto com todos os elementos
contidos entre os dois elementos especificados como argumentos do mtodo.
A interface Set tem duas implementaes j oferecidas no pacote java.util. A classe
HashSet uma implementao padro que utiliza o valor de cdigo hash para detectar e impedir duplicaes. A classe TreeSet uma implementao de SortedSet que usa uma estrutura
de dados em rvore para manter ordenados os elementos do conjunto.
A interface List uma extenso de Collection que introduz mecanismos de indexao.
Alm dos mtodos bsicos de colees, adiciona mtodos tais como get() para obter o elemento
armazenado na posio especificada como argumento; indexOf() para obter a posio da primeira
ocorrncia do objeto especificado como argumento; e subList() para obter uma sublista contendo
os elementos compreendidos entre as duas posies especificadas, incluindo o elemento da primeira
posio mas no o da segunda.
Da mesma forma que para Set, h duas implementaes padronizadas para a interface List
j definidas em java.util. A classe ArrayList oferece uma implementao bsica da interface, enquanto que a classe LinkedList oferece uma implementao otimizada para manipular
listas dinmicas, introduzindo os mtodos addFirst(), getFirst(), removeFirst(), addLast(), getLast() e removeLast().
Para percorrer os elementos de uma coleo no novo framework, um objeto que implementa a
interface Iterator utilizado. Essa interface especifica os mtodos hasNext(), que retorna um
valor booleano verdadeiro para indicar que h mais elementos na coleo, e next(), que retorna o
objeto que o prximo elemento da coleo. Adicionalmente, um mtodo void remove() pode
ser utilizado para retirar um elemento da coleo atravs da referncia a um Iterator.
A interface ListIterator uma extenso de Iterator que permite a varredura da coleo
nas duas direes, especificando novos mtodos tais como boolean hasPrevious() e Object
previous().

c 2001 FEEC/UNICAMP

44

Programao orientada a objetos com Java

3.4

3.4. Extenses padronizadas

Extenses padronizadas

Alm das funcionalidades bsicas oferecidas por esses pacotes, h tambm APIs definidas para
propsitos mais especficos compondo a extenso padronizada ao ncleo Java. Por exemplo, o Input
Method Framework est associado ao pacote java.awt.im e contempla funcionalidades para
manipular textos no-ocidentais usando teclados convencionais.
Funcionalidades para definir e utilizar componentes de software em Java so oferecidas atravs
de Java Beans, um conjunto de APIs definidas atravs do pacote java.beans e seu subpacote
java.beans.context para suportar os modelos de instrospeco, customizao, eventos, propriedades e persistncia desses componentes.
Uma das extenses mais significativas definida pelo conjunto da Java Foundation Classes,
extenso de AWT que oferece um conjunto de componentes de interface grfica com usurio completamente porttil. Trs pacotes compem JFC: Swing, Drag and Drop e Java 2D. Swing define
uma famlia de pacotes com o prefixo javax.swing com componentes e servios GUI de aparncia independente de plataforma. Drag and Drop, associado ao pacote java.awt.dnd, suporta o
compartilhamento de dados baseado no padro MIME, Multipurpose Internet Mail Extension. Java
2D acrescenta novas classes aos pacotes java.awt e java.awt.image para estender as funcionalidades associadas manipulao de imagens bidimensionais e acrescenta novos pacotes java.awt.color, java.awt.font, java.awt.geom, java.awt.image.renderable e
java.awt.print. As funcionalidades para a construo de interfaces grficas com usurios so
apresentadas na Seo 4.
Outra funcionalidade acrescentada Java foi a capacidade de acesso a bancos de dados relacionais usando a linguagem de consulta SQL. Atravs da API definida em JDBC, atravs do pacote
java.sql, possvel enviar comandos SQL para um servidor de banco de dados e processar o
retorno obtido nessa consulta. A utilizao de JDBC descrita na Seo 5.2.3.
Java IDL integra a funcionalidade da arquitetura CORBA a aplicaes Java, permitindo obter
inter-operabilidade e conectividade baseadas nesse padro do OMG (Object Management Group).
Alm das classes presentes nos pacotes org.omg.CORBA e org.omg.CosNaming, alguns aplicativos so acrescidos ao ambiente de desenvolvimento e execuo de Java, como o compilador de
Java para IDL e um aplicativo que oferece o servio de nomes. O desenvolvimento de aplicaes
usando Java IDL descrito na Seo 5.4.3.

c 2001 FEEC/UNICAMP

45

Captulo 4

Desenvolvimento de aplicaes grficas


A linguagem Java oferece, dentre as funcionalidades incorporadas sua API padro, um extenso
conjunto de classes e interfaces para o desenvolvimento de aplicaes grficas. Esse conjunto facilita
a criao de sadas na forma grfica e de interfaces grficas com usurios (GUIs), tanto na forma de
aplicaes autnomas como na forma de applets.
Aplicaes grficas so criadas atravs da utilizao de componentes grficos, que esto agrupados em dois grandes pacotes: java.awt e javax.swing.
AWT o Abstract Windowing Toolkit, sendo definido atravs das classes do pacote java.awt e
seus subpacotes, tais como java.awt.event. Essas classes agrupam as funcionalidades grficas
que esto presentes desde a primeira verso de Java, que operam tendo por base as funcionalidades
de alguma biblioteca grfica do sistema onde a aplicao executada.
J o pacote javax.swing define uma extenso padronizada a partir de AWT que congrega
componentes grficos que utilizam exclusivamente Java (lightweight components), com funcionalidades e aparncia independentes do sistema onde a aplicao executada.

4.1

Apresentao grfica

A base para tudo que desenhado na tela de uma aplicao grfica o contexto grfico, em Java
um objeto da classe Graphics do pacote java.awt. So nesses objetos que linhas, retngulos,
crculos, strings, etc. so desenhados, compondo a apresentao visual da aplicao grfica.
Todo componente grfico tem associado a si um contexto grfico e alguns mtodos chaves para
manipul-lo. A um objeto da classe Component pode-se aplicar os mtodos getGraphics(),
que permite obter uma referncia para um objeto da classe Graphics; paint(Graphics), que
determina o que feito no contexto grfico; e repaint(), que solicita uma atualizao no contexto
grfico.
Para determinar o contedo grfico do contexto, os mtodos da classe Graphics so utilizados.
Esses mtodos incluem facilidades para definio de cores, fontes e definio de figuras geomtricas.
O sistema de coordenadas para definir a posio do desenho no contexto tem origem no canto superior
esquerdo da rea grfica, tomando valores inteiros para e representando quantidades de pixels na
horizontal e na vertical, respectivamente.
A cor corrente para o contexto grfico pode ser obtida e definida pelos mtodos getColor()
e setColor(), respectivamente. Esses mtodos usam cores representadas por objetos da classe

5 6

46

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

Color, que oferece constantes para usar cores pr-definidas, mtodos para definir cores especificando nveis RGB (red, green, blue) ou HSB (hue, saturation, brightness) e mtodos para manipular as
cores existentes.
Similarmente, a fonte usada para a apresentao de strings no contexto pode ser obtida e definida
atravs de mtodos getFont() e setFont(). Fontes so representadas por objetos da classe
Font.
Entre os diversos mtodos usados para desenhar no contexto, h mtodos para desenhar texto
usando a fonte de texto e a cor corrente, drawString(); desenhar linhas retas, drawLine(); e
desenhar diversas formas geomtricas, tais como arcos, drawArc(); retngulos, drawRect(),
drawRoundRect(), draw3DRect(); polgonos, drawPolygon(); ovais, drawOval();
e suas correspondentes verses preenchidas, fillArc(), fillRect(), fillRoundRect(),
fill3DRect(), fillPolygon() e fillOval().

4.2

Interfaces grficas com usurios

Criar uma interface grfica com usurios em Java envolve tipicamente a criao de um container,
um componente que pode receber outros. Em uma aplicao grfica autnoma, tipicamente o container usado como base um frame (uma janela com bordas e barra de ttulo), enquanto que em um
applet o container base um panel (uma rea grfica inserida em outra). Em aplicaes complexas,
qualquer tipo de combinao desses e de outros tipos de componentes utilizado.
Aps sua criao, os containers da aplicao recebem componentes de interface com usurios,
que permitiro apresentar e receber dados aos e dos usurios. Embora seja possvel posicionar esses
componentes atravs de coordenadas absolutas em cada container, recomendvel que o projetista
utilize sempre um gerenciador de layout para realizar essa tarefa. Deste modo, garante-se que a aplicao possa ser executada independentemente das caractersticas da plataforma onde ser executada.
Finalmente, preciso especificar quais devem ser os efeitos das aes dos usurios tais como
um "clique"do mouse ou uma entrada de texto quando realizadas sobre cada um desses componentes. Isto se d atravs da especificao de classes manipuladoras de eventos, projetadas para a
aplicao. Ao associar objetos dessas classes aos componentes grficos, o projetista determina o
comportamento da aplicao.

4.2.1

Eventos da interface grfica

No modelo de eventos suportado a partir da verso 1.1 de Java, um componente grfico qualquer pode reconhecer alguma ao do usurio e a partir dela disparar um evento indicando, por
exemplo, que o boto do mouse foi pressionado ou que um texto foi modificado que ser capturado por um objeto registrado especificamente para registrar aquele tipo de evento ocorrido naquele
componente.
O pacote java.awt.event define as diversas classes de eventos que podem ocorrer atravs
das interfaces grficas. Eventos grficos so objetos derivados da classe AWTEvent, que por sua
vez so derivados de objetos de evento genricos definidos pela classe EventObject. Desta, eventos grficos herdam o mtodo getSource(), que permite identificar o objeto que deu origem ao
evento.

c 2001 FEEC/UNICAMP

47

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

Eventos grficos genricos so especializados de acordo com o tipo de evento sob considerao
por exemplo, pressionar um boto do mouse gera um objeto da classe MouseEvent. A mesma
ao sobre um boto, no entanto, gera tambm um ActionEvent, enquanto que sobre o boto de
minimizar na barra de ttulo de um frame um WindowEvent seria ao invs adicionalmente gerado.
Outros eventos de interesse definidos em java.awt.event incluem ItemEvent, indicando que um item de uma lista de opes foi selecionado; TextEvent, quando o contedo de um
componente de texto foi modificado; e KeyEvent, quando alguma tecla foi pressionada no teclado.
A resposta que uma aplicao d a qualquer evento que ocorre em algum componente grfico
determinada por mtodos especficos, registrados para responder a cada evento. O nome e a assinatura de cada um desses mtodos determinado por uma interface Java do tipo listener. Assim, para
responder a um ActionEvent ser utilizado o mtodo definido na interface ActionListener;
para responder a um WindowEvent, os mtodos de WindowListener. Similarmente, h interfaces ItemListener, TextListener e KeyListener. Os eventos do mouse so manipulados
atravs de mtodos especificados em duas interfaces, MouseListener (para aes sobre o mouse)
e MouseMotionListener (para tratar movimentos realizados com o mouse).
Apesar de existir um grande nmero de eventos e possibilidades de resposta que a aplicao
poderia dar a cada um deles, cada aplicao pode especificar apenas aqueles para os quais h interesse
que sejam tratados. Para os eventos que o projetista da aplicao tem interesse de oferecer uma
reao, ele deve definir classes manipuladoras de eventos (handlers), implementaes de cada listener
correspondente ao tipo de evento de interesse.
Para interfaces listener que especificam diversos mtodos, classes adaptadoras so definidas.
Essas classes adaptadoras so classes abstratas definidas no pacote de eventos AWT, com nome XXXAdapter, onde XXX seria o prefixo correspondente ao tipo de evento de interesse. Assim, para
que a aplicao use uma classe adaptadora para tratar os eventos do tipo WindowEvent, por exemplo, uma classe que estende a classe WindowAdapter pode ser definida. Nessa classe derivada, os
mtodos relacionados aos eventos de interesse so redefinidos (pelo mecanismo de overriding). Como a classe adaptadora implementa a interface correspondente WindowListener, assim o far a
classe derivada. Os mtodos no redefinidos herdaro a definio original, que simplesmente ignora
os demais eventos.
A API de eventos AWT de Java define, alm de WindowAdapter, as classes adaptadoras MouseAdapter, MouseMotionAdapter e KeyAdapter.
Uma vez que uma classe handler tenha sido criada para responder aos eventos de um componente, preciso associar esse componente ao objeto handler. Para tanto, cada tipo de componente
grfico oferece mtodos na forma addXXXListener(XXXListener l) e removeXXXListener(XXXListener l), onde XXX est associado a algum evento do tipo XXXEvent. Por
exemplo, para o componente Window (e por herana para todas os componentes derivados desse) so definidos os mtodos public void addWindowListener(WindowListener l)
e public void removeWindowListener(WindowListener l), uma vez que nesse tipo de componente possvel ocorrer um WindowEvent.
Manipuladores de eventos de baixo nvel
Eventos de mouse so tratados pelos mtodos definidos em dois listeners distintos definidos em
java.awt.event. A interface MouseListener especifica os mtodos para os eventos de maior

c 2001 FEEC/UNICAMP

48

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

destaque na interao do usurio com o mouse. A classe abstrata MouseAdapter oferece implementaes vazias para todos esses mtodos.
Um objeto associado a um evento do mouse descreve eventos notveis ocorridos com o mouse,
como o fato de ter entrado ou sado na rea de interesse (uma janela, tipicamente), um clique
ocorrido, se alguma tecla de modificao (A LT, S HIFT ou C ONTROL) estava pressionada e a posio
na qual o evento ocorreu.
A interface MouseMotionListener especifica mtodos para manipular eventos de movimentao do mouse. A classe abstrata MouseMotionAdapter uma adaptadora para esse listener. Nesse caso, qualquer movimentao do mouse relatada, diferenciando entre eventos da forma
MOUSE_MOVED, para movimentos com o mouse livre, e MOUSE_DRAGGED, para movimentos do
mouse com algum boto pressionado.
A interface KeyListener especifica os mtodos necessrios para detectar e tratar eventos de
teclado. So eles: keyPressed(), para indicar que a tecla foi pressionada; keyReleased(),
para indicar que a tecla foi solta; e keyTyped(), para indicar que uma tecla que no de controle foi
pressionada e solta. Todos os mtodos recebem um objeto KeyEvent como parmetro. Esse objeto
indica o tipo de evento ocorrido (KEY_PRESSED, KEY_TYPED ou KEY_RELEASED), o cdigo
da tecla e se havia modificadores associados. Como essa interface listener especifica mais de um
mtodo, uma classe adaptadora, KeyAdapter, oferecida.
Manipuladores de eventos de alto nvel
Raramente uma aplicao est preocupada em tratar eventos no nvel to bsico como qualquer
movimento do mouse ou tecla pressionada. Java oferece um conjunto de funcionalidades que filtram
esses eventos para outros mais prximos da viso da aplicao, como o pressionar de um boto ou
entrar texto em um campo.
A interface ActionListener especifica o mtodo actionPerformed() para tratar eventos do tipo ao. Objetos da classe ActionEvent representam eventos associados a uma ao
aplicada a algum componente AWT.
Uma descrio (na forma de uma string) da ao pode ser obtida atravs do mtodo getActionCommand(). Dessa forma, se mais de um componente compartilha um mesmo listener, esse
mtodo permite diferenciar qual componente foi o gerador da ao.
Outro atributo que est representado em um objeto evento diz respeito aos modificadores, teclas
que podem estar apertadas simultaneamente ocorrncia do evento para requisitar um tratamento
alternativo. A classe ActionEvent define o mtodo getModifiers(), que retorna um valor
inteiro que pode ser analisado em relao a quatro constantes da classe, ALT_MASK, CTRL_MASK,
META_MASK e SHIFT_MASK.
Um objeto de uma classe que implemente ActionListener deve ser associado a um componente atravs do mtodo addActionListener(), que definido para componentes do tipo
boto, listas e campos de texto.
Quando um evento desse tipo ocorre, o objeto registrado notificado. O mtodo actionPerformed() ento invocado, recebendo como argumento o objeto que representa o evento.
Eventos associados manipulao de janelas so definidos na interface WindowListener.
Essa interface especifica os seguintes mtodos:
windowOpened() trata evento que apenas gerado quando a janela criada e aberta pela primeira

c 2001 FEEC/UNICAMP

49

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

vez
windowClosing() usurio solicitou que a janela fosse fechada, seja atravs de um menu do sistema
ou atravs de um boto da barra de ttulos ou atravs de uma sequncia de teclas do sistema.
windowClosed() trata evento que indica que a janela foi fechada.
windowIconified() trata evento que indica que janela foi iconificada.
windowDeiconified() trata evento indicando que o cone da janela foi aberto.
windowActivated() trata evento que indica que a janela ganhou o foco do teclado e tornou-se a
janela ativa.
windowDeactivated() trata evento que indica que a janela deixou de ser a janela ativa, provavelmente porque outra janela foi ativada.
Todos esses mtodos tm como argumento um objeto da classe WindowEvent, que representa
um evento de janela.
Como a interface WindowListener especifica diversos mtodos, uma classe adaptadora abstrata, WindowAdapter, fornecida com implementaes vazias de todos os mtodos.
Para implementar a interface ItemListener preciso definir a implementao do mtodo
itemStateChanged(), que recebe como argumento um objeto evento do tipo ItemEvent.
Um ItemEvent sinaliza que um elemento de algum tipo de lista de opes foi selecionado ou
desselecionado. Componentes que emitem esse tipo de evento implementam a interface ItemSelectable.
A interface TextListener especifica o mtodo que trata eventos do tipo texto. Um objeto da classe TextEvent est relacionado a um evento indicando que o usurio modificou o valor
de texto que aparece em um TextComponent qualquer modificao no texto apresentado no
componente gera esse evento. Um mtodo apenas especificado na interface, textValueChanged(TextEvent e). O corpo desse mtodo determina o que deve ser executado quando o texto
em algum componente de texto alterado.

4.2.2

Componentes grficos

A criao de uma interface grfica com usurios utiliza tipicamente uma srie de componentes
pr-estabelecidos para tal fim, tais como rtulos (labels, textos que so apresentados mas no alterveis) e botes, um componente que pode ser ativado pelo usurio atravs do mouse.
Java oferece um amplo conjunto de classes pr-definidas e re-utilizveis que simplificam o desenvolvimento de aplicaes grficas. A raiz desse conjunto de classes grficas no pacote java.awt
a classe abstrata Component, que representa qualquer objeto que pode ser apresentado na tela e
ter interao com usurios. Similarmente, o pacote Swing tem por raiz a classe JComponent, que
(indiretamente) em si uma extenso de Component.
Os mtodos da classe Component definem funcionalidades que dizem respeito manipulao
de qualquer componente grfico em Java. O mtodo getSize() permite obter a dimenso do
componente, expressa na forma de um objeto da classe Dimension um objeto dessa classe tem

c 2001 FEEC/UNICAMP

50

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

campos pblicos width e height que indicam respectivamente as dimenses horizontais e verticais do componente em pixels. J o mtodo setSize() permite definir a dimenso do componente.
Outro grupo de mtodos importantes dessa classe composto pelos mtodos que permitem determinar os manipuladores de eventos que so relevantes para qualquer tipo de objeto grfico, como os
eventos de mouse (addMouseListener(), addMouseMotionListener(), removeMouseListener(), removeMouseMotionListener()) e de teclado (addKeyListener(),
removeKeyListener()).
Subclasses de Component que so amplamente utilizadas no desenvolvimento de aplicaes
grficas incluem os containers, um objeto grfico que pode conter outros componentes, e os componentes de interface grfica com usurios.
Para manipular texto em uma interface grfica h componentes dos tipos campos de texto e reas
de texto, que permitem a entrada e/ou apresentao de texto em uma janela grfica, respectivamente
para uma nica linha ou para diversas linhas de texto.
Quando a aplicao oferece ao usurio uma srie de opes pr-estabelecidas, os componentes
tipicamente utilizados em interfaces grficas so de escolha, que pode ser nica, quando a seleo de
uma opo exclui as demais, ou mltipla, quando vrias opes podem ser selecionadas simultaneamente.
Rtulos
Rtulos so campos de texto includos em uma janela grfica com o nico objetivo de apresentao. Dessa forma, rtulos no reagem a interaes com usurios.
A classe Label define um componente de AWT que apresenta uma nica linha de texto noaltervel. Um dos atributos associados a um Label o texto a ser apresentado, que pode ser especificado em um dos construtores ou atravs do mtodo setText(). O mtodo getText() retorna
o valor desse atributo. Outro atributo de Label o alinhamento, que pode ser Label.CENTER,
Label.LEFT ou Label.RIGHT. O alinhamento pode ser definido em um dos construtores (juntamente com o texto) ou atravs do mtodo setAlignment(). O mtodo getAlignment()
retorna o valor desse atributo.
A classe JLabel define o componente Swing para implementar rtulos. Alm de oferecer facilidades equivalentes quelas de Label, JLabel oferece a possibilidade de definir o alinhamento
vertical (o padro centralizado) e de usar um cone grfico como rtulo, em adio ou em substituio a um texto.
Botes
Um boto corresponde a um componente grfico que pode ser pressionado atravs de um clique do mouse, podendo assim responder ativao por parte de um usurio.
A classe Button implementa um boto no AWT. Para criar um boto com algum rtulo, basta
usar o construtor que recebe como argumento uma string com o texto do rtulo. Alternativamente, pode-se usar o construtor padro (sem argumentos) e definir o rtulo do boto com o mtodo
setLabel(). O rtulo que foi definido para o boto pode ser obtido do mtodo getLabel().
Em Swing, o componente que define um boto JButton. Alm de poder ser definido com
rtulos de texto, um boto Swing pode conter tambm cones.

c 2001 FEEC/UNICAMP

51

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

Para manipular o evento associado seleo de um boto, preciso definir uma classe que realize
o tratamento de um evento do tipo ao implementando um ActionListener.
Campos de texto
Um campo de texto uma rea retangular, de tamanho correspondente a uma linha, que pode ser
utilizada para apresentar ou adquirir strings do usurio.
A classe TextField uma extenso da classe TextComponent que implementa um campo
de texto no toolkit AWT. Os construtores dessa classe permitem a criao de um campo de texto
que pode estar vazio ou conter algum texto inicial. O nmero de colunas no campo tambm pode ser
especificado atravs dos construtores.
O componente correspondente a esse em Swing JTextField. Alm de funcionalidades
associadas a TextField, esse componente oferece outras que permitem definir campos de texto
customizados.
Quando o usurio entra um texto em um campo de texto e tecla E NTER, gerado um evento do
tipo ao. Para indicar o objeto manipulador para esse evento, os mtodos addActionListener() e removeActionListener() so utilizados. Ambos tm como argumento um objeto
ActionListener. Eventos relativos modificao de um valor em um campo de texto (sem pressionar a tecla E NTER) esto associados a eventos do tipo texto. Desse modo, possvel monitorar se
alguma modificao ocorreu no campo de texto.
possvel no ecoar a apresentao dos caracteres de entrada para a tela definindo um carter
alternativo que deve ser apresentado. Em AWT, utiliza-se o mtodo setEchoChar() da classe
TextField. Em Swing, para tal fim deve ser utilizado o componente JPasswordField.
reas de texto
Uma rea de texto permite apresentar e opcionalmente editar textos de mltiplas linhas. possvel adicionar texto a uma rea atravs do mtodo append(), que recebe uma string como argumento.
Em AWT, a classe TextArea oferece essa funcionalidade, sendo tambm uma extenso da
classe TextComponent. Assim como para um campo de texto de uma linha, o texto apresentado inicialmente e o nmero de colunas visveis pode ser definido em construtores. Adicionalmente,
o nmero de linhas visveis pode ser definido no momento da construo do objeto. Para a apresentao de textos que ocupam uma rea maior que a visvel, um construtor tem um argumento
que indica se e quantas barras de rolagem estaro presentes na rea de texto. Os valores possveis, definidos como constantes estticas dessa classe, so SCROLLBARS_BOTH (barras de rolagem
nas direes vertical e horizontal), SCROLLBARS_HORIZONTAL_ONLY (apenas na horizontal),
SCROLLBARS_VERTICAL_ONLY (apenas na vertical) e SCROLLBARS_NONE (sem barras de rolagem).
O componente correspondente a esse em Swing o JTextArea. Em Swing, o comportamento
default para a rea de texto no ter barras de rolagem se isso for necessrio, a aplicao deve
usar um componente decorador JScrollPane. Outras diferenas dizem respeito habilidade de
mudar de linha (automtico em AWT) e gerao de eventos do tipo texto (no presente em Swing).
O framework Swing oferece, no entanto, outros componentes mais elaborados que tambm manipulam reas de texto. Componentes das classes JEditorPane e JTextPane conseguem mani-

c 2001 FEEC/UNICAMP

52

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

pular vrios tipos de contedo, como por exemplo texto em HTML.


Componentes de seleo
Java apresenta trs mecanismos bsicos para definir um componente que permite ao usurio a
seleo de opes apresentadas: drop-down, lista ou caixa de seleo.
Um componente de interao em drop-down aquele que deixa visvel uma nica opo (aquela
que est selecionada) ao usurio, mas que permite que esse visualize e selecione as outras opes
atravs da ativao de um mini-boto associado ao componente. Quando esse tipo de componente
permite tambm a entrada de valores em um campo de texto combinado lista, usualmente chamado
de combo box. Em componentes do tipo combo box, a seleo restrita a uma nica opo, com uma
lista de itens em apresentao drop-down onde apenas o elemento selecionado visvel. Os demais
itens podem ser apresentados para seleo atravs de interao com o mouse.
Em AWT, a funcionalidade de lista em drop-down suportada atravs da classe Choice, que
permite definir uma lista de itens no-editveis. Para essa classe, apenas o construtor padro oferecido. Os principais mtodos para manipular objetos dessa classe so: add(String s), que
permite adicionar itens lista; getSelectedIndex(), que retorna a posio numrica do item
selecionado na lista (o primeiro elemento tem ndice 0); getSelectedItem(), que retorna o rtulo do item selecionado na lista; e getItem(int index), retorna o rtulo do item cujo ndice
foi especificado.
A classe Choice implementa a interface ItemSelectable, o que permite associar objetos
dessa classe a um manipulador de eventos do tipo item, ItemListener.
Em Swing, o mecanismo de lista em drop-down suportado pela classe JComboBox, que pode
ser configurado para ser editvel ou no.
A segunda opo para seleo de itens oferecida atravs de listas, onde vrios itens so apresentados simultaneamente em uma janela. Na construo desse tipo de componente, o programador
pode estabelecer se a seleo ser exclusiva ou mltipla. Um componente do tipo lista oferece a funcionalidade de apresentar uma lista de opes dos quais um ou vrios itens podem ser selecionados.
Em AWT, a classe List oferece essa funcionalidade. Alm do construtor padro, essa classe
oferece um construtor que permite especificar quantas linhas da lista sero visveis. Um terceiro
construtor permite especificar um valor booleano indicando se o modo de seleo de vrios itens est
habilitado (true) ou no. Se no especificado, apenas um item pode ser selecionado da lista.
Os principais mtodos dessa classe incluem: add(String item), que acrescenta o item lista; add(String item, int index), que acrescenta um item lista na posio especificada;
getSelectedIndex(), que retorna a posio numrica do item selecionado na lista, sendo que o
primeiro item est na posio 0; getSelectedItem(), que retorna o rtulo do item selecionado
na lista; e getItem(int index), que retorna o rtulo do item cujo ndice foi especificado. H
ainda mtodos para a manipulao de selees mltiplas: getSelectedIndexes(), que retorna
um arranjo de inteiros correspondendo s posies selecionadas, e getSelectedItems(), que
retorna um arranjo de String correspondente aos rtulos dos itens selecionados.
Assim como a classe Choice, a classe List implementa a interface ItemSelectable, que
permite associar um objeto dessa classe a um manipulador de eventos do tipo item, ou seja, a um
objeto ItemListener. Esse tipo de evento gerado quando o item alvo de um nico toque do
mouse. Alm disso, um item da lista pode reagir a um toque duplo do mouse atravs da gerao
de um evento do tipo ao, usando para o tratamento do evento nesse caso um manipulador do
c 2001 FEEC/UNICAMP

53

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

tipo ActionListener. O tratamento de mltiplas selees atravs de eventos de itens no


amigvel atravs dessa interface, pois a cada seleo um novo evento gerado. Por esse motivo,
a documentao da API Java recomenda que esse tipo de seleo mltipla em AWT seja efetivada
atravs de algum controle externo, como um boto.
Em Swing, funcionalidade similar apresentada por List oferecida pela classe JList, embora algumas diferenas devam ser observadas. Por exemplo, ao contrrio de List, um JList
no suporta barras de rolagem diretamente, o que deve ser acrescido atravs de um objeto decorador
JScrollPane.
A terceira opo para selecionar itens em uma interface grfica utilizar componentes do tipo
caixas de seleo, que podem ser independentemente selecionadas ou organizadas em grupos de
caixas de seleo das quais apenas uma pode estar selecionada. Uma caixa de seleo oferece um
mecanismo de seleo em que uma opo pode assumir um de dois valores, selecionada ou noselecionada. Diz-se que tais componentes tm comportamento booleano.
Em AWT, essa funcionalidade suportada pela classe Checkbox. Alm do construtor padro,
essa classe oferece construtores que permitem expressar um rtulo (String) para o boto e o estado inicial (boolean). O mtodo getState() permite obter o estado da seleo; o mtodo
getLabel(), o rtulo associado caixa de seleo. Checkbox implementa a interface ItemSelectable, permitindo tratar reaes a eventos do tipo item atravs de um ItemListener.
Em Swing, essa funcionalidade suportada de forma similar pela classe JCheckBox.
tambm possvel definir grupos de caixas de seleo das quais apenas uma pode estar selecionada em um dado instante, constituindo assim opes exclusivas entre si. Em AWT, esse tipo de
funcionalidade oferecido atravs do conceito de um grupo de checkboxes, suportado atravs da classe CheckboxGroup. Um CheckboxGroup no um componente grfico, como um container,
mas sim um agrupamento lgico entre os componentes grficos do tipo Checkbox, que devem especificar na sua construo ou atravs do mtodo setCheckboxGroup() a qual grupo pertencem,
se for o caso de pertencer a algum.
Funcionalidade similar a essa oferecida em Swing atravs das classes JRadioButton e ButtonGroup.

4.2.3

Containers

Dificilmente uma aplicao grfica composta por um nico componente, mas sim por vrios
componentes inter-relacionados. Para este tipo de aplicao, um componente fundamental a rea
onde os demais componentes da aplicao estaro dispostos. Um componente que pode conter outros
componentes denominado um container.
Em Java, a classe Container a classe abstrata que define as funcionalidades bsicas associadas a um container, tais como adicionar e remover componentes, o que possvel atravs dos
mtodos add() e remove(), respectivamente. possvel tambm estabelecer qual a estratgia de
disposio de componentes no container, ou seja, qual o mtodo de gerncia de layout, atravs do
mtodo setLayout().
Window uma classe derivada de Container cujos objetos esto associados a janelas. Cada
objeto Window uma janela independente em uma aplicao, embora a essa janela no estejam
associadas as funcionalidades usualmente oferecidas por gerenciadores de janela. Raramente um
objeto desse usado diretamente, mas objetos dessa classe so muito utilizados atravs de suas
subclasses, tais como Frame.
c 2001 FEEC/UNICAMP

54

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

Outra classe derivada de Container de extensa aplicao Panel, que define uma rea de
composio de componentes contida em alguma janela. A classe Applet uma extenso de Panel
que permite criar applets (Seo 4.3).
Embora a classe JComponent, raiz da hierarquia para todos os componentes do novo framework
para interfaces grficas de Java, seja derivada da classe Container, no se pode acrescentar diretamente um componente grfico a qualquer componente Swing. Para as classes de Swing que
correspondem a containers no sentido definido em AWT, ou seja, s quais podem ser acrescentados outros componentes, deve-se obter uma referncia ao objeto Container atravs do mtodo
getContentPane().

4.2.4

Janelas

Janelas so reas retangulares que podem ser exibidas em qualquer parte da tela grfica de um
usurio. Em AWT, objetos da classe Window esto associados a essa funcionalidade, sendo que
nessa classe so definidos os mtodos aplicveis a qualquer tipo de janela. O framework Swing
oferece a classe JWindow, derivada da classe Window, com esse mesmo tipo de funcionalidade
porm adaptada ao novo framework.
Um objeto Window, no entanto, corresponde a uma janela sem nenhum tipo de decorao.
mais comum que aplicaes grficas criem janelas atravs de uma das classes derivadas de Window,
tais como um frame ou uma janela de dilogo. Convm destacar da classe Window os mtodos
show(), para trazer a janela para a frente da tela; dispose(), para eliminar uma janela e liberar
os recursos usados por ela usados; e addWindowListener() e removeWindowListener()
para associar ou remover objetos manipuladores de eventos de janelas.
Um frame agrega a uma janela as funcionalidades mnimas para que ela possa ser identificada e
manipulada pelo usurio da aplicao, tais como uma borda e a barra de ttulos com botes de controle
da janela. Um frame uma janela com propriedades adicionais que a habilitam a ter uma vida
independente no ambiente de janelas grficas. Para que um frame seja apresentado pela aplicao,
um objeto desse tipo de classe deve ser criado e algumas de suas propriedades bsicas tais como
sua dimenso e o fato de estar visvel ou no devem ser estabelecidas.
Em AWT, frames esto associados a objetos da classe Frame. Esse exemplo ilustra as operaes
essenciais para que um frame AWT seja criado e exibido em um ambiente grfico. O resultado da
execuo desse cdigo a criao e exibio de uma janela grfica com contedo vazio:
1
2
3
4
5
6
7
8
9
10
11
12

import java.awt.*;
import java.awt.event.*;
public class Janela extends Frame {
class WindowHandler extends WindowAdapter {
public void windowClosing(WindowEvent we) {
dispose();
System.exit(0);
}
public void windowActivated(WindowEvent we) {
we.getWindow().validate();
}
}

c 2001 FEEC/UNICAMP

55

Programao orientada a objetos com Java

13
14
15
16
17
18
19
20
21
22
23
24
25

4.2. Interfaces grficas com usurios

public Janela() {
this("Janela");
}
public Janela(String titulo) {
setTitle(titulo);
setSize(320,200);
addWindowListener(new WindowHandler());
}
public static void main(String[] args) {
Janela j = new Janela();
j.setVisible(true);
}
}

Se o tamanho da janela (em pixels, horizontal e vertical) no for definido (mtodo setSize()),
ento o default (x=0, y=0) assumido, criando uma janela de dimenses nulas. Mesmo que o tamanho seja definido, a janela quando criada por padro invisvel para exibi-la preciso invocar o
mtodo setVisible().
Frame uma extenso da classe Window que, por sua vez, uma concretizao de Container, que uma extenso de Component. Assim, importante tomar contato com os diversos
mtodos definidos ao longo dessa hierarquia para ter uma noo mais precisa sobre o que possvel
realizar com um objeto Frame. Por exemplo, para tratar eventos relativos a janelas preciso associar ao frame um WindowListener atravs do mtodo addWindowListener(), definido na
classe Window.
A classe Frame propriamente dita define os mtodos que dizem respeito ao que um frame tem
de especfico que uma janela (objeto da classe Window) no tem por exemplo, setTitle()
para definir um ttulo para a barra da janela, setMenuBar() para incluir uma barra de menus e
setCursor() para determinar o tipo de cursor a ser utilizado. O tipo de cursor definido por
uma das alternativas especificadas como constantes da classe Cursor, tais como HAND_CURSOR
ou Cursor.TEXT_CURSOR.
O pacote Swing tambm oferece a sua verso de um frame atravs da classe JFrame, que uma
extenso da classe Frame. Esse cdigo ilustra a criao de uma janela vazia, como acima, usando
JFrame:
1
2
3
4
5
6
7
8
9
10
11

import javax.swing.*;
import java.awt.event.*;
public class SJanela extends JFrame {
class WindowHandler extends WindowAdapter {
public void windowClosing(WindowEvent we) {
dispose();
System.exit(0);
}
}
public SJanela() {
this("Janela");

c 2001 FEEC/UNICAMP

56

Programao orientada a objetos com Java

12
13
14
15
16
17
18
19
20
21
22

4.2. Interfaces grficas com usurios

}
public SJanela(String title) {
setSize(200,120);
setTitle(title);
addWindowListener(new WindowHandler());
}
public static void main(String[] args) {
SJanela je = new SJanela();
je.show();
}
}

4.2.5

Gerenciadores de layout

Quando um container tem mais de um componente, preciso especificar como esses componentes devem ser dispostos na apresentao. Em Java, um objeto que implemente a interface LayoutManager responsvel por esse gerenciamento de disposio. A interface LayoutManager2
uma extenso de LayoutManager que incorpora o conceito de restries de posicionamento de
componentes em um container.
Os principais mtodos da classe Container relacionados ao layout de componentes so setLayout(), que recebe como argumento o objeto que implementa LayoutManager e que determina qual a poltica de gerncia de disposio de componentes adotada; e validate(), usado para
rearranjar os componentes em um container se o gerenciador de layout sofreu alguma modificao
ou novos componentes foram adicionados.
O pacote java.awt apresenta vrios gerenciadores de layout pr-definidos. As classes FlowLayout e GridLayout so implementaes de LayoutManager; as classes BorderLayout,
CardLayout e GridBagLayout so implementaes de LayoutManager2. Swing acrescenta
ainda um gerenciador de layout atravs da classe BoxLayout.
Para determinar que o gerenciador de layout em um container c seja do tipo XXXLayout,
preciso invocar setLayout() passando como argumento um objeto gerenciador:
c.setLayout(new XXXLayout());
Containers derivados da classe Window tm como padro um gerenciador de layout do tipo
BorderLayout, enquanto aqueles derivados de Panel usam como padro FlowLayout.
FlowLayout
FlowLayout uma classe gerenciadora de layout que arranja os componentes seqencialmente
na janela, da esquerda para a direita, do topo para baixo, medida que os componentes so adicionados ao container.
Os componentes so adicionados ao container da forma similar a um texto em um pargrafo,
permitindo que cada componente mantenha seu tamanho natural. Como padro, os componentes so
horizontalmente centralizados no container. possvel mudar esse padro de alinhamento especificando um valor alternativo como parmetro para um dos construtores da classe ou para o mtodo

c 2001 FEEC/UNICAMP

57

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

setAlignment(). Esse parmetro pode assumir um dos valores constantes definidos na classe,
tais como LEFT ou RIGHT.
possvel tambm modificar a distncia em pixels entre os componentes arranjados atravs desse
tipo de gerenciador com os mtodos setHgap() e setVgap(); alternativamente, esses valores
podem tambm ser especificados atravs de construtores da classe FlowLayout. Para obter os
valores utilizados, h mtodos getHgap() e getVgap().
Esse o gerenciador de layout padro para containers derivados de Panel, tais como Applet.
Esse exemplo ilustra o uso desse tipo de gerenciador de layout para dispor um conjunto de botes
em um frame:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

import java.awt.*;
public class JanelaFlow extends Frame {
public JanelaFlow() {
setTitle("FlowLayout");
setSize(240,100);
setLayout(new FlowLayout());
}
public void addButton(int count) {
for(int i=1; i <= count; ++i)
add(new Button("B"+i));
}
public static void main(String[] args) {
JanelaFlow j = new JanelaFlow();
int qtde = 10;
try {
if (args.length > 0)
qtde = Integer.parseInt(args[0]);
}
catch (Exception e) {
}
j.addButton(qtde);
j.validate();
j.setVisible(true);
}
}

GridLayout
GridLayout uma implementao de LayoutManager que permite distribuir componentes
ao longo de linhas e colunas. A distribuio d-se na ordem de adio do componente ao container,
da esquerda para a direita e de cima para baixo.
Essa classe oferece um construtor que permite especificar o nmero de linhas e colunas desejado
para o grid para o construtor padro, um grid de uma nica coluna usado. Adicionalmente, h

c 2001 FEEC/UNICAMP

58

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

outro construtor que permite especificar, alm da quantidade de linhas e colunas, o espao em pixels
entre esses componentes nas direes horizontal e vertical.
Deve-se observar que, nesse tipo de layout, as dimenses dos componentes so ajustadas para
ocupar o espao completo de uma posio no grid.
Esse exemplo mostra como GridLayout dispe um conjunto de dez botes em um grid de trs
linhas e quatro colunas:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

import java.awt.*;
public class JanelaGrid extends Frame {
private final int rows=3, cols=4;
public JanelaGrid() {
setTitle("GridLayout");
setSize(240,100);
setLayout(new GridLayout(rows, cols));
}
public void addButton(int count) {
int max = rows*cols;
if (count < max)
max = count;
for(int i=1; i <= max; ++i)
add(new Button("B"+i));
}
public static void main(String[] args) {
JanelaGrid j = new JanelaGrid();
int qtde = 10;
try {
if (args.length > 0)
qtde = Integer.parseInt(args[0]);
}
catch (Exception e) {
}
j.addButton(qtde);
j.validate();
j.setVisible(true);
}
}

BorderLayout
BorderLayout uma implementao de LayoutManager2 adequado para janelas com at
cinco componentes. Ele permite arranjar os componentes de um container em cinco regies, cujo
c 2001 FEEC/UNICAMP

59

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

posicionamento representado pelas constantes BorderLayout.NORTH, SOUTH, EAST, WEST e


CENTER:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

import java.awt.*;
public class JanelaBorder extends Frame {
public JanelaBorder() {
setTitle("BorderLayout");
setSize(240,100);
add(new Button("North"), BorderLayout.NORTH);
add(new Button("South"), BorderLayout.SOUTH);
add(new Button("East"), BorderLayout.EAST);
add(new Button("West"), BorderLayout.WEST);
add(new Button("Center"), BorderLayout.CENTER);
}
public static void main(String[] args) {
JanelaBorder j = new JanelaBorder();
j.validate();
j.setVisible(true);
}

Observe a utilizao do mtodo add(Component c, Object o) da classe Container,


que incorpora a especificao das restries de posicionamento.
Alm do construtor padro, outro construtor permite especificar o gap horizontal e vertical (em
pixels) entre os componentes.
Esse tipo de layout o padro para containers do tipo Frame. Para utilizar esse tipo de gerenciador para janelas com mais de cinco componentes, basta definir que o componente inserido em
um BorderLayout seja um Panel, que um container que pode ter seu prprio gerenciador de
layout.
CardLayout
Um gerenciador do tipo CardLayout empilha os componentes de um container de tal forma que
apenas o componente que est no topo permanece visvel. Esse gerenciador implementa a interface
LayoutManager2.
Os mtodos do gerenciador estabelecem funcionalidades que permitem navegar entre os componentes empilhados, determinando qual item deve estar visvel em um dado momento. Os mtodos de navegao first(), next(), previous() e last() permitem realizar uma varredura
seqencial pelos componentes de container especificado, cujo gerenciador de layout deve ser do tipo
CardLayout.
O mtodo show() permite selecionar um componente para exposio diretamente atravs de
uma string, que especificada como uma restrio quando da adio do componente ao container,
como no seguinte fragmento:
Panel p = new Panel();
cm = new CardLayout();

c 2001 FEEC/UNICAMP

60

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

p.setLayout(cm);
Button b = new Button("Teste");
p.add(b, b.getLabel());
que permitiria a exibio desse boto com a invocao
cm.show(p, b.getLabel());
Tipicamente, os componentes manipulados por um gerenciador do tipo CardLayout so containers, os quais por sua vez utilizam qualquer outro tipo de gerenciador de layout.
Esse exemplo ilustra o uso de CardLayout para organizar cinco rtulos distintos em um container alocado ao elemento central de um frame com BorderLayout. Os quatro elementos perifricos
do BorderLayout so usados para navegar entre os rtulos do CardLayout central:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

import java.awt.*;
import java.awt.event.*;
public class JanelaCard extends Frame {
Panel central = new Panel();
CardLayout cl = new CardLayout();
class FirstHandler implements ActionListener {
public void actionPerformed(ActionEvent ae) {
cl.first(central);
}
}
class LastHandler implements ActionListener {
public void actionPerformed(ActionEvent ae) {
cl.last(central);
}
}
class NextHandler implements ActionListener {
public void actionPerformed(ActionEvent ae) {
cl.next(central);
}
}
class PreviousHandler implements ActionListener {
public void actionPerformed(ActionEvent ae) {
cl.previous(central);
}
}
public JanelaCard() {
setTitle("CardLayout");
setSize(240,200);
Button next = new Button("Proximo");
next.addActionListener(new NextHandler());
Button previous = new Button("Anterior");
previous.addActionListener(new PreviousHandler());
c 2001 FEEC/UNICAMP

61

Programao orientada a objetos com Java

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

4.2. Interfaces grficas com usurios

Button first = new Button("Primeiro");


first.addActionListener(new FirstHandler());
Button last = new Button("Ultimo");
last.addActionListener(new LastHandler());
add(first, BorderLayout.NORTH);
add(last, BorderLayout.SOUTH);
add(previous, BorderLayout.WEST);
add(next, BorderLayout.EAST);
add(central, BorderLayout.CENTER);
central.setLayout(cl);
central.add(new Label("Primeiro painel"), "Primeiro");
central.add(new Label("Segundo painel"), "Segundo");
central.add(new Label("Terceiro painel"), "Terceiro");
central.add(new Label("Quarto painel"), "Quarto");
central.add(new Label("Quinto painel"), "Quinto");
}
public static void main(String[] args) {
JanelaCard jc = new JanelaCard();
jc.setVisible(true);
}
}

Nesse exemplo, o rtulo Primeiro painel inicialmente exibido por estar no topo da pilha do
objeto Panel com gerenciador do tipo CardLayout. Se o boto Prximo for pressionado, o
rtulo Segundo painel ser exibido.
GridBagLayout
GridBagLayout o gerenciador de layout mais flexvel dentre aqueles pr-definidos em java.awt; tambm, em decorrncia dessa flexibilidade, o mais complexo. uma implementao
de LayoutManager2 que permite, como GridLayout, arranjar componentes ao longo de uma
matriz de linhas e colunas. No entanto, componentes podem ser acrescentados em qualquer ordem e
podem tambm variar em tamanho, podendo ocupar mais de uma linha ou coluna.
Uma vez que o desenho da interface tenha sido especificado, a chave para a utilizao desse
gerenciador a criao de um objeto de restrio de posicionamento. Esse objeto da classe GridBagConstraints. Objetos da classe GridBagConstraints determinam como um gerenciador do tipo GridBagLayout deve posicionar um dado componente em seu container.
Uma vez que esse objeto tenha sido criado e suas restries especificadas, basta associar essas
restries ao componente usando o mtodo setConstraints() e adicion-lo ao container com o
mtodo add() com o segundo parmetro de restries. A especificao das restries de posicionamento, tamanho e propriedades de um componente nesse tipo de gerenciador determinada atravs
da atribuio de valores a campos pblicos do objeto da classe GridBagConstraints.
O posicionamento especificado pelas variveis gridx e gridy, respectivamente para indicar
a coluna e a linha onde o componente deve ser posicionado. Para gridx, o valor 0 indica a coluna
mais esquerda. Do mesmo modo, para gridy o valor 0 indica a linha mais ao topo. Alm de

c 2001 FEEC/UNICAMP

62

Programao orientada a objetos com Java

4.2. Interfaces grficas com usurios

valores absolutos de posicionamento, essa classe define a constante RELATIVE para posicionamento
relativo, aps o ltimo componente includo, sendo esse o valor padro para esses campos.
O nmero de clulas que o componente ocupa no grid indicado pelas variveis gridwidth e
gridheight, relacionadas respectivamente ao nmero de colunas e ao nmero de linhas que ser
ocupado pelo componente. O valor REMAINDER para esses campos indica que o componente ser
o ltimo dessa linha ou coluna, devendo ocupar a largura ou altura restante. O valor padro desses
campos 1.
Outras variveis de restrio definidas nessa classe incluem weightx, weighty, fill e anchor. Os atributos weightx e weighty indicam o peso, ou a prioridade, que o componente ter
para receber pores de espao extra horizontalmente ou verticalmente, respectivamente, quando o
container redimensionado e espao adicional torna-se disponvel. O padro um componente no
receber espao extra (valor 0).
O atributo fill utilizado quando a rea para a apresentao do componente maior que
o tamanho natural do componente. Indica como a apresentao do componente ir ocupar a rea
disponvel, podendo assumir os valores definidos em constantes da classe: NONE, no modifica o
tamanho do componente (o padro); VERTICAL, ocupa o espao vertical mas no altera a largura
do componente; HORIZONTAL, ocupa o espao disponvel na horizontal mas no altera a altura do
componente; e BOTH, ocupa os espao disponvel nas duas dimenses.
O atributo anchor utilizado quando o tamanho do componente menor que a rea da clula
qual ele foi alocado para indicar a posio do componente na clula. O padro CENTER, mas outros
valores possveis so NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST,
NORTHWEST.
Esse exemplo de cdigo ilustra a criao de uma janela com trs regies, sendo que a primeira
regio contm uma lista, a segunda um grupo de trs botes e a terceira uma rea de texto:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import java.awt.*;
import java.awt.event.*;
public class JanelaGridBag extends Frame {
GridBagLayout gb = new GridBagLayout();
private final int noLinhas = 3;
public JanelaGridBag() {
setTitle("GridBagLayout");
setSize(320,200);
setLayout(gb);
List lEsq = new List(noLinhas, true);
lEsq.add("Um");
lEsq.add("Dois");
lEsq.add("Tres");
lEsq.add("Quatro");
lEsq.add("Cinco");
lEsq.add("Seis");
lEsq.add("Sete");
Button add = new Button(">>");
Button clear = new Button("Clear");
Button close = new Button("Close");
c 2001 FEEC/UNICAMP

63

Programao orientada a objetos com Java

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

4.2. Interfaces grficas com usurios

TextArea tDir = new TextArea("", noLinhas,


10, TextArea.SCROLLBARS_NONE);
GridBagConstraints gc = new GridBagConstraints();
gc.gridx = 0;
gc.gridy = 0;
gc.gridwidth = 1;
gc.gridheight = 3;
gc.fill = GridBagConstraints.VERTICAL;
add(lEsq, gc);
gc.gridx = 2;
add(tDir, gc);
Insets margens = new Insets(4, 3, 4, 3);
gc.gridx = 1;
gc.gridy = 0;
gc.gridwidth = 1;
gc.gridheight = 1;
gc.fill = GridBagConstraints.BOTH;
gc.ipadx = 4;
gc.ipady = 4;
gc.insets = margens;
add(add, gc);
gc.gridy = 1;
add(clear, gc);
gc.gridy = 2;
add(close, gc);
}
public static void main(String[] args) {
JanelaGridBag jgb = new JanelaGridBag();
jgb.setVisible(true);
}
}

BoxLayout
Swing oferece um gerenciador de layout simples, com alto grau de flexibilidade, que o BoxLayout. Nesse tipo de layout, componentes podem ser dispostos em uma nica linha ou em uma
nica coluna, porm arranjos de componentes bem complexos podem ser obtidos atravs da combinao desses mecanismos.
Em BoxLayout os componentes mantm sua dimenso natural, como em FlowLayout. A
direo na qual os componentes sero dispostos se da esquerda para a direita ou se de cima
para baixo pode ser especificada no construtor da classe, atravs respectivamente das constantes
X_AXIS ou Y_AXIS.
Tipicamente, esse tipo de layout no utilizado diretamente, mas sim atravs de um container
do tipo Box, que adota BoxLayout como padro nico de gerenciamento de layout.

c 2001 FEEC/UNICAMP

64

Programao orientada a objetos com Java

4.3. Desenvolvimento de applets

Esse cdigo ilustra a construo de uma interface similar quela usando GridBagLayout,
porm construda usando caixas aninhadas:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

import javax.swing.*;
public class JanelaBox extends JFrame {
public JanelaBox() {
setTitle("BoxLayout");
setSize(240,120);
Box h = Box.createHorizontalBox();
Box v = Box.createVerticalBox();
String[] lista = {"Um", "Dois", "Tres", "Quatro",
"Cinco", "Seis", "Sete"};
JList jl = new JList(lista);
jl.setFixedCellWidth(70);
int mis = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
jl.setSelectionMode(mis);
JScrollPane lEsq = new JScrollPane(jl);
lEsq.setMinimumSize(new java.awt.Dimension(100,100));
JButton add = new JButton(">>");
JButton clear = new JButton("Clear");
JButton close = new JButton("Close");
JTextArea tDir = new JTextArea();
v.add(add);
v.add(clear);
v.add(close);
h.add(lEsq);
h.add(v);
h.add(tDir);
getContentPane().add(h);
}
public static void main(String[] args) {
JanelaBox jb = new JanelaBox();
jb.setVisible(true);
jb.validate();
}
}

4.3

Desenvolvimento de applets

Applets so programas projetados para ter uma execuo independente dentro de alguma outra
aplicao, eventualmente interagindo com esta tipicamente, um browser (navegador) Web. Assim,
applets executam no contexto de um outro programa, o qual interage com o applet e determina
assim sua seqncia de execuo. Funcionalidades associadas a applets Java so agregadas no pacote
java.applet.

c 2001 FEEC/UNICAMP

65

Programao orientada a objetos com Java

4.3. Desenvolvimento de applets

O processo de criao de um applet similar ao processo de criao de uma aplicao o programa deve ser criado por um editor de programas e o arquivo de bytecodes (com extenso .class)
deve ser gerado a partir da compilao do arquivo fonte.
Uma vez criado ou disponibilizado o bytecode, preciso incluir uma referncia a ele em alguma
pgina Web. Essa pgina Web, uma vez carregada em algum navegador, ir reconhecer o elemento
que faz a referncia ao applet, transferir seu bytecode para a mquina local e dar incio sua execuo.

4.3.1

Criao de applet

Para criar um applet, preciso desenvolver uma classe que estenda a classe Applet:
import java.applet.*;
public class MeuApplet extends Applet {
...
}
A classe Applet uma extenso de uma classe container do tipo Panel. Assim, o desenvolvimento de um applet segue as estratgias de desenvolvimento de qualquer aplicao grfica.
Um applet deve ser referenciado a partir de uma pgina Web. Tipicamente, para referenciar um
applet cujo bytecode esteja em um arquivo MeuApplet.class a partir de uma pgina usando
HTML na verso 3.2, o seguinte elemento deve ser includo na pgina:
<applet code="MeuApplet.class"
width=200 height=150>
</applet>
Atributos opcionais para o elemento APPLET incluem, entre outros, CODEBASE, que indica o
diretrio (na forma de um URL) onde est localizado o cdigo do applet, e NAME, uma string para
identificar o applet.
Para navegadores compatveis com HTML na verso 4.01 ou superiores ou ainda que usem
XHTML, a forma de referenciar um applet na pgina seria atravs da tag OBJECT:
<object codetype="application/java"
classid="java:MeuApplet.class"
width="200" height="150">
</object>
O navegador ir ento criar um espao grfico de 200 pixels de largura por 150 pixels de altura
na pgina apresentada, ir transferir o cdigo do applet do mesmo local de onde a pgina se originou
para a mquina local e dar incio execuo do applet dentro deste espao usando a mquina virtual
Java associada ao navegador.
possvel tambm passar argumentos para o cdigo do applet a partir da pgina HTML que o
referencia. Para tanto, o tag PARAM utilizado no interior do elemento APPLET, ocorrendo tantas
vezes quantos forem os argumentos para o applet. Cada ocorrncia de PARAM tem dois atributos,
name e value, que permitiro a identificao do argumento no cdigo do applet:
<applet ...>
<param name="background" value="white">
</applet>

c 2001 FEEC/UNICAMP

66

Programao orientada a objetos com Java

4.3.2

4.3. Desenvolvimento de applets

Execuo de applets

Ao contrrio das aplicaes Java, a execuo de um applet em uma pgina no iniciada pelo mtodo main(). Um applet executado como uma thread subordinada ao navegador (ou aplicao
appletviewer, presente no ambiente de desenvolvimento Java). O navegador ser responsvel
por invocar os mtodos da classe Applet que controlam a execuo de um applet.
Quando o applet carregado pela primeira vez pelo navegador, o mtodo init() invocado
pelo navegador. Esse mtodo pode ser considerado funcionalmente equivalente ao mtodo construtor
em aplicaes, pois ser apenas executado no momento em que o cdigo for carregado.
Aps o carregamento do applet para a mquina local e a execuo do mtodo init(), o mtodo
start() invocado. Esse mtodo ser invocado tambm a cada vez que a rea do applet torna-se
visvel no navegador, dando renicio a operaes que eventualmente tenham sido paralisadas pelo
mtodo stop().
O mtodo stop() invocado cada vez que o applet torna-se temporariamente invisvel, ou seja,
que sua rea no esteja visvel no navegador. uma forma de evitar que operaes que demandem
muitos ciclos de CPU continuem a executar desnecessariamente. Tambm invocado imediatamente
antes de destroy(), que invocado quando o applet est para ser eliminado do navegador. Este
mtodo serve para liberar recursos alm de memria que o applet tenha eventualmente alocado
para sua execuo.
Esse exemplo ilustra a definio de um applet que implementa apenas esses quatro mtodos.
Quando carregada em um navegador Web, a pgina que referencia esse cdigo apresenta apenas uma
rea vazia; porm, se o console Java do navegador for aberto, ser possvel visualizar as mensagens:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

import java.applet.*;
public class MeuApplet extends Applet {
public void init() {
System.out.println("MeuApplet inicializado com dimensao "
+ getSize());
}
public void start() {
System.out.println("MeuApplet deve executar");
}
public void stop() {
System.out.println("MeuApplet deve parar");
}
public void destroy() {
System.out.println("Adeus, MeuApplet");
}

Sendo Applet um componente grfico do tipo container, todas as funcionalidades descritas


para o desenvolvimento de aplicaes grficas aplicam-se a applets. Por exemplo, possvel que um
applet apresente formas geomtricas em seu contexto grfico usando o mtodo paint() ou incluir
componentes de interface com usurio e tratar a manipulao de eventos.
Alguns mtodos da classe Applet permitem a comunicao do applet com o navegador no qual
ele est inserido. O mtodo getParameter() permite a obteno dos parmetros passados pelo
navegador para o applet. O mtodo showStatus() exibe uma mensagem na linha de status do
c 2001 FEEC/UNICAMP

67

Programao orientada a objetos com Java

4.3. Desenvolvimento de applets

navegador (na barra inferior da janela) que executa o applet. O mtodo getAppletContext()
permite obter o contexto de execuo do applet, o que permite por exemplo estabelecer a comunicao entre dois applets de uma mesma pgina.
Como o cdigo de um applet geralmente obtido atravs de uma conexo remota, sua execuo
est restrita aos princpios de segurana impostos por Java para a execuo de cdigo em ambientes
distribudos. Tipicamente, um applet no pode acessar arquivos e informaes do ambiente onde est
executando nem pode estabelecer conexes remotas com outras mquinas, a no ser aquela de onde
o prprio cdigo foi obtido.

4.3.3

Passagem de parmetros

O mtodo getParameter() da classe Applet permite obter parmetros passados para o


applet atravs do elemento PARAM em uma pgina HTML. O argumento para esse mtodo o nome
do parmetro, estabelecido no atributo name da tag PARAM, e o retorno uma string com o valor do
argumento ou seja, o contedo do atributo value de PARAM.
Esse applet recebe como parmetro a cor de fundo, que pode ser branca, amarela ou cinza (o
padro):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

import java.applet.*;
import java.awt.*;
public class AppletParameter extends Applet {
private int altura;
private int largura;
private int incremento;
public void init() {
Dimension d = getSize();
altura = d.height - 2;
largura = d.width;
incremento = altura/3;
Color c = Color.gray;
String cor = getParameter("background");
try {
if (cor.equalsIgnoreCase("yellow"))
c = Color.yellow;
else if (cor.equalsIgnoreCase("white"))
c = Color.white;
}
catch (Exception e) {
}
setBackground(c);
}
public void paint(Graphics g) {
int x=1;
int y=1;

c 2001 FEEC/UNICAMP

68

Programao orientada a objetos com Java

28
29
30
31
32
33
34
35
36
37

4.3. Desenvolvimento de applets

int finalPos = largura - altura;


while (x < finalPos) {
g.setColor(new Color((float)Math.random(),
(float)Math.random(),
(float)Math.random()));
g.drawRect(x, y, altura, altura);
x += incremento;
}
}
}
Se na pgina HTML o elemento especificado for
<p>
<APPLET code="AppletParameter.class" width="640" height="20">
<PARAM name="background" value="White">
</APPLET>

o applet ser apresentado com fundo branco; com


<p>
<APPLET code="AppletParameter.class" width="640" height="20">
<PARAM name="background" value="yellow">
</APPLET>
ser apresentado com fundo amarelo. Se for invocado sem argumento, tendo na pgina HTML o
elemento
<p>
<APPLET code="AppletParameter.class" width="640" height="20">
</APPLET>
os retngulos sero desenhados sobre um fundo cinza.

4.3.4

Contexto de execuo

Em algumas situaes pode ser de interesse fazer com que o applet interaja com o contexto no
qual ele est executando (usualmente, o navegador Web). A interface AppletContext especifica
algumas funcionalidades que permitem essa interao.
Para obter o contexto no qual o applet est executando, o mtodo getAppletContext() da
classe Applet utilizado. Esse mtodo retorna um objeto AppletContext, a partir do qual
possvel obter referncias a outros applets no mesmo contexto atravs de uma enumerao, usando o
mtodo getApplets(). Alternativamente, se ao applet foi atribudo um nome usando o atributo
name na tag APPLET, uma referncia a esse applet pode ser obtida atravs do mtodo getApplet().
Como exemplo, considere a execuo de dois applets em uma pgina, onde um applet tem um
campo de texto para obter uma entrada do usurio e o outro tem uma rea de texto para exibir as

c 2001 FEEC/UNICAMP

69

Programao orientada a objetos com Java

4.3. Desenvolvimento de applets

entradas que o usurio digitou na outra janela. O primeiro applet definido em uma classe Entrada,
enquanto que o segundo definido em uma classe TextAreaApplet. A incluso em uma pgina
HTML d-se atravs de dois elementos APPLET:
<p>
<applet code="Entrada.class"
width="200" height="100"
name="entra">
</applet>
<applet code="TextAreaApplet.class"
width="200" height="100"
name="mostra">
</applet>
</p>
O applet TextAreaApplet tem simplesmente uma rea para exibio de texto:
1
2
3
4
5
6
7
8
9
10
11

import java.awt.*;
import java.applet.*;
public class TextAreaApplet extends Applet {
TextArea ta = new TextArea(5, 30);
public void init() {
add(ta);
}
public void append(String s) {
ta.append("\n" + s);
}
}

O applet Entrada define um campo para entrada de texto e estabelece a conexo entre os
contextos em seu mtodo de inicializao:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Entrada extends Applet {
TextField tf = new TextField(30);
TextAreaApplet ta;
public void init() {
add(tf);
ta = (TextAreaApplet) getAppletContext().getApplet("mostra");
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
ta.append(tf.getText());
}
});

c 2001 FEEC/UNICAMP

70

Programao orientada a objetos com Java

15
16

4.3. Desenvolvimento de applets

}
}

possvel tambm determinar que o navegador deve carregar um novo documento a partir de
um applet, usando o mtodo showDocument() de AppletContext. O argumento para esse
mtodo um objeto localizador uniforme de recursos, do tipo java.net.URL.

c 2001 FEEC/UNICAMP

71

Captulo 5

Desenvolvimento de aplicaes
distribudas
Entre os atrativos de Java est a facilidade que essa linguagem oferece para desenvolver aplicaes para execuo em sistemas distribudos. J em sua primeira verso, Java oferecia facilidades
para o desenvolvimento de aplicaes cliente-servidor usando os mecanismos da Internet, tais como
os protocolos TCP/IP e UDP.
Se o cliente na aplicao distribuda precisa acessar um servidor de banco de dados relacional,
Java oferece uma API especfica para tal fim, JDBC. Atravs das classes e interfaces desse pacote
possvel realizar consultas expressas em SQL a um servidor de banco de dados e manipular as tabelas
obtidas como resultado dessas consultas.
Em termos de desenvolvimento voltado para a World-Wide Web, Java oferece o j clssico mecanismo de applets, cdigo Java que executa em uma mquina virtual no lado do cliente Web, como
descrito na Seo 4.3. O mecanismo de servlets permite associar o potencial de processamento da
plataforma Java a servidores Web, permitindo construir assim uma camada middleware baseada no
protocolo HTTP e em servios implementados em Java.
Aplicaes distribudas mais elaboradas podem ser desenvolvidas usando uma arquitetura de objetos distribudos, onde aplicaes orientadas a objetos lidam diretamente com referncias a objetos
em processos remotos. Java oferece duas alternativas nessa direo, RMI (Remote Method Invocation), uma soluo 100% Java, e Java IDL, uma soluo integrada arquitetura padro CORBA. Um
passo adiante na evoluo desse tipo de sistema a utilizao do conceito de agentes mveis, onde
no apenas referncias a objetos so manipuladas remotamente mas os prprios objetos cdigo e
estado movem-se pela rede.

5.1

Programao cliente-servidor

O paradigma de programao distribuda atravs da separao das aplicaes entre servidores


(aplicaes que disponibilizam algum servio) e clientes (aplicaes que usam esses servios) foi
a arquitetura de distribuio predominante nos anos 1990. Um dos seus atrativos o aumento da
confiabilidade (a falha de uma mquina no necessariamente inviabiliza a operao do sistema como
um todo) e reduo de custo (mquinas mais simples podem executar os servios isoladamente, ao
invs de ter uma grande mquina fazendo todos os servios).
72

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

As aplicaes clientes e servidoras so programas executando em mquinas distintas, trocando


informao atravs de uma rede de computadores. Para que os servios possam ser solicitados, a
aplicao cliente deve conhecer quem fornece o servio (o endereo da aplicao servidora) e qual o
protocolo pr-estabelecido para realizar a solicitao.
Entre as vantagens citadas para o modelo de programao cliente-servidor destacam-se:

Relaciona a execuo de processos distintos.

Oferece uma estruturao do processamento distribudo baseado no conceito de servios, tendo


um servidor, o provedor de servios, e um cliente, o consumidor de servios oferecidos.

Permite compartilhamento de recursos, com o servidor atendendo a vrios clientes.

Oferece transparncia de localizao, com tratamento uniforme independentemente de processos estarem na mesma mquina ou em mquinas distintas.




Permite a comunicao atravs da troca de mensagens, oferecendo uma arquitetura fracamente


acoplada atravs das mensagens para solicitaes (cliente para servidor) e respostas (servidor
para cliente).
Encapsula servios, pois o cliente no precisa saber como servidor implementa o servio, mas
apenas a interface para solicitao e resposta.

Estaremos estudando aqui como Java oferece e simplifica o suporte a esse tipo de programao
atravs das funcionalidades do pacote java.net. A partir da apresentao de alguns conceitos preliminares, apresenta-se os fundamentos Java para criar aplicaes distribudas usando os mecanismos
de TCP/IP, UDP e HTTP.

5.1.1

Conceitos preliminares

A programao em redes de computadores atualmente a regra, no a exceo. A principal


vantagem nesse modelo de programao a possibilidade de distribuir tarefas computacionalmente
pesadas e conjuntos extensos de dados e informaes entre diversas mquinas.
No entanto, h um custo associado a essa distribuio. H necessidade de trocar mensagens entre
as mquinas envolvidas no processamento, com um custo (tempo) adicional necessrio para efetivar
essa troca.
importante tambm que os dispositivos envolvidos na troca de mensagens comuniquem-se
usando uma mesma linguagem, ou protocolo. Protocolos so organizados em camadas (ou pilhas)
de diferentes nveis de abstrao. O conjunto de protocolos mais comuns na programao em rede
aquele estabelecido pela arquitetura TCP/IP, que opera com um software de suporte oferecido pelo
sistema operacional de uma mquina ligada em rede.
A arquitetura TCP/IP organiza uma rede de computadores em quatro camadas:
Interface de rede: define padres de conexo rede fsica, seja local (Ethernet-CSMA/CD, Token
Ring, FDDI, ATM) ou de longa distncia (HDLC, X.25, ATM). Opera com endereos fsicos,
realizando a converso entre endereos fsicos e lgicos atravs dos protocolos ARP (Address
Resolution Protocol) e RARP (Reverse ARP).

c 2001 FEEC/UNICAMP

73

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

Inter-redes: protocolos para transporte no-confivel de mensagens (IP Internet Protocol), para
controle da comunicao e informe de erros (ICMP Internet Control Message Protocol) e
para roteamento de mensagens (EGP Exterior Gateway Protocol, RIP Routing Information Protocol). Endereos para comunicao host a host so lgicos (endereos IP).
Transporte: protocolos para transporte confivel de dados por conexo (TCP/IP Transfer Control
Protocol/IP) e para transporte de datagramas, sem conexo (UDP User Datagram Protocol).
Introduz o conceito de porta (endereo que identifica a aplicao na mquina). Endereos nesse
nvel so descritos por um par (host, port).
Aplicao: define conjunto de servios manipulados por usurios. Servios utilizam filosofia clienteservidor, com os servidores estabelecendo portas para disponibilizao do servio. Algumas
portas de servios TCP/IP j so pr-definidas, sendo denominadas de portas notveis. Exemplos de portas notveis incluem: 7, echo (reenvia o que recebe); 21, ftp (transferncia de
arquivos); 23, telnet (terminal virtual); 25, smtp (correio eletrnico); e 37, time (envia hora e
data local da mquina).
Na verso corrente do protocolo, endereos IP ocupam 32 bits e so divididos em cinco classes.
As classes A, B e C tm seus endereos estruturados em um prefixo de identificao de classe (binrios 0, 10 e 110, respectivamente), identificador de subrede (7, 14 e 21 bits) e identificador de host.
A classe D (prefixo 1110) utilizada para multicast, enquanto que endereos da classe E (11110) so
reservados para uso futuro. Usualmente, endereos IP so representados por uma qudrupla de valores decimais correspondente aos quatro grupos de 8 bits do endereo. Nessa forma de representao,
endereos iniciados por valores entre 0 e 127 so da classe A; entre 128 e 191, classe B; entre 192 e
223, classe C; entre 224 e 239, classe D; e entre 240 e 247, classe E.
Existe tambm uma forma de representao simblica de endereos IP baseada em nomes de
domnios. Domnios so parties da rede Internet organizados hierarquicamente em estruturas de
domnios e sub-domnios. Existe um mapeamento entre endereos IP representados simbolicamente
e numericamente, o qual realizado por servidores de nome distribudos pela Internet atravs do
Sistemas de Nomes de Domnio (DNS).
O desenvolvimento de software na arquitetura TCP/IP segue a filosofia de particionamento em
mltiplos processos concorrentes. Isso permite a simplificao de projeto, implementao e manipulao de software para ambientes distribudos, assim como a gerncia independente de protocolos
em diversos nveis.
O software organizado na forma de processos independentes. No nvel mais prximo da mquina, isso permite o isolamento dos dispositivos fsicos atravs da utilizao de device drivers.
No nvel da camada de transporte, dois tipos de processos so suportados. A informao em processos TCP (entrada ou sada) manipulada atravs do conceito de streams (arquivos seqenciais).
J a informao em processos UDP manipulada atravs do contedo de pacotes datagramas, enviados sem verificao de contedo ou garantia de recebimento. O processo IP atua como chaveador de
datagramas.
As portas estabelecem a ligao entre o processo da aplicao e os processos IP, estando associadas a buffers finitos com acesso controlado. O acesso a portas pode sofrer bloqueio devido a uma
tentativa de ler de uma porta com buffer vazio ou de escrever para porta com buffer cheio.

c 2001 FEEC/UNICAMP

74

Programao orientada a objetos com Java

5.1.2

5.1. Programao cliente-servidor

Aplicaes TCP/IP

Para estabelecer a conexo TCP, preciso identificar as extremidades dessa conexo tanto no
processo cliente como no processo servidor. Essas extremidades so soquetes, identificados por um
endereo de rede e um nmero de porta. A conexo pode ser interpretada como uma ligao direta
entre os dois processos, atravs da qual os bytes podem fluir nos dois sentidos.
Um soquete TCP estabelece uma conexo stream bidirecional entre os endereos (hostC,portC)
e (hostS,portS), ou seja, entre uma aplicao cliente em execuo na mquina hostC controlando a
porta portC e outra aplicao servidora em execuo na mquina hostS monitorando a porta portS de
hostS. A aplicao cliente utiliza a porta portC da mquina hostC para enviar solicitaes de servios
e para receber retornos a suas solicitaes. A aplicao servidora monitora constantemente a porta
portS da mquina hostS aguardando a chegada de solicitaes de servio. Quando alguma solicitao
recebida, a aplicao servidora executa o servio e utiliza a conexo para enviar o retorno com os
resultados do servio.
Java suporta a troca de bytes entre um cliente e um servidor TCP atravs do estabelecimento
de uma conexo entre eles. Todas as funcionalidades de Java referentes ao estabelecimento de uma
conexo TCP esto agregadas no pacote java.net.
Clientes TCP em Java
Em Java, a classe que permite o estabelecimento de uma conexo pelo lado do cliente Socket.
Para criar um soquete, o construtor da classe tipicamente utilizado :
public Socket(InetAddress address, int port) throws IOException
Uma vez que a conexo entre cliente e servidor tenha sido estabelecida pela criao dos correspondentes soquetes, os dados da aplicao podem fluir atravs dos streams a ela associados.
Os argumentos do construtor estabelecem o endereo IP da mquina remota na conexo. A classe
InetAddress de java.net permite representar endereos IP como objetos Java. Uma vez que
um objeto Java esteja representando um endereo IP, ele pode ser utilizado como parmetro para
mtodos de outras classes que manipulam transferncias de dados atravs dos protocolos TCP/IP.
Os mtodos estticos dessa classe permitem definir tais objetos associados representao simblica ou numrica de endereos IP InetAddress.getByName(String host) ou associados mquina local InetAddress.getLocalHost().
Este exemplo ilustra a manipulao de endereos IP atravs dos mtodos dessa classe:
1
2
3
4
5
6
7
8
9
10

import java.net.*;
public class WhoIs {
public static void main(String[] args) {
try {
InetAddress myself = InetAddress.getLocalHost();
System.out.println("Local host is " +
myself.getHostName() +
" at IP address " +
myself.getHostAddress());
}

c 2001 FEEC/UNICAMP

75

Programao orientada a objetos com Java

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

5.1. Programao cliente-servidor

catch (UnknownHostException uhe) {


System.err.println(uhe);
}
// Processamento dos argumentos na linha de comando
int count = 0;
InetAddress otherHost;
while (count > args.length) {
try{
otherHost = InetAddress.getByName(args[count]);
System.out.println("Host " + otherHost.getHostName() +
" is at IP address " +
otherHost.getHostAddress());
}
catch (UnknownHostException uhe) {
System.err.println(uhe);
}
++count;
}
}
}

A classe Socket oferece tambm mtodos para obter informaes sobre os endereos (mquina
e porta) envolvidos na conexo e para estabelecer timeouts associados conexo.
Quando um soquete criado, automaticamente so estabelecidos streams de entrada e de sada
para a transferncia de dados pela conexo. Os mtodos getInputStream() e getOutputStream() da classe Socket permitem identificar os objetos associados a esses streams.
Streams implementam o conceito de cadeias unidirecionais de dados (FIFO, First-In, First-Out)
apenas de escrita ou apenas de leitura. Assim, uma aplicao pode obter dados do incio de um stream
de entrada e pode enviar dados para o final de um stream de sada de dados, sempre seqencialmente.
Streams em Java so suportados por classes do pacote java.io (Seo 3.2). Para leitura seqencial de bytes utiliza-se um objeto da classe InputStream; para enviar bytes para um stream utilizase um objeto OutputStream e seus mtodos write(), para agregar bytes ao stream, e flush(),
para assegurar que os bytes inseridos sejam efetivamente encaminhados a seu destino.
Servidores TCP em Java
O processo servidor na arquitetura TCP deve estar preparado para responder a solicitaes de
conexes por parte dos clientes, permanecendo em estado de espera entre solicitaes. Assim, um
servidor TCP/IP deve realizar duas tarefas bsicas: permanecer em execuo aguardando (listening)
a chegada de requisies em alguma porta pr-especificada; e responder solicitao atravs de uma
conexo estabelecida com o cliente em funo da requisio recebida.
Em Java, a classe que permite a criao de servidores com essa funcionalidade ServerSocket, tambm do pacote java.net. O principal mtodo desta classe accept(), que implementa
a espera bloqueada por uma solicitao no endereo de porta especificado na construo do objeto.

c 2001 FEEC/UNICAMP

76

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

O retorno desse mtodo um objeto da classe Socket que estabelece a conexo com a aplicao
cliente.
Esse exemplo mostra o cdigo para um servidor que responde a qualquer solicitao com uma
mensagem fixa, cujo contedo a seqncia de bytes que compe um endereo URL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

import java.io.*;
import java.net.*;
import java.util.*;
public class TCPServer1 {
public static void main(String[] args) {
ServerSocket ss = null;
Socket cliente = null;
OutputStream os = null;
try {
ss = new ServerSocket(0);
System.out.println("Server: Aguardando na porta " +
ss.getLocalPort());
while (true) {
cliente = ss.accept();
os = cliente.getOutputStream();
System.out.println("Server: " +
"Processando solicitacao de " +
cliente.getInetAddress().getHostName());
String data =
"http://www.dca.fee.unicamp.br/cursos/PooJava/";
byte[] buffer = data.getBytes();
System.out.println("Server: Enviando \"" +
new String(buffer) + "\"");
os.write(buffer);
os.flush();
}
}
catch (Exception e) {
System.err.println(e);
}
finally {
try {
os.close();
cliente.close();
ss.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
c 2001 FEEC/UNICAMP

77

Programao orientada a objetos com Java

41
42

5.1. Programao cliente-servidor

}
}

Uso de mltiplas threads


Tipicamente, por razes de eficincia, um servidor TCP implementado como um processo
multithreaded. Um dos possveis problemas na execuo de aplicaes segundo o modelo clienteservidor est associado com o tempo de atendimento a uma solicitao pelo servidor. Se o servidor
for um processo monoltico, ele estar indisponvel para receber novas requisies enquanto a solicitao no for completamente atendida. A soluo para este problema depende da possibilidade de
se estabelecer um processamento independente para o atendimento de cada solicitao ao servidor,
liberando to cedo quanto possvel o servidor para receber novas solicitaes.
O conceito de processamento independente parte integrante da linguagem Java, atravs de multithreading. Todo processamento em Java est associado a alguma thread, sendo que novas threads
de execuo podem ser criadas a partir de qualquer thread. A criao de novas threads em geral
associada a classes que implementam a interface Runnable do pacote java.lang. Essa interface especifica o mtodo run(), os quais so utlizados para criar objetos da classe Thread, com
mtodos start() e stop(), entre outros.
Com as facilidades suportadas pela linguagem, torna-se atrativo implementar servidores multithreaded, cujo corpo principal de processamento resume-se a um lao eterno para aceitar solicitaes
na porta especificada e criar um objeto thread para atender solicitao recebida. A funcionalidade
do servio que ser executado pela thread definida no corpo do mtodo run() que implementa a
interface Runnable associada thread criada. Cada thread criada existe exclusivamente durante o
tempo necessrio para atender solicitao.
O seguinte exemplo revisita o servidor TCP anteriormente apresentado usando o mecanismo de
mltiplas threads de execuo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

import java.io.*;
import java.net.*;
import java.util.*;
class DataProvider implements Runnable {
Socket client;
OutputStream os = null;
public DataProvider(Socket s) throws IOException {
client = s;
os = client.getOutputStream();
}
public void run() {
String data =
"http://www.dca.fee.unicamp.br/courses/PooJava/";
byte[] buffer = data.getBytes();
try {
os.write(buffer);
os.flush();
os.close();

c 2001 FEEC/UNICAMP

78

Programao orientada a objetos com Java

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

5.1. Programao cliente-servidor

client.close();
}
catch (Exception e) {
System.err.println(e);
}
}
}
public class TCPServer2 {
public static void main(String[] args) {
ServerSocket ss = null;
Socket cliente = null;
try {
ss = new ServerSocket(0);
System.out.println("Server: Aguardando na porta " +
ss.getLocalPort());
while (true) {
cliente = ss.accept();
System.out.println("Server: " +
"Processando solicitacao de " +
cliente.getInetAddress().getHostName());
DataProvider dp = new DataProvider(cliente);
new Thread(dp).start();
}
}
catch (Exception e) {
System.err.println(e);
}
finally {
try {
ss.close();
}
catch (Exception e) {
System.err.println(e);
}
}
}
}

5.1.3

Aplicaes UDP

Aqui sero apresentadas as funcionalidades que Java oferece para a programao cliente-servidor
usando o protocolo de transporte UDP.
A principal diferena em relao programao cliente-servidor em TCP que o protocolo UDP
no suporta o conceito da transferncia por streams de dados. UDP trabalha diretamente com o conceito de pacotes (datagramas). Assim, UDP no oferece a garantia de envio ou recepo e nem de
c 2001 FEEC/UNICAMP

79

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

ordenao correta dos pacotes. Por outro lado, a ausncia desses mecanismos permite uma transferncia mais rpida.
O endereamento em UDP d-se como para a programao TCP, usando a classe Java InetAddress.
Soquetes UDP
Assim como para o protocolo TCP, UDP estabelece uma conexo entre o processo da aplicao
e a rede atravs de um soquete.
Em Java, soquetes UDP so manipulados atravs de objetos da classe DatagramSocket. O
construtor padro para essa classe cria um soquete local na primeira porta disponvel. Alternativamente, outro construtor permite especificar o nmero da porta desejado.
Ao contrrio da classe Socket, um DatagramSocket no estabelece uma conexo com uma
mquina remota, mas simplesmente um acesso local para a rede que pode ser utilizada para enviar e
receber pacotes, atravs dos mtodos send() e receive(), respectivamente.
H um mtodo connect() associado a objetos da classe DatagramSocket; no entanto, esse
mtodo atua como um filtro, s permitindo enviar ou receber pacotes para ou de um endereo IP ao
qual o soquete foi conectado. O mtodo disconnect() permite desconectar um soquete de um
destino pr-especificado.
Datagramas
Os pacotes enviados e recebidos atravs dos soquetes UDP so objetos Java da classe DatagramPacket. Objetos dessa classe podem ser construdos de duas maneiras, dependendo se sero
enviados ou recebidos atravs do soquete UDP:
Pacotes a enviar. Nesse caso, deve ser utilizado o construtor que incorpora em seus argumentos o
arranjo de bytes a enviar, seu tamanho, e o endereo de destino (mquina, especificada pelo
seu endereo IP, e porta).
Pacotes a receber. Nesse caso, os argumentos especificam apenas o arranjo de bytes para onde o
contedo do pacote ser transferido e o limite no tamanho do pacote que ser recebido nesse
arranjo.
Uma vez que um pacote tenha sido recebido, a informao sobre sua origem pode ser obtida
atravs dos mtodos getAddress() e getPort(). Os dados efetivamente recebidos podem ser
extrados do pacote usando o mtodo getData(); o mtodo getLength() permite determinar a
dimenso dos dados.
Multicast
Um MulticastSocket uma especializao de um DatagramSocket que permite que
uma aplicao receba pacotes datagramas associados a um endereo multicast (classe D, endereos
entre 224.0.0.1 e 239.255.255.255). No preciso nenhuma funcionalidade especial para apenas
enviar datagramas para um endereo multicast.

c 2001 FEEC/UNICAMP

80

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

Todos os soquetes multicast que estejam inscritos em um endereo multicast recebem o datagrama que foi enviado para esse endereo e porta. Para gerenciar a inscrio de um soquete em um
endereo multicast, dois mtodos so oferecidos na classe MulticastSocket.
O primeiro, joinGroup(InetAddress m), permite aplicao juntar-se a um grupo multicast. o mtodo que inscreve o soquete no grupo associado ao endereo multicast especificado
como argumento.
O outro mtodo, para desligar-se de um grupo multicast, leaveGroup(InetAddress m),
que desconecta o soquete do grupo multicast especificado.

5.1.4

Aplicaes HTTP

A World Wide Web (WWW ou simplesmente Web) a primeira concretizao de uma rede mundial de informao atravs de computadores. Proposta em 1989 no CERN (Sua) por Tim-Berners
Lee, ela interconecta principalmente documentos hipertexto (expressos em HTML HyperText
Markup Language) usando a infra-estrutura da Internet para a transferncia de informao. Sua
difuso expandiu-se principalmente aps a popularizao de interfaces grficas com o usurio para
navegao em hipertexto, iniciada a partir do lanamento do aplicativo Mosaic no NCSA (EUA).
A Web pode ser vista como um servio de aplicao da arquitetura TCP/IP. Como tal, a arquitetura da Web define um esquema de endereamento (URL) no nvel da aplicao; estabelece protocolos
de sesso (soquetes TCP/IP) e apresentao (HTML e auxiliares); define um protocolo (HTTP) no
nvel da aplicao; e segue o modelo cliente-servidor.
As aplicaes clientes na Web so usualmente navegadores (browsers) responsveis pela apresentao de documentos HTML e pela solicitao de um recurso a servidores Web. O recurso pode ser
um documento HTML ou um arquivo contendo informao texto ou binria (imagem, udio, vdeo,
applet Java, etc), conforme estabelecido pelo elemento que originou a solicitao.
No necessariamente o software navegador precisa saber manipular todos os tipos de recursos,
podendo ele ativar rotinas auxiliares de exibio para tipos no reconhecidos. As rotinas auxiliares
podem ser ativadas sob a forma de programas executveis externos ao navegador ou atravs de plugins. O conceito de plug-in foi desenvolvido pela Nestcape, sendo constitudo por uma interface de
programao (API) padronizada para ativar funcionalidades carregadas dinamicamente.
Servidores Web so responsveis por atender a solicitaes de clientes, por default operando
na porta notvel 80. As funcionalidades bsicas de servidores Web incluem: organizar e gerenciar
os recursos HTTP; prover acesso seguro a esses recursos; e processar scripts (extenses CGI, por
exemplo ver Seo 5.3).
Java tambm oferece suporte ao desenvolvimento de aplicaes sobre a Web usando recursos do
pacote java.net. Dentre os conceitos oferecidos pela linguagem Java para a programao distribuda h uma grande nfase na programao direcionada para a Web, com suporte para a manipulao
de recursos Web atravs de URL, a manipulao de conexes HTTP, a converso de strings para o
formato de codificao www-urlencoded e suporte manipulao de contedos de diferentes tipos
MIME.
Endereamento por URL
Um endereo localizador uniforme de recursos (URL) definido por uma seqncia de caracteres
que identifica de forma global e precisa um recurso na Web. A forma genrica de um URL

c 2001 FEEC/UNICAMP

81

Programao orientada a objetos com Java

5.1. Programao cliente-servidor

esquema:parte_especfica
onde o esquema identifica o protocolo utilizado para manipular o recurso, tais como http, ftp,
mailto, telnet e nntp. A parte especfica descreve o endereo do recurso de acordo com a infraestrutura e o tipo de recurso.
Na Internet, a parte especfica de um URL toma a forma genrica
//user:password@host:port/url-path
onde nem todos os campos devem necessariamente estar presentes para todos os recursos endereados. Quando port omitido, a porta notvel para o esquema especificado utilizada (21 para ftp,
23 para telnet, 25 para mailto, 80 para http). O campo url-path dependente do esquema.
A classe java.net.URL oferece a funcionalidade de nvel mais alto (menor detalhamento)
para a especificao de recursos Web. Cada recurso est associado a um objeto dessa classe, sendo
que o localizador (URL) do recurso especificado na construo do objeto.
Uma vez que o objeto URL esteja instanciado, h trs maneiras de realizar a transferncia do
contedo do recurso para a aplicao local.
Na primeira forma, atravs do mtodo openStream(), obtm-se um fluxo de leitura de bytes
que permite transferir o contedo do recurso. Outra possibilidade usar o mtodo openConnection(), que retorna um objeto da classe (abstrata) URLConnection. Esta classe permite manipular
um maior nmero de detalhes referentes conexo URL, tais como obter dimenso, tipo e codificao do contedo, manipulao do contedo associado a um stream de entrada, obteno do cabealho
e outras. Finalmente, possvel usar o mtodo getContent(), que obtm o contedo do recurso
diretamente. Nesse caso, um objeto ContentHandler especfico para o tipo de recurso recebido
ser ativado.
Conexes HTTP
O protocolo no nvel da aplicao para a transferncia de hipertexto (HTTP, HyperText Transfer
Protocol) opera sobre o protocolo TCP/IP para estabelecer um mecanismo de servio com estrutura
requisio-resposta. Uma das caractersticas peculiares de HTTP a composio flexvel do cabealho, composto por diversas linhas, o que permite sua utilizao como integrador de diversos formatos
e no apenas de documentos HTML.
Essa flexibilidade reflete-se tambm na maior complexidade desse protocolo. No entanto, possvel estabelecer servidores HTTP operando com configuraes simplificadas, onde nem todos os
servios previstos no protocolo so implementados.
Os principais servios de HTTP incluem:
GET: solicita ao servidor o envio de um recurso; o servio essencial para o protocolo.
HEAD: variante de GET que solicita ao servidor o envio apenas de informaes sobre o recurso.
PUT: permite que o cliente autorizado armazene ou altere o contedo de um recurso mantido pelo
servidor.
POST: permite que o cliente envie mensagens e contedo de formulrios para servidores que iro
manipular a informao de maneira adequada.

c 2001 FEEC/UNICAMP

82

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

DELETE: permite que o cliente autorizado remova um recurso mantido pelo servidor.
Um cabealho HTTP composto por uma linha contendo a especificao do servio e recurso
associado, seguida por linhas contendo parmetros. Um exemplo de requisio gerada por um cliente
HTTP :
GET http://www.dca.fee.unicamp.br/
Accept: text/html, image/gif, image/jpeg
User-Agent: Mozilla/3.0
para a qual o cabealho da resposta poderia ser:
HTTP/1.1 200 OK
Date: Wed, 24 Mar 1999 23:23:45 GMT
Server: Apache/1.2b6
Connection: close
Content-Type: text/html
Content-length: 648
A indicao do tipo de contedo do recurso (usada nos parmetros Accept e Content-Type)
seguem a especificao no padro MIME (Multipurpose Internet Mail Extensions).
A classe HttpURLConnection uma especializao da classe URLConnection. Quando
um objeto da classe URL invoca openConnection() esse o tipo de conexo retornada quando
o protocolo HTTP.
Alm das funcionalidades de conexes URL, essa classe define vrias constantes associadas especificamente ao protocolo HTTP (tais como os cdigos de erros) e alguns poucos mtodos especficos
de conexo HTTP.
Codificao e decodificao de dados
A traduo de strings para o formato esperado por um servidor Web a partir de um formulrio,
x-www-form-urlencoded, suportada atravs da classe URLEncoder. Essa classe oferece o mtodo
esttico encode(String s), retornando uma string com o contedo codificado do argumento.
O formato www-urlencoded agrega em uma nica string uma srie de pares na forma atributo=valor separados pelo smbolo &. Nesse formato, espaos so convertidos para o smbolo +
e caracteres com conotao especial tais como +, = e & so representados por seqncia de
escape %xx para a representao hexadecimal do valor ASCII do carter. Assim, o carter = que
faa parte do nome de um atributo ou parte do contedo de um valor ser codificado na string na
forma %3d.
O processo de traduo a partir de uma string nesse formato, que seria o necessrio para implementar um servio em Java que recebesse dados de um formulrio, oferecido pela classe URLDecoder, atravs do mtodo esttico decode(String).

5.2

Acesso a bancos de dados

A linguagem Java vem se destacando como uma alternativa vivel para a integrao de aplicaes novas e legadas na Internet. Essa infra-estrutura de integrao no estaria completa se no
contemplasse o acesso a sistemas de bancos de dados.
c 2001 FEEC/UNICAMP

83

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

Um sistema de banco de dados constitudo por uma coleo organizada de dados (a base de
dados) e pelo software que coordena o acesso a esses dados (o sistema gerenciador de banco de dados,
ou SGBD). Utilizar um sistema de banco de dados ao invs de simples arquivos para armazenar de
forma persistente os dados de uma aplicao apresenta diversas vantagens, das quais se destacam:

o desenvolvedor da aplicao no precisa se preocupar com os detalhes do armazenamento,


trabalhando com especificaes mais abstratas para a definio e manipulao dos dados;




tipicamente, um SGBD incorpora mecanismos para controle de acesso concorrente por mltiplos usurios e controle de transaes;
possvel compartilhar dados comuns entre mais de uma aplicao mesmo que a viso dos
dados de cada aplicao seja distinta.

Existem solues para integrar aplicaes Java a bancos de dados orientados a objetos e a bancos
de dados relacionais. Neste caso, a soluo padronizada atravs da especificao JDBC.

5.2.1

Bancos de dados relacionais

Um banco de dados relacional organiza seus dados em relaes. Cada relao pode ser vista
como uma tabela, onde cada coluna corresponde a atributos da relao e as linhas correspondem s
tuplas ou elementos da relao. Em uma nomenclatura mais prximas quela de sistemas de arquivos,
muitas vezes as tuplas so denominadas registros e os atributos, campos.
Um conceito importante em um banco de dados relacional o conceito de atributo chave, que
permite identificar e diferenciar uma tupla de outra. Atravs do uso de chaves possvel acelerar o
acesso a elementos (usando ndices) e estabelecer relacionamentos entre as mltiplas tabelas de um
sistema de banco de dados relacional.
Essa viso de dados organizados em tabelas oferece um conceito simples e familiar para a estruturao dos dados, sendo um dos motivos do sucesso de sistemas relacionais de dados. Certamente,
outros motivos para esse sucesso incluem o forte embasamento matemtico por trs dos conceitos utilizados em bancos de dados relacionais e a uniformizao na linguagem de manipulao de sistemas
de bancos de dados relacionais atravs da linguagem SQL.
Sob o ponto de vista matemtico, uma relao o subconjunto do produto cartesiano dos domnios da relao. Sendo um conjunto, possvel realizar operaes de conjuntos tais como unio,
interseo e diferena envolvendo duas relaes de mesma estrutura.
No entanto, um dos pontos mais fortes do modelo relacional est nos mecanismos de manipulao estabelecidos pela lgebra Relacional. Os trs principais operadores da lgebra relacional so
seleo, projeo e juno.
A operao de seleo tem como argumento uma relao e uma condio (um predicado) envolvendo atributos da relao e/ou valores. O resultado uma outra relao contemplando apenas as
tuplas para as quais a condio foi verdadeira.
A operao de projeo tem como argumento uma relao e uma lista com um subconjunto dos
atributos da relao. O resultado outra relao contendo todas as tuplas da relao mas apenas com
os atributos especificados.
Observe que se a lista de atributos no englobar a chave da relao, o resultado dessa operao
poderia gerar tuplas iguais. Sob o ponto de vista estritamente matemtico, os elementos duplicados
devem ser eliminados, pois no fazem sentido para um conjunto.
c 2001 FEEC/UNICAMP

84

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

A operao de juno recebe como argumentos duas relaes e uma condio (um predicado)
envolvendo atributos das duas relaes. O resultado uma relao com os atributos das duas relaes
contendo as tuplas que satisfizeram o predicado especificado. A operao de juno no uma
operao primitiva, pois pode ser expressa em termos da operao de produto cartesiano e da seleo,
mas uma das operaes mais poderosas da lgebra relacional.
A forma mais usual de juno aquela na qual a condio de juno a igualdade entre valores
de dois atributos das relaes argumentos. Essa forma to usual que recebe o nome de juno
natural. Nesse caso, o atributo comum aparece apenas uma vez na relao resultado, j que ele teria
para todas as tuplas o mesmo valor nas duas colunas.

5.2.2

SQL

SQL uma linguagem padronizada para a definio e manipulao de bancos de dados relacionais. Tipicamente, um SGBD oferece um interpretador SQL que permite isolar a aplicao dos
detalhes de armazenamento dos dados. Se o projetista da aplicao tiver o cuidado de usar apenas
as construes padronizadas de SQL, ele poder desenvolver a aplicao sem se preocupar com o
produto SGBD que estar sendo utilizado depois.
As trs componentes de SQL so:
1. uma linguagem de definio de dados (DDL) para definir e revisar a estrutura de bancos de
dados relacionais;
2. uma linguagem de controle de dados (DCL) para especificar mecanismos de segurana e integridade dos dados; e
3. uma linguagem de manipulao de dados (DML) para ler e escrever os dados.
A DDL supre as facilidades para a criao e manipulao de esquemas relacionais. Uma das
necessidades de uma aplicao que ir armazenar seus dados em um sistema de banco de dados
relacional como criar uma identidade para o conjunto de tabelas de sua aplicao. Esse mecanismo
no padronizado em SQL, podendo variar de fornecedor a fornecedor de banco de dados. Algumas
possibilidades incluem
CREATE SCHEMA name [AUTHORIZATION

{user | group}]

ou
CREATE DATABASE name [On {default | device}]
[Log On device [= size]]
Para criar uma tabela, o comando CREATE TABLE utilizado:
CREATE TABLE name ( ATTRIBUTE DOMAIN [UNIQUE] [{NULL | NOT NULL}])
Alguns fabricantes adotam, ao invs da forma UNIQUE para indicao de chave da relao, um
comando Primary Key aps a criao da tabela para indicar qual atributo formar ou quais atributos comporo a chave primria da relao.
O campo ATTRIBUTE especifica o nome para a aplicao da coluna da tabela, enquanto DOMAIN
especifica o tipo de dado para a coluna. Alguns tipos de dados usuais em SQL so INTEGER,
c 2001 FEEC/UNICAMP

85

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

DECIMAL(p,q) dos dgitos so casas decimais, FLOAT(p) a preciso, CHARACTER(n)


string de caracteres, BIT(n) arranjo de valores booleanos, DATE, TIME e TIMESTAMP.
Alm desses comandos, ALTER TABLE permite modificar a estrutura de uma tabela existente e
DROP TABLE permite remover uma tabela.
O principal comando da DML de SQL SELECT. Por exemplo, para obter todos os dados de
uma relao utiliza-se a forma bsica:

SELECT * FROM table


Atravs do mesmo comando, possvel especificar projees e selees de uma tabela:
SELECT columns FROM table WHERE condition
A condio pode envolver comparaes entre atributos e/ou valores constantes, podendo para
tanto utilizar comparadores tais como igual (=), maior que (>), menor que (<), maior ou igual que
(>=), menor ou igual que (<=), diferente (!= ou <>) e comparadores de strings (LIKE string, onde
string pode usar os caracteres _ e % para indicar um carter qualquer os uma seqncia qualquer de caracteres, respectivamente). As comparaes podem ser combinadas atravs dos conectivos
lgicos And, Or e Not.
possvel expressar as quatro operaes aritmticas (+, -, *, /), tanto para a condio como para
a especificao de recuperao dos dados.
possvel tambm especificar a ordem desejada de apresentao dos dados, usando para tal a forma SELECT...ORDER BY.... Uma alternativa a esse comando SELECT...GROUP BY...,
que ordena os dados e no apresenta elementos que tenham o mesmo valor para a clusula de agrupamento.
Uma importante categoria de funes de SQL incluem as funes de agregao, que permitem
computar a mdia (Avg), a quantidade (Count), o maior ou menor valor (Max ou Min) e o total
(Sum) das expresses especificadas.
Atravs do mesmo comando Select, possvel especificar consultas envolvendo mltiplas
tabelas, como em
SELECT nome, data FROM Pedidos, Clientes
WHERE Pedidos.NumCliente = Clientes.NumCliente
Nesse caso, a juno das duas tabelas Pedidos e Clientes realizada tendo como NumCliente como atributo de juno.
possvel especificar consultas internas a uma consulta, como em
SELECT NumProduto From Produtos
WHERE PrecoUnit > (SELECT Avg(PrecoUnit) FROM Produtos)
Para qualificar os resultados de uma subconsulta, podem ser utilizadas as funes All (a condio foi verdadeira para todos os elementos resultantes da subconsulta), Any (verdade para pelo
menos um elemento), Exists (verdade se resultado da consulta tem pelo menos um elemento), In
(verdade se o valor especificado faz parte do resultado), Not Exists (verdade se subconsulta teve
resultado vazio) e Not In (verdade se valor especificado no faz parte do resultado da subconsulta).
SQL oferece ainda mecanismos para inserir elementos em uma tabela,

c 2001 FEEC/UNICAMP

86

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

INSERT INTO table (columns) VALUES (values)


para modificar valores de colunas de um elemento,
UPDATE table SET column = value [, column = value]*
WHERE condition
e para remover elementos de uma tabela,
DELETE FROM table
WHERE condition
SQL pode ser utilizado diretamente pelo usurio, quando o SGBD oferece um interpretador SQL
interativo, ou atravs de comandos embutidos em uma aplicao desenvolvida em uma linguagem
de programao. No caso dessa linguagem ser Java, a forma de interagir com o banco de dados
especificado por JDBC.

5.2.3

JDBC

Java permite o acesso a bancos de dados relacionais atravs das funcionalidades definidas no
pacote java.sql, que define o produto JDBC.
JDBC uma API para execuo e manipulao de resultados a consultas SQL atravs de Java.
Para desenvolver uma aplicao com Java e bancos de dados relacionais, preciso ter disponvel:




O pacote JDBC (padro na distribuio da plataforma de desenvolvimento Java desde sua


verso 1.1);

Acesso ao servidor, o sistema gerenciador de banco de dados que entende SQL; e


O driver JDBC adequado ao tipo de SGBD acessado.

Uma vez que esses recursos estejam disponveis, a aplicao Java tem acesso ao banco de dados
relacional atravs da execuo dos seguintes passos:
1. Habilitar o driver;
2. Estabelecer uma conexo com o banco de dados;
3. Executar consulta SQL; e
4. Apresentar resultados da consulta.
Driver JDBC
Do ponto de vista da aplicao Java, um driver nada mais do que uma classe cuja funcionalidade
precisa ser disponibilizada para a aplicao. A funcionalidade bsica que um driver deve oferecer
especificada atravs da interface Driver.
A classe DriverManager estabelece um conjunto bsico de servios para a manipulao de
drivers JDBC. Como parte de sua inicializao, essa classe tentar obter o valor da propriedade

c 2001 FEEC/UNICAMP

87

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

jdbc.drivers de um arquivo de definio de propriedades e carregar os drivers especificados


pelos nomes das classes.
Alternativamente, um driver pode ser carregado explicitamente para a JVM; a forma usual para
executar essa tarefa atravs do mtodo forName() da classe Class, como em
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Conexo com banco de dados
Uma vez que o driver esteja carregado, a aplicao Java pode estabelecer uma conexo com o gerenciador de banco de dados. Para especificar com qual banco de dados deseja-se estabelecer a conexo, utilizada uma string na forma de um URL na qual o protocolo jdbc: e o restante da string
dependente do driver. Por exemplo, o driver jdbc:odbc especifica o formato jdbc:odbc:dsn,
onde dsn o data source name que identifica o banco de dados.
Identificado o banco de dados, a sesso a ser estabelecida para o acesso ao banco de dados ser
controlada por um objeto de uma classe que implementa a interface Connection. O DriverManager oferece o mtodo getConnection() para executar essa tarefa.
O encerramento de uma sesso sinalizado pelo mtodo close() da conexo:
import java.sql.*;
...
String DB = "jdbc:...";
...
Connection c = DriverManager.getConnection(DB);
...
c.close(); // encerra a sesso
Execuo da consulta
Estabelecida a conexo ao banco de dados, possvel criar uma consulta e execut-la a partir
da aplicao Java. Para representar uma consulta, o JDBC utiliza um objeto de uma classe que
implementa a interface Statement. Um objeto dessa classe pode ser obtido atravs do mtodo
createStatement() da classe Connection.
Uma vez que um objeto Statement esteja disponvel, possvel aplicar a ele o mtodo executeQuery(), que recebe como argumento uma string representando uma consulta SQL.
O resultado da execuo da consulta disponibilizado atravs de um objeto ResultSet.
import java.sql.*;
...
Connection c;
c = ...;
Statement s = c.createStatement();
String query;
query = ...;
ResultSet r = s.executeQuery(query);
...
s.close();
c 2001 FEEC/UNICAMP

88

Programao orientada a objetos com Java

5.2. Acesso a bancos de dados

Os mtodos da interface ResultSet permitem a manipulao dos resultados individuais de uma


tabela de resultados. Mtodos como getDouble(), getInt(), getString() e getTime(),
que recebem como argumento a especificao de uma coluna da tabela, permitem acessar o valor da
coluna especificada na tupla corrente para os diversos tipos de dados suportados.
Para varrer a tabela, um cursor mantido. Inicialmente, ele est posicionado antes do incio da
tabela, mas pode ser manipulado pelos mtodos first(), next(), previous(), last() e
absolute(int row).
Por exemplo,
ResultSet r = s.executeQuery("Select * from Clientes");
System.out.println("ID
NOME");
while (r.next())
System.out.println(r.getString("ClienteID")+
" " + r.getString("Nome"));
r.close();
Para lidar com atributos que podem assumir valores nulos, o mtodo wasNull() oferecido.
Ele retorna verdadeiro quando o valor obtido pelo mtodo getXXX() for nulo, onde XXX um dos
tipos SQL.
A interface ResultSetMetadata permite obter informao sobre a tabela com o resultado da
consulta. Um objeto desse tipo pode ser obtido atravs da aplicao do mtodo getMetaData()
ao ResultSet:
ResultSetMetaData m = r.getMetaData();
Uma vez obtido esse objeto, a informao desejada pode ser obtida atravs de mtodos tais como
getColumnCount(), getColumnLabel(), getColumnTypeName() e getColumnType(). O ltimo mtodo retorna tipos que podem ser identificados a partir de constantes definidas
para a classe java.sql.Types.
Alm da forma Statement, JDBC oferece duas formas alternativas que permitem respectivamente ter acesso a comandos SQL pr-compilados (PreparedStatement) e a procedimentos
armazenados no banco de dados (CallableStatement).
Exemplo completo
Este exemplo ilustra o mecanismo bsico para uma aplicao Java acessar um banco de dados. O
objetivo apresentar o contedo da seguinte relao, a tabela notas do banco de dados poojava:
> java PoojavaDB
fname
lname
Joao
Silva
Joao
Silva
Pedro
Souza
Pedro
Souza
Maria
Santos
Maria
Santos

c 2001 FEEC/UNICAMP

activ
1
2
1
2
1
2

grd
6
7
8
5
7
8

89

Programao orientada a objetos com Java

5.3. Servlets

O resultado acima foi obtido a partir da execuo da seguinte aplicao, acessando um gerenciador de banco de dados PostgreSQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

import java.sql.*;
public class PoojavaDB {
public static void main(String[] args) {
try {
// carrega driver
Class.forName("postgresql.Driver");
// estabelece conexao com banco de dados
Connection c =
DriverManager.getConnection("jdbc:postgresql:poojava",
"ricarte","");
// monta e executa consulta
Statement s = c.createStatement();
ResultSet r = s.executeQuery("Select * from notas");
// apresenta estrutura da tabela
ResultSetMetaData m = r.getMetaData();
int colCount = m.getColumnCount();
for (int i=1; i<=colCount; ++i)
System.out.print(m.getColumnName(i) + "\t\t");
System.out.println();
// apresenta resultados da consulta
while (r.next())
System.out.println(r.getString(1) + " " +
r.getString(2) + " " +
r.getInt(3) + "\t\t" +
r.getInt(4));
r.close();
// fecha conexao com banco de dados
c.close();
}
catch (Exception e) {
System.err.println(e);
}
}
}

5.3

Servlets

Servlets oferecem uma maneira alternativa a CGI para estender as funcionalidades de um servidor
Web. Na verdade, a API de servlet de Java oferece mecanismos adequados adaptao qualquer
servidor baseado em requisies e respostas, mas em aplicaes Web que servlets tm sido mais
utilizados.

c 2001 FEEC/UNICAMP

90

Programao orientada a objetos com Java

5.3. Servlets

CGI (Common Gateway Interface) a especificao de uma interface que permite que servidores
Web tenham acesso a funcionalidades oferecidas por programas executando no ambiente da mquina
servidora. Atravs de programas conectados a essa interface possvel por exemplo conectar uma
base de dados Web ou gerar dinamicamente o contedo de uma pgina HTML.
O servidor Web reconhece uma requisio CGI quando o URL especificado na solicitao identifica um arquivo executvel (programa ou script) localizado em um diretrio especfico dentro do
espao Web de recursos disponibilizados aos clientes. Parmetros podem ser repassados ao programa
CGI especificando-os no URL, separados do nome do recurso pelo carter ?.
Tipicamente um programa CGI pode ser desenvolvido em qualquer linguagem de programao
que tenha acesso leitura de variveis de ambiente e manipulao dos streams padres de entrada
e sada de dados do sistema operacional (stdin, System.in; stdout, System.out).
Com o uso de servlets, a arquitetura da Web torna-se um base atrativa para o desenvolvimento de
aplicaes distribudas em Java. A utilizao de browsers HTML simplifica o desenvolvimento das
aplicaes cliente. Servidores Web suportam os mecanismos bsicos de conexo ao cliente. Assim,
o desenvolvimento ir se concentrar na extenso dos servios atravs dos servlets.

5.3.1

Ciclo de vida de um servlet

A execuo de um servlet no difere muito de uma aplicao CGI em sua forma de interao com
o servidor. As quatro principais etapas nessa interao so:
1. cliente envia solicitao ao servidor;
2. servidor invoca servlet para a execuo do servio solicitado;
3. servlet gera o contedo em resposta solicitao do cliente; e
4. servidor envia resultado do servlet ao cliente.
Quando um servlet carregado pela primeira vez para a mquina virtual Java do servidor, o
seu mtodo init() invocado. Esse mtodo tipicamente prepara recursos para a execuo do
servio (por exemplo, abrir arquivos ou ler o valor anterior de um contador de nmero de acessos)
ou estabelece conexo com outros servios (por exemplo, com um servidor de banco de dados). O
mtodo destroy() permite liberar esses recursos (fechar arquivos, escrever o valor final nessa
sesso do contador de acessos), sendo invocado quando o servidor estiver concluindo sua atividade.
Uma diferena fundamental entre um servlet e uma aplicao CGI que a classe que implementa
o servlet permanece carregada na mquina virtual Java aps concluir sua execuo. Um programa
CGI, ao contrrio, inicia um novo processo a cada invocao por este motivo, CGI deve utilizar
mecanismos adicionais para manter o estado entre execues, sendo a forma mais comum a utilizao
de arquivos em disco. Com um servlet, tais mecanismos so necessrios apenas na primeira vez que
carregado e ao fim da execuo do servidor, ou eventualmente como um mecanismo de checkpoint.
Servlets tambm oferecem como vantagem o fato de serem programas Java. Assim, eles permitem
a utilizao de toda a API Java para a implementao de seus servios e oferecem adicionalmente
portabilidade de plataforma.

c 2001 FEEC/UNICAMP

91

Programao orientada a objetos com Java

5.3.2

5.3. Servlets

Fundamentos da API de servlets

O suporte a servlets uma extenso padronizada ao pacote Java, no sendo parte da distribuio
bsica do Java SDK. Assim, quem quiser desenvolver servlets deve obter o JSDK, o Java Servlet
Development Kit. Adicionalmente, o servidor Web deve suportar o acesso a servlets, o que pode
ocorrer de forma nativa (como no caso do Java Web Server) ou atravs de mdulos add-on (como no
caso de apache).
O JSDK inclui as classes que implementam a API de servlets organizadas em pacotes, dos quais
os principais so javax.servlet e javax.servlet.http. Adicionalmente, uma aplicao
servletrunner permite desenvolver e testar servlets antes de integr-los a servidores.
Os trs mecanismos alternativos bsicos para criar um servlet so:
1. Estender a classe javax.servlet.GenericServlet, quando o servlet no for implementar nenhum protocolo especfico de comunicao;
2. Estender a classe javax.servlet.HttpServlet, para servlets que manipulam dados
especficos do protocolo HTTP; ou
3. Implementar a interface javax.servlet.Servlet.
Na primeira forma bsica de implementar um servlet, estendendo a classe GenericServlet,
o mtodo service() deve ser definido. Esse mtodo descreve o servio que o servlet estar oferecendo.
Esse exemplo ilustra o cdigo de um servlet que responde solicitao de servio com uma
mensagem fixa:
1
2
3
4
5
6
7
8
9
10
11

import javax.servlet.*;
import java.io.*;
public class OiServlet extends GenericServlet {
public void service(ServletRequest solicitacao,
ServletResponse resposta)
throws ServletException, IOException {
resposta.setContentType("text/plain");
PrintWriter saida = resposta.getWriter();
saida.println("Oi!");
}
}

Nesse exemplo, o mtodo getWriter() utilizado para estabelecer o canal de envio de dados
desde o servlet no caso, um objeto PrintWriter, permitindo o envio de textos. Alternativamente, dados binrios poderiam ser enviados atravs de um OutputStream, obtido atravs do
mtodo getOutputStream().
A classe HttpServlet uma extenso de GenericServlet especificamente projetada para
a conexo de servlets a servidores HTTP. Assim, mtodos dedicados a lidar com solicitaes HTTP,
tais como doGet(), doPost() e doPut(), so definidos. A implementao padro do mtodo
service() reconhece qual o tipo de solicitao recebida e invoca o mtodo correspondente.

c 2001 FEEC/UNICAMP

92

Programao orientada a objetos com Java

5.3. Servlets

Este exemplo ilustra a utilizao de um servlet que envia uma mensagem fixa no corpo de uma
pgina HTML em resposta a uma requisio GET ao servidor Web, usando para tal o mtodo doGet():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class OiHttpServlet extends HttpServlet {
public void doGet(HttpServletRequest solicitacao,
HttpServletResponse resposta)
throws ServletException, IOException {
resposta.setContentType("text/html");
PrintWriter saida = resposta.getWriter();
saida.println("<HTML>");
saida.print("<HEAD><TITLE>");
saida.print("Resposta do servlet");
saida.println("</TITLE></HEAD>");
saida.println("<BODY><P>Oi!</P></BODY>");
saida.println("</HTML>");
}
}

Outros mtodos que suportam a interao do servlet atravs de solicitaes HTTP incluem getLastModified(), que invocado pelo servidor para obter a data da ltima modificao do documento (um nmero negativo se no houver informao ou long com o nmero de segundos desde
1 de janeiro de 1970 GMT); e getServletInfo(), que retorna uma string de documentao
sobre o servlet, tal como nome, autor e verso.
A passagem de dados de um formulrio do cliente para o servlet pode se dar atravs do mtodo
getParameter(), que permite obter uma string com o valor do campo especificado. Por exemplo,
se um formulrio HTML especificasse um campo de texto para entrada do nome do usurio, como
em
<INPUT type="text" name="username" size=20>
esse valor poderia ser obtido no cdigo do servlet do exemplo anterior atravs da invocao
String nome = solicitacao.getParameter("username");
Alm de getParameter(), o mtodo getParameterValues() retorna um arranjo de
strings com todos os valores de um determinado parmetro. Outros mtodos so oferecidos para obter informao das aplicaes que esto invocando o servlet, tais como getRemoteHost(), getServerName(), getServerPort() e, especificamente para HTTP, getHeaderNames() e
getHeader().
A forma de integrar o servlet ao servidor Web dependente da implementao; por exemplo,
alguns servidores especificam um diretrio (tal como servlet) onde as classes servlets so concentradas e a invocao d-se pela invocao direta da URL, como em
http://site/servlet/OiHttpServlet

c 2001 FEEC/UNICAMP

93

Programao orientada a objetos com Java

5.4

5.4. Programao com objetos distribudos

Programao com objetos distribudos

Na programao distribuda usando a arquitetura cliente-servidor, clientes e servidores podem


ser implementados usando qualquer paradigma de programao. Assim, possvel que um servio
especfico seja executado por um mtodo de algum objeto. No entanto, mesmo que o cliente tambm tenha sido desenvolvido orientao a objetos, na comunicao entre o cliente e o servidor esse
paradigma deve ser esquecido, devendo ser utilizado algum protocolo pr-estabelecido de troca de
mensagens para a solicitao e resposta ao servio.
Um sistema de objetos distribudos aquele que permite a operao com objetos remotos. Dessa
forma possvel, a partir de uma aplicao cliente orientada a objetos, obter uma referncia para um
objeto que oferece o servio desejado e, atravs dessa referncia, invocar mtodos desse objeto
mesmo que a instncia desse objeto esteja em uma mquina diferente daquela do objeto cliente.
O conceito bsico que suporta plataformas de objetos distribudos o conceito de arquiteturas
de objetos. Essencialmente, uma arquitetura orientada a objetos estabelece as regras, diretrizes e
convenes definindo como as aplicaes podem se comunicar e inter-operar. Dessa forma, o foco
da arquitetura no em como a implementao realizada, mas sim na infra-estrutura e na interface
entre os componentes da arquitetura.
Na plataforma Java, dois mecanismos so oferecidos para o desenvolvimento de aplicaes usando o conceito de objetos distribudos: Java RMI e Java IDL. RMI (invocao remota de mtodos)
um mecanismo para desenvolver aplicaes com objetos distribudos que opera exclusivamente com
objetos Java. Java IDL utiliza a arquitetura padro CORBA para integrao de aplicaes Java a
aplicaes desenvolvidas em outras linguagens.

5.4.1

Arquiteturas de objetos distribudos

No paradigma de arquiteturas de objetos, h trs elementos principais. A arquitetura OO fornece uma descrio abstrata do software que categorias de objetos sero utilizadas, como estaro
particionados e como interagiro. As interfaces distribudas so as descries detalhadas das funcionalidades do software. Finalmente, a implementao composta por mdulos de software que
suportam as funcionalidades especificadas nas interfaces distribudas.
O uso de interfaces distribudas permite isolar a arquitetura de um sistema de sua implementao. Dessa forma, o sistema pode ser construdo com um alto grau de independncia em relao s
implementaes especficas de suas funcionalidades, ou seja, possvel substituir implementaes
especficas com pequeno impacto sobre o sistema como um todo.
A adoo do paradigma de arquitetura de objetos permite tambm atingir um alto grau de interoperabilidade atravs da adoo de uma infra-estrutura padronizada de comunicao entre objetos
atravs das interfaces. Assim, cada componente da arquitetura deve se preocupar apenas em como
se dar sua comunicao com a infra-estrutura de comunicao, estabelecida atravs de um objeto
wrapper. Sem essa padronizao, seria necessrio estabelecer os mecanismos de comunicao com
todos os demais componentes do sistema.
Em uma arquitetura de objetos, alguma forma deve ser estabelecida para que clientes possam
localizar servios que esto sendo oferecidos. Isso usualmente oferecido na forma de um servio
bsico da plataforma de objetos distribudos. Do ponto de vista de quem oferece o servio, preciso
habilitar o objeto para que seus mtodos possam ser invocados remotamente. Isto realizado atravs
das seguintes atividades:

c 2001 FEEC/UNICAMP

94

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

Descrever o servio. Na arquitetura de objetos, a descrio ou especificao de servios determinada atravs das interfaces. Em Java, isto realizado atravs da especificao oferecida por
uma interface.
Implementar o servio. Isto realizado atravs do desenvolvimento de uma classe Java que implemente a interface especificada.
Anunciar o servio. Quando um objeto que implementa o servio torna-se ativo, preciso que ele
seja registrado em um diretrio de servios de forma que potenciais clientes possam localizlo.
Sob o ponto de vista do objeto cliente, que vai usar o servio do objeto remoto, preciso localizar
o servio, o que feito acessando o registro de servios. Portanto, necessrio que servidores e
clientes estejam de acordo com o local (a mquina) onde o registro realizado. Como resultado
dessa tarefa, obtm-se uma referncia ao objeto remoto que pode ser utilizada como se fosse uma
referncia para o objeto local.
A utilizao desse mecanismo de localizar o servio atravs de um diretrio ou registro permite
que as mquinas clientes ignorem totalmente em que mquinas os servios solicitados esto operando
uma facilidade conhecida como transparncia de localizao.
Um dos principais objetivos em uma plataforma de objetos distribudos atingir transparncia de
localizao, tornando uniforme a forma de utilizao de objetos independentemente desses objetos
estarem na mquina local da aplicao ou em mquinas distintas.
A fim de que se atinja transparncia de localizao, as seguintes funcionalidades devem ser oferecidas:
1. Localizar e carregar classes remotas;
2. Localizar e obter referncias a objetos remotos; e
3. Habilitar a invocao de mtodos de objetos remotos.
A primeira funcionalidade, no muito diferente do que ocorre em sistemas com objetos locais,
necessria para que a aplicao conhea as facilidades oferecidas pelo objeto remoto.
Referncias a objetos tambm so utilizadas em sistemas com objetos locais, porm com diferenas significativas. Em um sistema local, as referncias a objetos so tipicamente manipuladores com
especificao de endereos de memria. No caso de objetos remotos, esses endereos da memria
de outra mquina no tm validade na mquina local. Assim, preciso oferecer mecanismos que
traduzam essas referncias entre mquinas de forma transparente para o programador.
Para a invocao de mtodos de um objeto remoto, alm da necessidade de se localizar a referncia ao mtodo preciso oferecer mecanismos para tornar transparente a passagem de argumentos
para e o retorno de valores desde o mtodo.
Alm dessas funcionalidades, a comunicao de falhas no oferecimento da transparncia de localizao ao programador essencial. Assim, funcionalidades para comunicar excees entre mquinas
tambm dever ser suportadas pela plataforma de objetos distribudos.

c 2001 FEEC/UNICAMP

95

Programao orientada a objetos com Java

5.4.2

5.4. Programao com objetos distribudos

Java RMI

RMI (Remote Method Invocation) uma das abordagens da tecnologia Java para prover as funcionalidades de uma plataforma de objetos distribudos. Esse sistema de objetos distribudos faz parte
do ncleo bsico de Java desde a verso JDK 1.1, com sua API sendo especificada atravs do pacote
java.rmi e seus subpacotes.
Atravs da utilizao da arquitetura RMI, possvel que um objeto ativo em uma mquina virtual
Java possa interagir com objetos de outras mquinas virtuais Java, independentemente da localizao
dessas mquinas virtuais.
A arquitetura RMI oferece a transparncia de localizao atravs da organizao de trs camadas
entre os objetos cliente e servidor:
1. A camada de stub/skeleton oferece as interfaces que os objetos da aplicao usam para interagir
entre si;
2. A camada de referncia remota o middleware entre a camada de stub/skeleton e o protocolo
de transporte. nesta camada que so criadas e gerenciadas as referncias remotas aos objetos;
3. A camada do protocolo de transporte oferece o protocolo de dados binrios que envia as solicitaes aos objetos remotos pela rede.
Desenvolvimento da aplicao RMI
No desenvolvimento de uma aplicao cliente-servidor usando Java RMI, como para qualquer
plataforma de objetos distribudos, essencial que seja definida a interface de servios que sero
oferecidos pelo objeto servidor.
A especificao de uma interface remota equivalente definio de qualquer interface em Java,
a no ser pelos seguintes detalhes: a interface dever, direta ou indiretamente, estender a interface
Remote; e todo mtodo da interface dever declarar que a exceo RemoteException (ou uma
de suas superclasses) pode ser gerada na execuo do mtodo.
Esse exemplo ilustra a definio de uma interface remota para um objeto que contm um contador
inteiro:
1
2
3
4
5
6
7

import java.rmi.*;
public interface Count extends Remote {
void set(int val) throws RemoteException;
void reset() throws RemoteException;
int get() throws RemoteException;
int increment() throws RemoteException;
}
Esse contador manipulado por quatro mtodos: set(), para definir um valor inicial para o contador; reset(), para reiniciar o contador com o valor 0; get(), para consultar o valor do contador
sem alter-lo; e increment(), que l o valor atual do contador e incrementa-o.
Os servios especificados pela interface RMI devero ser implementados atravs de uma classe Java. Nessa implementao dos servios preciso indicar que objetos dessa classe podero ser
acessados remotamente.

c 2001 FEEC/UNICAMP

96

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

A implementao do servio se d atravs da definio de uma classe que implementa a interface especificada. No entanto, alm de implementar a interface especificada, preciso incluir as
funcionalidades para que um objeto dessa classe possa ser acessado remotamente como um servidor.
A implementao da interface remota se d da mesma forma que para qualquer classe implementando uma interface Java, ou seja, a classe fornece implementao para cada um dos mtodos
especificados na interface.
As funcionalidades de um servidor remoto so especificadas na classe abstrata RemoteServer,
do pacote java.rmi.server. Um objeto servidor RMI dever estender essa classe ou, mais
especificamente, uma de suas subclasses. Uma subclasse concreta de RemoteServer oferecida
no mesmo pacote UnicastRemoteObject, que permite representar um objeto que tem uma
nica implementao em um servidor (ou seja, no replicado em vrios servidores) e mantm uma
conexo ponto-a-ponto com cada cliente que o referencia.
Tipicamente, a declarao de uma classe que implementa um servidor remoto RMI ter a forma
public class ... extends UnicastRemoteObject implements ... {
...
}
Esse exemplo oferece uma possvel implementao para a interface remota previamente especificada:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class CountImpl extends UnicastRemoteObject
implements Count {
private int sum;
public CountImpl() throws RemoteException {
}
public void set(int val) throws RemoteException {
sum = val;
}
public void reset() throws RemoteException {
sum = 0;
}
public int get() throws RemoteException {
return sum;
}
public int increment() throws RemoteException {
return sum++;
}
}

Clientes e servidores RMI


Uma vez que a interface remota esteja definida e a classe que implementa o servio remoto tenha
sido criada, o prximo passo no desenvolvimento da aplicao distribuda desenvolver o servidor
c 2001 FEEC/UNICAMP

97

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

RMI, uma classe que crie o objeto que implementa o servio e cadastre esse servio na plataforma
de objetos distribudos.
Um objeto servidor RMI simples deve realizar as seguintes tarefas: criar uma instncia do objeto
que implementa o servio; e disponibilizar o servio atravs do mecanismo de registro.
O desenvolvimento de um cliente RMI requer essencialmente a obteno de uma referncia remota para o objeto que implementa o servio, o que ocorre atravs do cadastro realizado pelo servidor.
Uma vez obtida essa referncia, a operao com o objeto remoto indistingvel da operao com
um objeto local.
Usando o servio de nomes
O aplicativo rmiregistry faz parte da distribuio bsica de Java. Tipicamente, esse aplicativo executado como um processo de fundo (em background) que fica aguardando solicitaes em
uma porta, que pode ser especificada como argumento na linha de comando. Se nenhum argumento
for especificado, a porta 1099 usada como padro.
O aplicativo rmiregistry uma implementao de um servio de nomes para RMI. O servio
de nomes uma espcie de diretrio, onde cada servio disponibilizado na plataforma registrado
atravs de um nome do servio, uma string nica para cada objeto que implementa servios em RMI.
Para ter acesso ao servio de nomes a partir de uma classe Java, so oferecidos dois mecanismos
bsicos. O primeiro utiliza a classe Naming, do pacote java.rmi. O segundo mecanismo utiliza
as facilidades oferecidas atravs das classes no pacote java.rmi.registry.
A classe Naming permite a realizao da busca de um servio pelo nome (lookup) usando o
mtodo esttico lookup(String nome), que retorna uma referncia para o objeto remoto. O
servio de registro aonde a busca se realiza especificado pela string usando uma sintaxe similar
URL:
rmi://objreg.host:port/objname
O protocolo padro rmi, sendo no momento o nico suportado atravs desse mtodo. Se no
especificado, o host a mquina local e a porta 1099. O nome de registro do objeto a nica parte
obrigatria desse argumento.
Alm de lookup() os mtodos bind(), rebind(), unbind() e list(), descritos na
seqncia, so tambm suportados.
Outra alternativa para ter acesso ao servio de nomes a partir da aplicao Java utilizar as
funcionalidades do pacote java.rmi.registry, que oferece uma classe e uma interface para
que classes Java tenham acesso ao servio de nomes RMI.
A interface Registry representa uma interface para o registro de objetos RMI operando em
uma mquina especfica. Atravs de um objeto dessa classe, possvel invocar o mtodo bind()
que associa um nome de servio (um String) ao objeto que o implementa.
Para obter uma referncia para um objeto Registry so utilizados os mtodos da classe LocateRegistry, todos estticos, tais como getRegistry(). H quatro verses bsicas desse
mtodo:
1. getRegistry(): obtm referncia para o registro local operando na porta default;
2. getRegistry(int port): obtm referncia para o registro local operando na porta especificada;
c 2001 FEEC/UNICAMP

98

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

3. getRegistry(String host): obtm referncia para o registro remoto operando na porta default;
4. getRegistry(String host, int port): obtm referncia para o registro remoto
operando na porta especificada.
O mtodo esttico createRegistry(int port) pode ser utilizado para iniciar um servio de registro na mquina virtual Java corrente na porta especificada como argumento, retornando
tambm um objeto da classe Registry.
Inicialmente, preciso obter uma referncia para o servio de registro, atravs da invocao do
mtodo:
Registry r = LocateRegistry.getRegistry();
Observe que a referncia para Registry em si uma referncia para um objeto remoto, uma
vez que a interface Registry uma extenso da interface Remote.
Uma vez que a referncia para o servio de registro tenha sido obtida, possvel acessar as
funcionalidades desse servio atravs dos mtodos da interface Registry. Particularmente, para
registrar um novo servio utiliza-se o mtodo bind():
r.bind(serviceName, myCount);
O objeto que est sendo registrado deve implementar tambm a interface Remote, que identifica
todos os objetos que podem ser acesados remotamente.
Outros servios disponveis atravs dos mtodos de Registry incluem atualizao, remoo
e busca dos servios l registrados. Para atualizar um registro j existente, o mtodo rebind()
pode ser utilizado. Para eliminar um registro, utiliza-se o mtodo unbind(). Dado o nome de um
servio, o objeto Remote que o implementa pode ser obtido pelo mtodo lookup(). O mtodo
list() retorna um arranjo de String com os nomes de todos os servios registrados.
Implementao do servidor RMI
Como observado, um objeto servidor RMI simples deve realizar as seguintes tarefas:
1. Criar uma instncia do objeto que implementa o servio; e
2. Disponibilizar o servio atravs do mecanismo de registro.
Esse exemplo de servidor RMI para o contador remoto cria uma instncia da implementao do
servio e coloca-a disposio de potenciais clientes, registrando-o no registry RMI:
1
2
3
4
5
6
7

import java.rmi.registry.*;
public class CountServer {
public static void main(String[] args) {
try {
String serviceName = "Count001";
CountImpl myCount = new CountImpl();
Registry r = LocateRegistry.getRegistry();

c 2001 FEEC/UNICAMP

99

Programao orientada a objetos com Java

8
9
10
11
12
13
14
15
16

5.4. Programao com objetos distribudos

r.bind(serviceName, myCount);
System.out.println("Count Server ready.");
}
catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
e.printStackTrace();
}
}
}

Cliente RMI
A principal etapa no desenvolvimento de uma aplicao cliente RMI a obteno da referncia
remota para o objeto (remoto) que implementa o servio desejado. Para tanto, o cliente RMI usa o
servio padro oferecido pelo mecanismo de registro de nomes de servios.
Uma vez que a referncia remota seja obtida, ela pode ser convertida (downcast) para uma referncia para a interface que especifica o servio. A partir de ento, os mtodos oferecidos pelo servio
remoto so invocados da mesma forma que ocorre para objetos locais.
Esses exemplos ilustram o desenvolvimento de cdigo cliente em RMI. No primeiro exemplo
desenvolve-se um cliente RMI que simplesmente invoca o mtodo reset() atravs de uma referncia remota para o objeto servidor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

import java.rmi.registry.*;
public class CountReset {
public static void main(String args[]) {
try {
Registry r = LocateRegistry.getRegistry();
Count myCount = (Count) r.lookup("Count001");
myCount.reset();
}
catch(Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}

Nesse outro exemplo, o cliente utiliza os mtodos para modificar e obter o valor do contador
remoto. Ele tambm ilustra a interao de um cdigo com o registro RMI atravs da classe Naming:
1
2
3
4
5
6

import java.rmi.*;
public class CountClient {
public static void main(String args[]) {
try {
Remote remRef = Naming.lookup("Count001");
Count myCount = (Count) remRef;
c 2001 FEEC/UNICAMP

100

Programao orientada a objetos com Java

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

5.4. Programao com objetos distribudos

int initValue = myCount.get();


System.out.print("De " + initValue + " para ");
long startTime = System.currentTimeMillis();
for (int i = 0 ; i < 1000 ; i++ )
myCount.increment();
long stopTime = System.currentTimeMillis();
System.out.println(myCount.get());
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f)
+ " msecs");
}
catch(Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}

Esse terceiro exemplo ilustra a utilizao de RMI a partir de um cliente desenvolvido como um
applet. Nesse applet, um campo de texto mostra o valor do contador no objeto servidor. Dois botes
so fornecidos, um para incrementar o valor mil vezes Start) e outro para obter o valor atual do
contador Get):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

import java.rmi.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class AppletClient extends Applet
implements ActionListener {
Count remCount;
TextField tfCnt;
Button bStart, bGet;
String bslabel = "Start";
String bglabel = "Get";
public void init() {
try {
setLayout(new GridLayout(2,2));
add(new Label("Count:"));
tfCnt = new TextField(7);
tfCnt.setEditable(false);
add(tfCnt);
bStart = new Button(bslabel);
bStart.addActionListener(this);
bGet = new Button(bglabel);
bGet.addActionListener(this);

c 2001 FEEC/UNICAMP

101

Programao orientada a objetos com Java

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

5.4. Programao com objetos distribudos

add(bStart);
add(bGet);
showStatus("Binding remote object");
remCount = (Count) Naming.lookup("Count001");
tfCnt.setText(Integer.toString(remCount.get()));
}
catch (Exception e) {
e.printStackTrace();
}
}
public void paint() {
try {
tfCnt.setText(Integer.toString(remCount.get()));
}
catch (Exception e) {
e.printStackTrace();
}
}
public void actionPerformed (ActionEvent ev) {
try {
String botao = ev.getActionCommand();
if (botao.equals(bslabel)) {
showStatus("Incrementing...");
for (int i = 0 ; i < 1000 ; i++ )
remCount.increment();
showStatus("Done");
}
else {
showStatus("Current count");
paint();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

Definindo stubs e skeletons


Para que um servio oferecido por um objeto possa ser acessado remotamente atravs de RMI,
preciso tambm as classes auxiliares internas de stubs e skeletons, responsveis pela comunicao
entre o objeto cliente e o objeto que implementa o servio, conforme descrito na apresentao da
arquitetura RMI.
Uma vez que a interface e a classe do servio tenham sido criadas e compiladas para bytecoc 2001 FEEC/UNICAMP

102

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

des usando um compilador Java convencional, possvel criar os correspondentes stubs e skeletons.
Para tanto, utiliza-se o aplicativo compilador RMI, rmic, disponibilizado juntamente com o kit de
desenvolvimento Java.
Um exemplo ilustra o processo de compilao RMI para o servio do contador remoto. Considere
a implementao do servio que foi previamente definida. O primeiro passo para a criao do stub
e do skeleton para esse servio obter a classe compilada, que por sua vez precisa da classe da
interface:
> javac Count.java
> javac CountImpl.java
Com a classe CountImpl.class disponvel, a execuo do comando
> rmic CountImpl
gera as classes CountImpl_Stub.class e CountImpl_Skel.class, correspondendo respectivamente ao stub e ao skeleton para o servio. O stub dever ser disponibilizado junto ao cdigo
do cliente RMI, enquanto que o skeleton dever estar disponvel junto ao cdigo do servidor.
Uma classe stub oferece implementaes dos mtodos do servio remoto que so invocadas no
lado do cliente. Internamente, esses mtodos empacotam marshall) os argumentos para o mtodo e
os envia ao servidor. A implementao correspondente no lado servidor, no skeleton, desempacota
(unmarshall) os dados e invoca o mtodo do servio. Obtido o valor de retorno do servio, o mtodo
no skeleton empacota e envia esse valor para o mtodo no stub, que ainda estava aguardando esse
retorno. Obtido o valor de retorno no stub, esse desempacotado e retornado aplicao cliente
como resultado da invocao remota.
Internamente, o processo de marshalling utiliza o mecanismo de serializao de Java. Assim,
argumentos e valores de retorno de mtodos remotos invocados atravs de RMI esto restritos a tipos
primitivos de Java e a objetos de classes que implementam Serializable.
Usando fbricas de objetos remotos
Pode haver situaes em que no seja interessante registrar cada implementao de um servio
no registry por exemplo, quando o servidor no sabe quantos objetos criar de antemo ou quando
a quantidade de pequenos servios registrados e to grande que pode tornar a busca por um servio
ineficiente.
Nessas situaes, pode ser interessante utilizar uma fbrica de objetos remotos. Nesse caso, o
servidor que est registrado em rmiregistry no uma implementao individual do servio,
mas sim um gerenciador de instncias de implementao do servio. Esse gerenciador deve implementar uma interface remota que permita que o cliente obtenha uma referncia remota para o servio
desejado em duas etapas:
1. obtendo a referncia para o gerenciador atravs da invocao do mtodo lookup(); e
2. obtendo a referncia para o servio propriamente dito atravs da invocao do mtodo do
gerenciador que retorna a referncia.

c 2001 FEEC/UNICAMP

103

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

Esses exemplos usando contadores inteiros ilustram a utilizao do conceito de fbrica de objetos
remotos. Alm da implementao do servio e da sua correspondente interface, preciso inicialmente
definir uma interface para a fbrica. Nesse exemplo, essa interface especifica a funcionalidade de um
gerenciador de contadores, que recebe o nome do contador e retorna uma referncia remota para
um objeto contador:
import java.rmi.*;
public interface CountManager extends Remote {
Count getCount(String nome) throws RemoteException;
}

1
2
3
4

No lado servidor, o que muda em relao ao exemplo anterior que agora no mais o objeto
que implementa o contador que deve ser cadastrado no registry, mas sim o objeto fbrica, uma implementao da interface especificada para o gerenciador de contadores. Essa fbrica, por sua vez,
mantm um registro interno dos objetos criados para poder retornar as referncias solicitadas pelos
clientes remotos. Essa classe combina as funcionalidades da implementao de uma interface remota
com aquelas de um servidor RMI:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;
public class CManagerImpl extends UnicastRemoteObject
implements CountManager {
private Hashtable counters = new Hashtable();
public CManagerImpl() throws RemoteException {
}
public Count getCount(String nome) throws RemoteException {
Count rem = null;
if (counters.containsKey(nome))
rem = (Count) counters.get(nome);
else {
rem = new CountImpl();
counters.put(nome,rem);
System.out.println("New counter: " + nome);
}
return rem;
}
public static void main(String[] args) {
try {
String serviceName = "CountFactory";
CManagerImpl myCM = new CManagerImpl();
Registry r = LocateRegistry.getRegistry();
r.bind(serviceName, myCM);
System.out.println("CountFactory ready.");
}
c 2001 FEEC/UNICAMP

104

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

catch (Exception e) {
e.printStackTrace();
}

29
30
31
32
33

}
}

No lado do cliente h referncias agora a duas interfaces remotas, uma para o gerenciador de
contadores e outra para o contador. A primeira delas resolvida atravs do servio de registro do
RMI, enquanto que a referncia para o objeto do segundo tipo de interface obtido a partir dessa
referncia para o gerenciador que foi obtida:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

import java.rmi.*;
public class CountClient {
public static void main(String args[]) {
String nome = "Count001";
try {
CountManager cm =
(CountManager) Naming.lookup("CountFactory");
if (args.length > 0)
nome = args[0];
Count myCount = cm.getCount(nome);
int initValue = myCount.get();
System.out.print("De " + initValue + " para ");
long startTime = System.currentTimeMillis();
for (int i = 0 ; i < 1000 ; i++ )
myCount.increment();
long stopTime = System.currentTimeMillis();
System.out.println(myCount.get());
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f)
+ " msecs");
}
catch(Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}

Execuo com RMI


A execuo da aplicao cliente-servidor em RMI requer, alm da execuo da aplicao cliente
e da execuo da aplicao servidor, a execuo do servio de registro de RMI. Alm do princpio
bsico de execuo de aplicaes RMI, a arquitetura RMI oferece facilidades para operao com
cdigo disponibilizado de forma distribuda e ativao dinmica, alm de outros servios distribudos.

c 2001 FEEC/UNICAMP

105

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

O registro RMI (rmiregistry) executa isoladamente em uma mquina virtual Java. O servidor da aplicao, assim como a implementao do servio, esto executando em outra mquina
virtual Java; sua interao com o registro (ao invocar o mtodo bind()) se d atravs de uma referncia remota. Da mesma forma, cada aplicao cliente pode ser executada em sua prpria mquina
virtual Java; suas interaes com o registro (mtodo lookup()) e com a implementao do servio
(usando os correspondentes stub e skeleton) do-se tambm atravs de referncias remotas.
Portanto, para executar uma aplicao RMI preciso inicialmente disponibilizar o servio de
registro RMI. Para tanto, o aplicativo rmiregistry deve ser executado.
Com o rmiregistry disponvel, o servidor pode ser executado. Para tanto, essa mquina
virtual Java dever ser capaz de localizar e carregar as classes do servidor, da implementao do
servio e do skeleton.
Aps a execuo do comando que ativa a aplicao servidor, a mensagem Count Server ready.
dever surgir na tela, indicando que o servidor obteve sucesso na criao e registro do servio e
portanto est apto a responder s solicitaes de clientes.
Finalmente, com o servidor j habilitado para responder s solicitaes, o cdigo cliente pode ser
executado. Essa mquina virtual dever ser capaz de localizar e carregar as classes com a aplicao
cliente, a interface do servio e o stub para a implementao do servio. Seria possvel tambm ter
vrias ativaes simultneas de CountClient em diferentes mquinas virtuais Java.
No caso mais simples de execuo, as diversas mquinas virtuais Java estaro executando em
uma mesma mquina, compartilhando um CLASSPATH comum. No entanto, h mecanismos para
permitir o carregamento de classes em uma aplicao RMI envolvendo classes remotas.
Operao com objetos em mquinas remotas
Na descrio da operao de aplicaes distribudas usando RMI, assumiu-se que as aplicaes
clientes, servidor e de registro eram processos distintos; porm considerou-se que todas as classes
necessrias para a operao das aplicaes estavam localizadas em algum diretrio do CLASSPATH
local.
No caso de execuo em mquinas separadas, h duas formas de fazer a distribuio das classes
de modo que clientes e servidores possam executar corretamente. Na primeira forma, a estratgia
distribuir explicitamente as classes necessrias e inclu-las em diretrios onde elas possam ser
localizadas quando necessrio. No lado cliente, essas classes complementares seriam a interface
do servio e o stub para a implementao do servio. No lado servidor, seriam essas as classes de
implementao do servio e o correspondente skeleton.
A outra forma utilizar os mecanismos de carregamento dinmico de classes distribudas, em
alternativa ao class loader padro da mquina virtual Java. Por exemplo, se a execuo do cliente
se d atravs de um applet, o AppletClassLoader oferece as funcionalidades necessrias para
localizar uma classe que est localizada no mesmo diretrio de onde foi carregada a classe original.
Em RMI, h uma alternativa adicional de se utilizar o RMIClassLoader, que permite o carregamento de stubs e skeletons a partir de um URL (especificado atravs da propriedade java.rmi.
server.codebase). Essa propriedade deve ser estabelecida para a mquina virtual Java que ir
executar o servidor, como em
>java -Djava.rmi.server.codebase=http://mhost/mdir/ CountServer

c 2001 FEEC/UNICAMP

106

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

Deste modo, quando o servidor realizar o cadastro do servio no registry, esse codebase ser
embutido na referncia do objeto. Quando o cliente obtiver a referncia ao objeto remoto do registry
e seu class loader falhar em localizar a classe stub no CLASSPATH local, sua mquina virtual Java
far uma conexo HTTP com mhost para obter a classe correspondente assim como outras classes
eventualmente necessrias para execuo do servio no lado cliente.
De forma similar, caso o rmiregistry estivesse operando em outra mquina, distinta daquela
onde as aplicaes clientes e servidor estivessem executando, seria necessrio especificar no cdigo
das aplicaes a mquina que executa rmiregistry, seja atravs do mtodo getRegistry()
da classe LocateRegistry ou atravs da especificao de URL no protocolo RMI nos mtodos
da classe Naming.
Como para qualquer situao na qual a mquina virtual Java ir carregar classes localizadas de
forma distribuda, preciso adicionalmente estabelecer qual a poltica de segurana para operar com
cdigo proveniente das outras mquinas. Essa poltica ser enforada pelo gerenciador de segurana, que pode ser definido pela invocao do mtodo correspondente antes de qualquer invocao a
mtodos de RMI:
System.setSecurityManager(new RMISecurityManager());
O uso dessas facilidades pode ser apreciado nos exemplos modificados para o cdigo do servidor
e cliente da aplicao do contador distribudo. No caso do servidor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.SocketPermission;
public class CountServer {
public static void main(String[] args) {
// Create and install the security manager
System.setSecurityManager(new RMISecurityManager());
catch (Exception e) {
e.printStackTrace();
}
try {
String serviceName = "Count001";
// Create CountImpl
CountImpl myCount = new CountImpl();
Registry r = LocateRegistry.getRegistry(args[0]);
r.rebind(serviceName, myCount);
System.out.println("Count Server ready.");
}
catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
e.printStackTrace();
}
}
}
c 2001 FEEC/UNICAMP

107

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

No caso da aplicao cliente, o cdigo modificado apresentado abaixo:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

import java.rmi.*;
import java.rmi.registry.*;
public class CountClient {
public static void main(String args[]) {
// Create and install the security manager
System.setSecurityManager(new RMISecurityManager());
try {
Count myCount = (Count)Naming.lookup("rmi://" +
args[0] + "/Count001");
// Calculate Start time
long startTime = System.currentTimeMillis();
// Increment 1000 times
System.out.print("Incrementing... ");
for (int i = 0 ; i < 1000 ; i++ )
myCount.increment();
System.out.println(myCount.get());
// Calculate stop time; print out statistics
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f)
+ " msecs");
}
catch(Exception e) {
System.err.println("System Exception" + e);
}
System.exit(0);
}
}

A especificao da interface e a implementao do servio permanecem inalteradas para esses


exemplos.
Ativao dinmica
Na primeira especificao de RMI (JDK 1.1), era necessrio que um servio oferecido por um
objeto fosse explicitamente ativado em alguma mquina virtual Java e ento fosse cadastrado em um
servio de registro.
O problema com essa abordagem ocorre principalmente quando, por algum motivo no previsto,
o servio torna-se indisponvel no h como sinalizar o cliente ou o registro sobre esse fato. O
servio de ativao, oferecido a partir de JDK 1.2, permite contornar essa limitao. As principais
facilidades oferecidas pelo mecanismo de ativao remota incluem:

a possibilidade de criar automaticamente um objeto remoto devido a solicitaes de obteno


de referncias ao objeto;

c 2001 FEEC/UNICAMP

108

Programao orientada a objetos com Java




5.4. Programao com objetos distribudos

o suporte a grupos de ativao, permitindo a ativao de vrios objetos remotos executando em


uma mesma mquina virtual;
a possibilidade de reiniciar a execuo de objetos remotos que tenham encerrado sua execuo
em decorrncia de alguma falha do sistema.

Para tornar um objeto que implementa um servio como remotamente ativvel, preciso satisfazer trs requisitos. Primeiro, preciso implementar o servio como uma subclasse de Activatable, do pacote java.rmi.activation. Segundo, preciso criar construtores de ativao
na implementao do servio. Finalmente, preciso registrar o objeto e seu mtodo de ativao no
servio de ativao.
A classe Activatable oferece construtores com argumentos especficos para o registro (no
servio de ativao) e a ativao de objetos (incluindo o URL onde o bytecode para o objeto pode
ser localizado, um objeto da classe MarshalledObject representando os argumentos de inicializao do objeto e um flag booleano indicando se o objeto deve ser reiniciado com seu grupo) e
para a reativao de objetos (incluindo como argumento um objeto ActivationID, previamente
designado pelo servio de ativao). Esses construtores devero ser invocados nos construtores do
objeto que implementam o servio. Particularmente, o servio de ativao busca um construtor com
dois argumentos dos tipos ActivationID e MarshalledObject.
A classe ActivationDesc permite registrar a informao de ativao de um objeto sem criar
uma instncia deste objeto, usando para tanto o mtodo esttico register() da classe Activatable.
Antes de criar um servio ativvel, preciso criar ou especificar o grupo de ativao ao qual ele
pertence. Isto realizado atravs dos mtodos das classes ActivationGroup, ActivationGroupID e ActivationGroupDesc, todas do pacote java.rmi.activation. Um grupo
define um conjunto de objetos ativveis que devem compartilhar o mesmo espao de endereamento,
executando na mesma mquina virtual.
O servio de ativao implementado em uma mquina virtual com um objeto da classe Activator do pacote java.rmi.activation. A aplicao rimd, distribuda juntamente com o
pacote bsico do JDK 1.2, um daemon que implementa esse servio.
Coleta de lixo distribuda
O processo de remoo de objetos remotamente no-referenciados ocorre de maneira automtica.
Cada servidor com objetos exportados mantm uma lista de referncias remotas aos objetos que ele
oferece. Atravs de comunicao com o cliente, ele notificado quando a referncia liberada na
aplicao remota.
Cada referncia remota recebe tambm um perodo de validade; quando esse perodo expira,
a referncia eliminada e o cliente notificado. Esse mecanismo oferece uma alternativa para a
liberao de objetos que tenham sido referenciados por clientes que eventualmente tenham falhado,
ficando impedidos de sinalizar que a referncia havia sido liberada.
Embora no sejam utilizadas normalmente por programadores, as funcionalidades do distributed
garbage collector esto especificadas atravs das classes do pacote java.rmi.dgc.

c 2001 FEEC/UNICAMP

109

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

Callback
Nas aplicaes em uma arquitetura de objetos distribudos, nem sempre a comunicao no estilo
cliente-servidor suficiente para atender aos requisitos da aplicao. usual que o servidor RMI aja
algumas vezes como cliente, invertendo os papis com o cliente RMI original.
Considere o exemplo do applet cliente RMI. Nesse applet, no h como saber se outro cliente
do mesmo objeto remoto realizou alguma atualizao no valor do contador a no ser pressionando o
boto Get e verificando se houve mudana. Essa uma situao tpica em muitas aplicaes, sendo
clara a necessidade de realizar tais notificaes de forma automtica.
O mecanismo para atingir esse objetivo utilizar a estratgia de callback. Esta tcnica tipicamente utilizada quando a aplicao cliente requer um retorno do servidor mas no quer permanecer
bloqueado aguardando a resposta. Atravs dessa tcnica, o servidor obtm uma referncia para o
cliente de forma que pode invocar remotamente um mtodo do objeto cliente. Assim, quando a execuo do servio solicitado concluda, o servidor pode notificar o cliente atravs da invocao do
mtodo disponibilizado pelo cliente para uso remoto.
Basicamente, assim como para o objeto de servio RMI, deve-se oferecer uma interface remota
para o cliente a fim de permitir que o servidor tenha acesso ao servio de atualizao do cliente.
Esse exemplo ilustra tal situao, com um mtodo que ser invocado pelo servidor quando seu valor
for alterado, quando passar um valor inteiro para o cliente com a valor atualizado:
1
2
3
4

import java.rmi.*;
public interface CountClientInterface extends Remote {
void update(int val) throws RemoteException;
}
Observe que neste exemplo a interface remota do servio tambm foi atualizada de forma a
permitir o cadastro dos clientes interessados na atualizao:

1
2
3
4
5
6
7
8
9

import java.rmi.*;
public interface Count extends Remote {
void set(int val) throws RemoteException;
void reset() throws RemoteException;
int get() throws RemoteException;
int increment() throws RemoteException;
void addClient(CountClientInterface c) throws RemoteException;
void remClient(CountClientInterface c) throws RemoteException;
}
Com callback, ambos cliente e servidor devero implementar o servio remoto especificado.
Considere o cdigo para o servidor:

1
2
3
4
5
6

import java.util.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class CountImpl extends UnicastRemoteObject
implements Count {
private int sum;
c 2001 FEEC/UNICAMP

110

Programao orientada a objetos com Java

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

5.4. Programao com objetos distribudos

// Lista de clientes registrados


private Vector clientes = new Vector();
public CountImpl() throws RemoteException {
}
public void set(int val) throws RemoteException {
sum = val;
}
public void reset() throws RemoteException {
sum = 0;
}
public int get() throws RemoteException {
return sum;
}
public int increment() throws RemoteException {
sum++;
if (sum%100 == 0)
update();
return sum;
}
public void addClient(CountClientInterface client)
throws RemoteException {
clientes.add(client);
}
public void remClient(CountClientInterface client)
throws RemoteException {
clientes.remove(client);
}
public void update() throws RemoteException {
CountClientInterface cci;
for (int i=0; i<clientes.size(); ++i) {
cci = (CountClientInterface) clientes.elementAt(i);
cci.update(sum);
}
}
}
Similarmente, para o cdigo do cliente:

1
2
3
4
5
6
7

import java.rmi.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.rmi.server.*;
public class AppletClient extends Applet
implements ActionListener, CountClientInterface {

c 2001 FEEC/UNICAMP

111

Programao orientada a objetos com Java

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

5.4. Programao com objetos distribudos

Count remCount;
TextField tfCnt;
Button bStart;
String bslabel = "Start";
public void init() {
try {
setLayout(new GridLayout(3,1));
add(new Label("Count:"));
tfCnt = new TextField(7);
tfCnt.setEditable(false);
add(tfCnt);
bStart = new Button(bslabel);
bStart.addActionListener(this);
add(bStart);
UnicastRemoteObject.exportObject(this);
showStatus("Binding remote object");
remCount = (Count) Naming.lookup("Count001");
showStatus("Registering with remote object");
remCount.addClient(this);
tfCnt.setText(Integer.toString(remCount.get()));
}
catch (Exception e) {
e.printStackTrace();
}
}
public void paint() {
try {
tfCnt.setText(Integer.toString(remCount.get()));
}
catch (Exception e) {
e.printStackTrace();
}
}
public void actionPerformed (ActionEvent ev) {
try {
showStatus("Incrementing...");
for (int i = 0 ; i < 1000 ; i++ )
remCount.increment();
showStatus("Done");
}
catch (Exception e) {
e.printStackTrace();
}
}

c 2001 FEEC/UNICAMP

112

Programao orientada a objetos com Java

52
53
54
55
56

5.4. Programao com objetos distribudos

public void update(int val) throws RemoteException {


showStatus("Update");
tfCnt.setText(Integer.toString(val));
}
}

Como anteriormente, devem ser criados os stubs e skeletons para ambos os servios. O cdigo
do servidor no sofre alterao em relao ao exemplo anterior, assim como a forma de execuo da
aplicao.

5.4.3

Java IDL

A API Java IDL, presente na plataforma Java desde a verso 1.2, permite a integrao entre
objetos Java e outros objetos, eventualmente desenvolvidos em outras linguagens de programao,
atravs da arquitetura CORBA. Os principais pacotes que compem essa API so org.omg.CORBA
e org.omg.CosNaming.
A partir da verso 1.3 da plataforma Java, possvel gerar interfaces IDL para classes Java usando o compilador rmic com a opo -idl". Outra opo, -iiop", indica que o protocolo de
comunicao de CORBA, IIOP, ser utilizado em stubs e ties (correspondentes aos skeletons) de
RMI.
Arquitetura CORBA
CORBA (Common Object Request Broker Architecture) um padro definido pelo consrcio
OMG Object Management Group) que define uma arquitetura de objetos, com uma linguagem para
descrio de interfaces com mapeamentos padronizados para diversas linguagens e um conjunto de
servios bsicos.
Como o padro CORBA visa atender a diversas linguagens de programao, sua especificao
ampla e relativamente complexa. De forma extremamente simplificada, os componentes bsicos
dessa arquitetura so:




a linguagem de descrio de interfaces;

o intermedirio para repassar requisies a objetos remotos;

o servio para localizar objetos remotos; e


o protocolo de comunicao.

IDL a Interface Description Language, uma linguagem que permite especificar interfaces de
forma independente da linguagem de programao na qual a especificao implementada. CORBA
determina uma srie de mapeamentos padronizados entre IDL e outras linguagens, tais como C, C++,
COBOL e Java.
ORB o Object Request Broker, o ncleo da arquitetura CORBA. um programa que deve
estar executando em cada mquina envolvida em uma aplicao CORBA, sendo o responsvel pela
conexo entre clientes e servios atravs dos correspondentes stubs e skeletons.

c 2001 FEEC/UNICAMP

113

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

O Servio de Nomes de CORBA define uma estrutura para associar nomes a objetos remotos
definidos na arquitetura. A estrutura definida uma hierarquia (ou rvore), onde cada ramo define
um contexto distinto e cujas folhas so os nomes dos servios disponibilizados. Assim, a referncia
completa para o nome de um servio dada pelo contexto (os nomes dos ns intermedirios) e pelo
nome do servio.
O protocolo de comunicao de CORBA especifica o padro para que as requisies de objetos
transmitidas entre ORBs, independentemente de como ou em qual linguagem esses ORBs foram
implementados, possam ser reconhecidas. O protocolo de comunicao CORBA mais comum o
IIOP, o Internet Inter-ORB Protocol, em funo da disseminao da Internet, mas outros protocolos
podem ser obtidos para outras plataformas.
CORBA e Java
Uma vez definida ou obtida a interface IDL para um servio, as classes auxiliares para acessar o
objeto remoto que implementa o servio so obtidas pela compilao da interface, usando o aplicativo
idlj (ou idltojava ou ainda idl2java em verses anteriores Java 1.3). Alm de classes para
stubs e skeletons, so geradas classes auxiliares (helpers e holders) para permitir a comunicao entre
objetos Java e dados estabelecidos em outras linguagens.
Na plataforma Java h uma implementao para o servio de nomes de CORBA, oferecida pelo
aplicativo tnameserv. Esse servio est mapeado por default para a porta 900, podendo esta ser
modificada pela opo -ORBInitialPort".
A interao entre um ORB e um programa Java d-se atravs de mtodos da classe ORB. Para
inicializar a referncia ao ORB, utiliza-se o mtodo esttico init() dessa classe. Para obter uma
referncia para o servio de nomes utiliza-se o mtodo resolve_initial_references(),
tendo a NameService como argumento.
O exemplo a seguir a implementao usando CORBA do clssico programa Hello, world.
composto por trs arquivos: a interface IDL, o cliente e o servidor.
A Interface IDL descreve um servio com um nico mtodo, sendo aqui definida usando as
construes da linguagem IDL:
1
2
3
4
5

module HelloApp {
interface Hello {
string sayHello();
}
}
Usando-se o aplicativo idlj, gera-se a interface Java correspondente, com a traduo das construes IDL para as primitivas Java segundo o padro estabelecido em CORBA, alm de outros
arquivos auxiliares (stub, skeleton, helper, holder), no apresentados aqui:

1
2
3
4
5

package HelloApp;
public interface Hello
extends org.omg.CORBA.Object {
String sayHello();
}

c 2001 FEEC/UNICAMP

114

Programao orientada a objetos com Java

5.4. Programao com objetos distribudos

O cdigo cliente ativa o ORB, obtm uma referncia para o servio de nomes e, a partir deste
servio, obtm uma referncia remota para o objeto com o servio Hello. Obtida a referncia, o
mtodo invocado normalmente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class HelloClient {
public static void main (String args[]) {
try {
ORB meuOrb = ORB.init(args,null);
org.omg.CORBA.Object objRef =
meuOrb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("Hello","");
NameComponent path[] = {nc};
Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
String hi = helloRef.sayHello();
System.out.println(hi);
}
catch(Exception e) {
System.out.println(e);
e.printStackTrace(System.out);
}
}
}

Nesse exemplo, combina-se a implementao do servio e o correspondente servidor. A classe


HelloServer um servidor que ativa o ORB, cria o objeto que implementa o servio, obtm uma
referncia para o servio de nomes e registra o objeto neste diretrio associado ao nome Hello. A
classe HelloServant uma implementao do servio especificado; observe que essa classe
uma extenso de _HelloImplBase, o skeleton definido pelo aplicativo idlj:
1
2
3
4
5
6
7
8
9
10
11
12
13

import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class HelloServer {
public static void main(string args[]) {
try {
// Create the ORB
ORB orb = ORB.init(args,null);
// Instantiate the servant object
HelloServant helloRef = new HelloServant();
// Connect servant to the ORB
orb.connect(helloRef);
c 2001 FEEC/UNICAMP

115

Programao orientada a objetos com Java

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

5.4. Programao com objetos distribudos

//Registering the servant


org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("Hello","");
NameComponent path[] = {nc};
ncRef.rebind(path, helloRef);
// Wait for invocation
java.lang.Object sync = new java.Lang.Object();
synchronized(sync) {
sync.wait();
}
}
catch(Exception e) {
System.out.println(e);
e.printStackTrace(System.out);
}
}
}
class HelloServant extends _HelloImplBase {
public String sayHello() {
return "\nHelloWorld!\n";
}
}

c 2001 FEEC/UNICAMP

116

Apndice A

Palavras chaves de Java


As palavras a seguir so de uso reservado em Java e no podem ser utilizadas como nomes de
identificadores:
abstract
boolean
break
byte
case
catch
char
class
const
continue
default
do

double
else
extends
final
finally
float
for
goto
if
implements
import
instanceof

int
interface
long
native
new
null
package
private
protected
public
return
short

117

static
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while

Você também pode gostar