Você está na página 1de 46

Captulo

1
Contedo
1.1

Conceitos Bsicos de Programao Java

Iniciando: classes, tipos e objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 1.1.2 1.1.3 Tipos bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tipos enumerados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

24 26 28 34 34 39 39 42 44 44 46 48 49 51 52 53 55 58 59 60 60 61 64 66

1.2 1.3

Mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Expresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 1.3.3 Literais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conversores e autoboxing/unboxing em expresses . . . . . . . . . . . . . . . . . Os comandos if e switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Laos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Expresses explcitas de controle de fluxo . . . . . . . . . . . . . . . . . . . . . . . . . Declarando arranjos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arranjos so objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4

Controle de fluxo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 1.4.2 1.4.3

1.5

Arranjos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.1 1.5.2

1.6 1.7 1.8 1.9

Entrada e sada simples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Um programa de exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Classes aninhadas e pacotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Escrevendo um programa em Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.1 1.9.2 1.9.3 1.9.4 Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pseudocdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Codificao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Teste e depurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.10

Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

24

Estruturas de Dados e Algoritmos em Java

1.1

Iniciando: classes, tipos e objetos


Construir estruturas de dados e algoritmos requer a comunicao de instrues detalhadas para um computador. Uma excelente maneira de fazer isso usar uma linguagem de programao de alto nvel tal como Java. Este captulo apresenta uma viso geral da linguagem Java assumindo que o leitor esteja familiarizado com alguma linguagem de programao de alto nvel. Este livro, entretanto, no prov uma descrio completa da linguagem Java. Existem aspectos importantes da linguagem que no so relevantes para o projeto de estruturas de dados e que no so includos aqui, tais como threads e sockets. O leitor que desejar aprender mais sobre Java deve observar as notas do final deste captulo. Iniciamos com um programa que imprime Hello Universe! na tela, que mostrado e dissecado na Figura 1.1.
todo cdigo Java chaves indicam deve pertencer o incio do corpo a uma classe da classe isto diz que todo mundo pode este o nome executar este programa da classe este mtodo no retorna nada o nome deste mtodo os parmetros passados para este mtodo (neste caso os argumentos da linha de comando passados como um arranjo de strings) chaves indicam o incio do corpo do mtodo ponto-e-vrgula indica o fim deste comando

todo mundo pode executar este programa

public class Universe {

public static void main (String[ ] args) { System.out.println ("Hello Universe!") ;

este mtodo pertence a classe, no ao objeto (mais sobre isso, adiante) chaves para fechar o corpo da classe

} }

o nome do mtodo que se deseja chamar (neste caso o mtodo para imprimir strings na tela)

o parmetro passado para o mtodo (neste caso o string que ser impresso)

chaves para fechar o corpo do mtodo

Figura 1.1 O programa Hello Universe! Os principais atores em um programa Java so os objetos. Os objetos armazenam dados e fornecem os mtodos para acessar e modificar esses dados. Todo objeto instncia de uma classe que define o tipo do objeto, bem como os tipos de operaes que executa. Os membros crticos de uma classe Java so os seguintes (classes tambm podem conter definies de classes aninhadas, mas essa uma discusso para mais tarde): Dados de objetos Java so armazenados em variveis de instncia (tambm chamadas de campos). Por essa razo, se um objeto de uma classe deve armazenar dados, ento sua classe deve especificar variveis de instncia para esse fim. As variveis de instncia podem ser de tipos bsicos (tais como inteiros, nmeros de ponto flutuante ou booleanos) ou podem se referir a objetos de outras classes. As operaes que podem atuar sobre os dados e que expressam as mensagens s quais os objetos respondem so chamadas de mtodos, e estes consistem de construtores, subprogramas e funes. Eles definem o comportamento dos objetos daquela classe.

Como as classes so declaradas


Resumindo, um objeto uma combinao especfica de dados e dos mtodos capazes de processar e comunicar esses dados. As classes definem os tipos dos objetos; por essa razo, objetos so tambm chamados de instncias da classe que os define, e usam o nome da classe como seu tipo. Um exemplo de definio de uma classe Java apresentado no Trecho de cdigo 1.1.

Conceitos Bsicos de Programao Java


public class Counter { protected int count; // uma simples varivel de instncia inteira /** O construtor default para um objeto Counter */ Counter( ) { count = 0; } /** Um mtodo de acesso para recuperar o valor corrente do contador */ public int getCount( ) { return count; } /** Um mtodo modicador para incrementar o contador */ public void incrementCount( ) { count ;} /** Um mtodo modicador para decrementar o contador */ public void decrementCount( ) {count ;} }

25

Trecho de cdigo 1.1 A classe Counter para um contador simples que pode ser acessado, incrementado e decrementado. Neste exemplo, observa-se que a definio da classe est delimitada por chaves, isto , comea por um { e termina com um }. Em Java, qualquer conjunto de comandos entre chaves { e } define um bloco de programa. Assim como a classe Universe, a classe Counter pblica, o que significa que qualquer outra classe pode criar e usar um objeto Counter. O Counter tem uma varivel de instncia um inteiro chamado count. Esta varivel inicializada com zero no mtodo construtor, Counter, que chamado quando se deseja criar um novo objeto Counter (este mtodo sempre tem o mesmo nome que a classe a qual pertence). Esta classe tambm tem um mtodo de acesso, getCount, que retorna o valor corrente do contador. Finalmente, esta classe tem dois mtodos de atualizao o mtodo incrementCount, que incrementa o contador, e o mtodo decrementCount, que decrementa o contador. Na verdade, esta uma classe extremamente aborrecida, mas pelo menos mostra a sintaxe e a estrutura de uma classe Java. Mostra tambm que uma classe Java no precisa ter um mtodo chamado main (mas tal classe no consegue fazer nada sozinha). O nome da classe, mtodo ou varivel em Java chamado de identificador, e pode ser qualquer string de caracteres desde que inicie por uma letra e seja composto por letras, nmeros e caracteres sublinhados (onde letra e nmero podem ser de qualquer lngua escrita definida no conjunto de caracteres Unicode). Listam-se as excees a esta regra geral para identificadores Java na Tabela 1.1.
Palavras reservadas
abstract boolean break byte case catch char class const continue default do double else extends false final finally float for goto if implements import instanceof int interface long native new null package private protected public return short static super switch synchronized this throw throws transient true try void volatile while

Tabela 1.1 Lista de palavras reservadas Java. Estas palavras no podem ser usadas como nomes de variveis ou de mtodos em Java.

26

Estruturas de Dados e Algoritmos em Java

Modificadores de classes
Os modificadores de classes so palavras reservadas opcionais que precedem a palavra reservada class. At agora, foram vistos exemplos que usavam a palavra reservada public. Em geral, os diferentes modificadores de classes e seu significado so os que seguem: O modificador de classe abstract descreve uma classe que possui mtodos abstratos. Mtodos abstratos so declarados com a palavra reservada abstract e so vazios (isto , no possuem um bloco de comandos definindo o cdigo do mtodo). Se uma classe tem apenas mtodos abstratos e nenhuma varivel de instncia, mais adequado consider-la uma interface (ver Seo 2.4), de forma que uma classe abstract normalmente uma mistura de mtodos abstratos e mtodos verdadeiros. (Discutem-se classes abstratas e seus usos na Seo 2.4). O modificador de classe final descreve uma classe que no pode ter subclasses. (Discutese esse conceito no prximo captulo). O modificador de classe public descreve uma classe que pode ser instanciada ou estendida por qualquer coisa definida no mesmo pacote ou por qualquer coisa que importe a classe. (Isso melhor detalhado na Seo 1.8.) Todas as classes pblicas so declaradas em arquivo prprio exclusivo nomeado classname.java, onde classname o nome da classe. Se o modificador de classe public no usado, ento a classe considerada amigvel. Isso significa que pode ser usada e instanciada por qualquer classe do mesmo pacote. Esse o modificador de classe default.

1.1.1

Tipos bsicos
Os tipos dos objetos so determinados pela classe de origem. Em nome da eficincia e da simplicidade, Java ainda oferece os seguintes tipos bsicos (tambm chamados de tipos primitivos) que no so objetos:
boolean char byte short int long loat double

valor booleano: true ou false caracter Unicode de 16 bits inteiro com sinal em complemento de dois de 8 bits inteiro com sinal em complemento de dois de 16 bits inteiro com sinal em complemento de dois de 32 bits inteiro com sinal em complemento de dois de 64 bits nmero de ponto flutuante de 32 bits (IEEE 754-1985) nmero de ponto flutuante de 64 bits (IEEE 754-1985)

Uma varivel declarada como tendo um desses tipos simplesmente armazena um valor deste tipo, em vez de uma referncia para um objeto. Constantes inteiras, tais como 14 ou 195, so do tipo int, a menos que seguidas de imediato por um Lou l, sendo, neste caso, do tipo long. Constantes de ponto flutuante, como 3.1415 ou 2.158e5, so do tipo double, a menos que seguidas de imediato por um F ou um f, sendo, neste caso, do tipo float. O Trecho de cdigo 1.2 apresenta uma classe simples que define algumas variveis locais de tipos bsicos no mtodo main.
public class Base { public static void main (String[ ] args) { boolean ag true; char ch A; byte b 12; short s 24; int i 257;

Conceitos Bsicos de Programao Java


long l 890L; // Observar o uso do L aqui float f = 3.1415F; // Observar o uso do F aqui double d = 2.1828; System.out.println ("flag = " + ag); // o indica concatenao de strings System.out.println ("ch = " + ch); System.out.println ("b = " + b); System.out.println ("s = " + s); System.out.println ("i = " + i); System.out.println ("l = " + l); System.out.println ("f = " + f ); System.out.println ("d = " + d); } }

27

Trecho de cdigo 1.2

A classe Base mostrando o uso dos tipos bsicos.

Comentrios
Observar o uso de comentrios neste e nos outros exemplos. Os comentrios so anotaes para uso de humanos, e no so processadas pelo compilador Java. Java permite dois tipos de comentrios comentrios de bloco e comentrios de linha usados para definir o texto a ser ignorado pelo compilador. Em Java, usa-se um /* para comear um bloco de comentrio e um */ para fech-lo. Deve-se destacar os comentrios iniciados por /**, pois tais comentrios tem um formato especial que permite que um programa chamado Javadoc os leia e automaticamente gere documentao para programas Java. A sintaxe e interpretao dos comentrios Javadoc ser discutida na Seo 1.9.3 Alm de comentrios de bloco, Java usa o // para comear comentrios de linha e ignorar tudo mais naquela linha. Por exemplo:
/*

* Este um bloco de comentrio */


// Este um comentrio de linha

Sada da classe Base


A sada resultante da execuo da classe Base (mtodo main) mostrada na Figura 1.2.
ag true ch A b 12 s 24 i 257 l 890 f 3.1415 d 2.1828

Figura 1.2 Sada da classe Base. Mesmo no se referindo a objetos, variveis dos tipos bsicos so teis no contexto de objetos, na medida em que so usadas para definir variveis de instncias (ou campos) dentro de um objeto. Por exemplo, a classe Counter (Trecho de cdigo 1.1) possui uma nica varivel de instncia do tipo int. Uma outra caracterstica adicional de Java o fato de que variveis de instncia

28

Estruturas de Dados e Algoritmos em Java


sempre recebem um valor inicial quando o objeto que as contm criado (seja zero, falso ou um caracter nulo, dependendo do tipo).

1.1.2

Objetos
Em Java, um objeto novo criado a partir de uma classe usando-se o operador new. O operador new cria um novo objeto a partir de uma classe especificada e retorna uma referncia para este objeto. Para criar um objeto de um tipo especfico, deve-se seguir o uso do operador new por uma chamada a um construtor daquele tipo de objeto. Pode-se usar qualquer construtor que faa parte da definio da classe, incluindo o construtor default (que no recebe argumentos entre os parnteses). Na Figura 1.3, apresentam-se vrios exemplos de uso do operador new que criam novos objetos e atribuem uma referncia para os mesmos a uma varivel.
o nome desta classe sintaxe padro para declarar um mtodo declara a varivel c como sendo do tipo Counter; isto , c pode se referir a qualquer objeto Counter cria um novo objeto Counter e retorna uma referncia para o mesmo

public class Example {

public static void main (String[ ] args) {


declara a varivel d como sendo o tipo Counter

Counter c; Counter d = new Counter() ; c = new Counter() ;

} }

atribui a referncia ao novo objeto para a varivel d cria um novo objeto Counter e retorna d=c; uma referncia para o mesmo atribui a referncia ao novo objeto a varivel c atribui a referncia para o mesmo objeto que c (o objeto que d referenciava no tem mais nenhuma varivel referenciando-o)

Figura 1.3 Exemplos de uso do operador new. A chamada do operador new sobre um tipo de classe faz com que ocorram trs eventos: Um novo objeto dinamicamente alocado na memria, e todas as variveis de instncia so inicializadas com seus valores padro. Os valores padro so null para variveis objeto e 0 para todos os tipos base, exceto as variveis boolean (que so false por default). O construtor para o novo objeto chamado com os parmetros especificados. O construtor atribui valores significativos para as variveis de instncia e executa as computaes adicionais que devam ser feitas para criar este objeto. Depois do construtor retornar, o operador new retorna uma referncia (isto , um endereo de memria) para o novo objeto recm criado. Se a expresso est na forma de uma atribuio, ento este endereo armazenado na varivel objeto, e ento a varivel objeto passa a referir o objeto recm criado.

Objetos numricos
s vezes, quer-se armazenar nmeros como objetos, mas os tipos bsicos no so objetos, como j se observou. Para contornar esse problema, Java define uma classe especial para cada tipo b-

Conceitos Bsicos de Programao Java

29

sico numrico. Essas classes so chamadas de classes numricas. Na Tabela 1.2, esto os tipos bsicos numricos e as classes numricas correspondentes, juntamente com exemplos de como se criam e se acessam os objetos numricos. Desde o Java 5.0, a operao de criao executada automaticamente sempre que se passa um nmero bsico para um mtodo que esteja esperando o objeto correspondente. Da mesma forma, o mtodo de acesso correspondente executado automaticamente sempre que se deseja atribuir o valor do objeto Nmero correspondente a um tipo numrico bsico.
Tipo base
byte short int long float double

Nome da classe
Byte Short Integer Long Float Double

Exemplo de criao
n = new Byte((byte)34) n = new Short((short)100) n = new Integer(1045) n = new Long(10849L) n = new Float(3.934F) n = new Double(3.934)

Exemplo de acesso
n.byteValue() n.shortValue() n.intValue() n.longValue() n.floatValue() n.doubleValue()

Tabela 1.2 Classes numricas de Java. Para cada classe fornecido o tipo bsico correspondente e expresses exemplificadoras de criao e acesso a esses objetos. Em cada linha, se admite que a varivel n declarada com o nome de classe correspondente.

Objetos string
Uma string uma seqncia de caracteres que provm de algum alfabeto (conjunto de todos os caracteres possveis). Cada caracter c que compe uma string s pode ser referenciado por seu ndice na string, a qual igual ao nmero de caracteres que vem antes de c em s (desta forma, o primeiro caractere tem ndice 0). Em Java, o alfabeto usado para definir strings o conjunto internacional de caracteres Unicode, um padro de codificao de caracteres de 16 bits que cobre as lnguas escritas mais usadas. Outras linguagens de programao tendem a usar o conjunto de caracteres ASCII, que menor (corresponde a um subconjunto do alfabeto Unicode baseado em um padro de codificao de 7 bits). Alm disso, Java define uma classe especial embutida de objetos chamados objetos String. Por exemplo, P pode ser
"hogs and dogs"

que tem comprimento 13 e pode ter vindo da pgina Web de algum. Neste caso, o caractere de ndice 2 g e o caractere de ndice 5 a. Por outro lado, P poderia ser a string "CGTAATAGTTAATCCG", que tem comprimento 16 e pode ser proveniente de uma aplicao cientfica de seqenciamento de DNA, onde o alfabeto {G,C,A,T}.

Concatenao
O processamento de strings implica em lidar com strings. A operao bsica para combinar strings chama-se concatenao, a qual toma uma string P e uma string Q e as combina em uma nova string denotada P Q, que consiste de todos os caracteres de P seguidos por todos os caracteres de Q. Em Java, o operador age exatamente desta maneira quando aplicado sobre duas strings. Sendo assim, em Java vlido (e muito til) escrever uma declarao de atribuio do tipo:
String s "kilo" + "meters";

Essa declarao define uma varivel s que referencia objetos da classe String e lhe atribui a string "kilometers". (Mais adiante, neste captulo, sero discutidos mais detalhadamente comandos de atribuio e expresses como a apresentada). Pressupe-se ainda que todo objeto

30

Estruturas de Dados e Algoritmos em Java


Java tem um mtodo predefinido chamado toString( ) que retorna a string associada ao objeto. Esta descrio da classe String deve ser suficiente para a maioria dos usos. Analisaremos a classe String e sua parente, a classe StringBuffer, na Seo 12.1.

Referncias para objetos


Como mencionado acima, a criao de um objeto novo envolve o uso do operador new para alocar espao em memria para o objeto e usar o construtor do objeto para inicializar esse espao. A localizao ou endereo deste espao normalmente atribuda para uma varivel referncia. Conseqentemente, uma varivel referncia pode ser entendida como sendo um ponteiro para um objeto. Isso como se a varivel fosse o suporte de um controle remoto que pudesse ser usado para controlar o objeto recm-criado (o dispositivo). Ou seja, a varivel tem uma maneira de apontar para o objeto e solicitar que o mesmo faa coisas ou acessar seus dados. Este conceito pode ser visto na Figura 1.4.
o objeto

a referncia

a varivel referncia

Figura 1.4 Demonstrando o relacionamento entre objetos e variveis referencia. Quando se atribui uma referncia para um objeto (isto , um endereo de memria) para uma varivel referncia, como se fosse armazenado um controle remoto do objeto naquela varivel.

O operador ponto
Toda a varivel referncia para objeto deve referir algum objeto, a menos que seja null, caso em que no aponta para nada. Seguindo com a analogia do controle remoto, uma referncia null um suporte de controle remoto vazio. Inicialmente, a menos que se faa a varivel referncia apontar para alguma coisa atravs de uma atribuio, ela null. Pode haver, na verdade, vrias referncias para um mesmo objeto, e cada referncia para um objeto especfico pode ser usada para chamar mtodos daquele objeto. Esta situao corresponde a existirem vrios controles remotos capazes de atuar sobre o mesmo dispositivo. Qualquer um dos controles pode ser usado para fazer alteraes no dispositivo (como alterar o canal da televiso). Observe que se um controle remoto usado para alterar o dispositivo, ento o (nico) objeto apontado por todos os controles se altera. Da mesma forma, se uma varivel referncia for usada para alterar o estado do objeto, ento seu estado muda para todas as suas referncias. Este comportamento vem do fato de que so muitas referncias, mas todas apontando para o mesmo objeto. Um dos principais usos de uma varivel referncia acessar os membros da classe a qual pertence o objeto, a instncia da classe. Ou seja, uma varivel referncia til para acessar os mtodos e as variveis de instncia associadas com um objeto. Este acesso feito atravs do operador ponto (.). Chama-se um mtodo associado com um objeto usando o nome da varivel referncia seguido do operador ponto, e ento o nome do mtodo e seus parmetros.

Conceitos Bsicos de Programao Java

31

Isso ativa o mtodo com o nome especificado associado ao objeto referenciado pela varivel referncia. Opcionalmente, podem ser passados vrios parmetros. Se existirem vrios mtodos com o mesmo nome definido para este objeto, ento a mquina de execuo do Java ir usar aquele cujo nmero de parmetros e tipos melhor combinem. O nome de um mtodo combinado com a quantidade e o tipo de seus parmetros chama-se de assinatura do mtodo, uma vez que todas essas partes so usadas para determinar o mtodo correto para executar uma certa chamada de mtodo. Considerem-se os seguintes exemplos:
oven.cookDinner( );

oven.cookDinner(food); oven.cookDinner(food, seasoning); Cada uma dessas chamadas se refere, na verdade, a mtodos diferentes, definidos com o mesmo nome na classe a qual pertencem. Observa-se, entretanto, que a assinatura de um mtodo em Java no inclui o tipo de retorno do mtodo, de maneira que Java no permite que dois mtodos com a mesma assinatura retornem tipos diferentes.

Variveis de instncia
Classes Java podem definir variveis de instncia, tambm chamadas de campos. Essas variveis representam os dados associados com os objetos de uma classe. As variveis de instncia devem ter um tipo, que pode tanto ser um tipo bsico (como int, float, double) ou um tipo referncia (como na analogia do controle remoto), isto , uma classe, como String, uma interface (ver Seo 2.4) ou um arranjo (ver Seo 1.5). Uma instncia de varivel de um tipo bsico armazena um valor do tipo bsico, enquanto que variveis de instncia, declaradas usando-se um nome de classe, armazenam uma referncia para um objeto daquela classe. Continuando com a analogia entre variveis referncia e controles remotos, variveis de instncia so como parmetros do dispositivo que podem tanto ser lidos, como alterados usando-se o controle remoto (tais como os controles de volume e canal do controle remoto de uma televiso). Dada uma varivel referncia v, que aponta para um objeto o, pode-se acessar qualquer uma das variveis de instncia de o que as regras de acesso permitirem. Por exemplo, variveis de instncia pblicas podem ser acessadas por qualquer pessoa. Usando o operador ponto, pode-se obter o valor de qualquer varivel de instncia, i, usando-se v.i em uma expresso aritmtica. Da mesma forma pode-se alterar o valor de qualquer varivel de instncia i, escrevendo v.i no lado esquerdo do operador de atribuio ( ). (Ver Figura 1.5.) Por exemplo, se gnome se refere a um objeto Gnome que tem as variveis de instncia pblicas name e age, ento os seguintes comandos so possveis:
gnome.name ProfessorSmythe;

gnome.age = 132; Entretanto, uma referncia para objeto no tem de ser apenas uma varivel referncia. Pode ser qualquer expresso que retorna uma referncia para objeto.

Modificadores de variveis
Em alguns casos, o acesso direto a uma varivel de instncia de um objeto pode no estar habilitado. Por exemplo, uma varivel de instncia declarada como privada em alguma classe s pode ser acessada pelos mtodos definidos dentro da classe. Tais variveis de instncia so parecidas com parmetros de dispositivo que no podem ser acessados diretamente pelo controle remoto. Por exemplo, alguns dispositivos tem parmetros internos que s podem ser lidos ou alterados por tcnicos da fbrica (e o usurio no est autorizado a alter-los sem violar a garantia do dispositivo). Quando se declara uma varivel de instncia, pode-se, opcionalmente, definir um modificador de varivel, seguido pelo tipo e identificador daquela varivel. Alm disso, tambm opcio-

32

Estruturas de Dados e Algoritmos em Java


o objeto o

a referncia
12 .3

ob ter r era alt 3 1 4

a varivel referncia v
7

2 5

Figura 1.5 Demonstrando a maneira pela qual uma referencia para objeto pode ser usada para obter ou alterar variveis de instncia em um objeto (assumindo que se tem acesso a estas variveis). nal atribuir um valor inicial para a varivel (usando o operador de atribuio =). As regras para o nome da varivel so as mesmas de qualquer outro identificador Java. O tipo da varivel pode ser tanto um tipo bsico, indicando que a varivel armazena valores daquele tipo, ou um nome de classe, indicando que a varivel uma referncia para um objeto desta classe. Por fim, o valor inicial opcional que se pode atribuir a uma varivel de instncia deve combinar com o tipo da varivel. Como exemplo, definiu-se a classe Gnome*, que contm vrias definies de variveis de instncia, apresentada no Trecho de cdigo 1.3. O escopo (ou visibilidade) de uma varivel de instncia pode ser controlado atravs do uso dos seguintes modificadores de variveis: public: qualquer um pode acessar variveis de instncia pblicas. protected: apenas mtodos do mesmo pacote ou subclasse podem acessar variveis de instncia protegidas. private: apenas mtodos da mesma classe (excluindo mtodos de uma subclasse) podem acessar variveis de instncias privadas. Se nenhum dos modificadores acima for usado, ento a varivel de instncia considerada amigvel. Variveis de instncia amigveis podem ser acessadas por qualquer classe no mesmo pacote. Os pacotes so discutidos detalhadamente na Seo 1.8. Alm dos modificadores de escopo de varivel, existem tambm os seguintes modificadores de uso: static: a palavra reservada static usada para declarar uma varivel que associada com a classe, no com instncias individuais daquela classe. Variveis static so usadas para armazenar informaes globais sobre uma classe (por exemplo, uma varivel static pode ser usada para armazenar a quantidade total de objetos Gnome criados). Variveis static existem mesmo se nenhuma instncia de sua classe for criada. final: uma varivel de instncia final um tipo de varivel para o qual se deve atribuir um valor inicial, e para a qual, a partir de ento, no possvel atribuir um novo valor. Se for

8 9

* N. de T. Gnomo.

Conceitos Bsicos de Programao Java

33

de um tipo bsico, ento uma constante (como a constante MAX_HEIGHT na classe Gnome). Se uma varivel objeto final, ento ir sempre se referir ao mesmo objeto (mesmo se o objeto alterar seu estado interno).
public class Gnome { // Variveis de instncia: public String name; public int age; public Gnome gnomeBuddy; private boolean magical = false; protected double height = 2.6; public static final int MAX HEIGHT = 3; // altura mxima // Construtores: Gnome(String nm, int ag, Gnome bud, double hgt) { // totalmente parametrizado name = nm; age = ag; gnomeBuddy = bud; height = hgt; } Gnome( ) { // Constructor default name = "Rumple"; age = 204; gnomeBuddy = null; height = 2.1; } // Mtodos: public static void makeKing (Gnome h) { h.name = "King " + h.getRealName( ); h.magical = true; // Apenas a classe Gnome pode referenciar este campo. } public void makeMeKing ( ) { name = "King " + getRealName( ); magical = true; } public boolean isMagical( ) { return magical; } public void setHeight(int newHeight) { height = newHeight; } public String getName( ) { return "I wont tell!"; } public String getRealName( ) { return name; } public void renameGnome(String s) { name = s; }

Trecho de cdigo 1.3

A classe Gnome.

Observa-se o uso das variveis de instncia no exemplo da classe Gnome. As variveis age, magical e height* so de tipos bsicos, a varivel name uma referncia para uma instncia da classe predefinida String, e a varivel gnomeBuddy** uma referncia para um objeto da classe sendo definida. A declarao da varivel de instncia MAX_HEIGHT*** est tirando proveito desses dois modificadores para definir uma varivel que tem um valor constante fixo. Na verdade, valores constantes associados a uma classe sempre devem ser declarados static e final.

* N. de T. Idade, mgica e altura, respectivamente. ** N. de T. Companheiro do duende. *** N. de T. Largura mxima.

34

Estruturas de Dados e Algoritmos em Java

1.1.3

Tipos enumerados
Desde a verso 5.0, Java suporta tipos enumerados chamados enums. Esses tipos so permitidos apenas para que se possa obter valores provenientes de conjuntos especficos de valores. Eles so declarados dentro de uma classe como segue: modificador enum nome {nome_valor0, nome_valor1, ..., nome_valorn1} onde modificador pode ser vazio, public, protected ou private. O nome desta enumerao, nome, pode ser qualquer identificador Java. Cada um dos identificadores de valor, nome_valuei, o nome de um possvel valor que variveis desse tipo podem assumir. Cada um desses nomes de valor pode ser qualquer identificador Java legal, mas, por conveno, normalmente comeam por letra maiscula. Por exemplo, a seguinte definio de tipo enumerado pode ser til em um programa que deve lidar com datas:
public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN };

Uma vez definido, um tipo enumerado pode ser usado na definio de outras variveis da mesma forma que um nome de classe. Entretanto, como o Java conhece todos os nomes dos valores possveis para um tipo enumerado, se um tipo enumerado for usado em uma expresso string, o Java ir usar o nome do valor automaticamente. Tipos enumerados tambm possuem alguns mtodos predefinidos, incluindo o mtodo valueOf, que retorna o valor enumerado que o mesmo que uma determinada string. Um exemplo de uso de tipo enumerado pode ser visto no Trecho de cdigo 1.4.
public class DayTripper { public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }; public static void main(String[ ] args) { Day d Day.MON; System.out.println("Initially d is " d); d Day.WED; System.out.println("Then it is " d); Day t Day.valueOf("WED"); System.out.println("I say d and t are the same: " } }

(d

t));

A sada deste programa :


Initially d is MON Then it is WED I say d and t are the same: true

Trecho de cdigo 1.4

Um exemplo de uso de tipo enumerado.

1.2

Mtodos

Os mtodos em Java so conceitualmente similares a procedimentos e funes em outras linguagens de alto nvel. Normalmente correspondem a trechos de cdigo que podem ser chamados em um objeto especfico (de alguma classe). Os mtodos podem admitir parmetros como argumentos, e seu comportamento depende do objeto ao qual pertencem e dos valores passados por qualquer parmetro. Todo mtodo em Java especificado no corpo de uma classe. A definio de um mtodo compreende duas partes: a assinatura, que define o nome e os parmetros do mtodo, e o corpo, que define o que o mtodo realmente faz.

Conceitos Bsicos de Programao Java

35

Um mtodo permite ao programador enviar uma mensagem para um objeto. A assinatura do mtodo especifica como uma mensagem deve parecer e o corpo do mtodo especifica o que o objeto ir fazer quando receber tal mensagem.

Declarando mtodos
A sintaxe da definio de um mtodo como segue: modificadores tipo nome(tipo0 parmetro0, ..., tipon1 parmetron1) {
// corpo do mtodo . . . }

Cada uma das partes desta declarao importante e ser descrita em detalhes nesta seo. A seo de modificadores usa os mesmos tipos de modificadores de escopo que podem ser usados para variveis, tais como public, protected e static, com significados parecidos. A seo tipo define o tipo de retorno do mtodo. O nome o nome do mtodo, e pode ser qualquer identificador Java vlido. A lista de parmetros e seus tipos declaram as variveis locais que correspondem aos valores que so passados como argumentos para o mtodo. Cada declarao de tipo, tipoi, pode ser qualquer nome tipo Java e cada parmetroi pode ser qualquer identificador Java. Esta lista de identificadores e seus tipos pode ser vazia, o que significa que no existem valores para serem passados para este mtodo quando for acionado. As variveis parmetro, assim como as variveis de instncia da classe, podem ser usadas dentro do corpo do mtodo. Da mesma forma, os outros mtodos desta classe podem ser chamados de dentro do corpo de um mtodo. Quando um mtodo de uma classe acionado, chamado para uma instncia especfica da classe, e pode alterar o estado daquele objeto (exceto o mtodo static, que associado com a classe propriamente dita). Por exemplo, invocando-se o mtodo que segue em um gnome particular, altera-se seu nome.
public void renameGnome (String s) { name s; // Alterando a varivel de instncia nome deste gnome. }

Modificadores de mtodos
semelhana das variveis de instncia, modificadores de mtodos podem restringir o escopo de um mtodo: public: qualquer um pode chamar mtodos pblicos. protected: apenas mtodos do mesmo pacote ou subclasse podem chamar um mtodo protegido. private: apenas mtodos da mesma classe (excluindo os mtodos de subclasses) podem chamar um mtodo privado. Se nenhum dos modificadores acima for usado, ento o mtodo considerado amigvel. Mtodos amigveis s podem ser chamados por objetos de classes do mesmo pacote. Os modificadores de mtodo acima podem ser precedidos por modificadores adicionais: abstract: um mtodo declarado como abstract no ter cdigo. A lista de parmetros de um mtodo abstrato seguida por um ponto-e-vrgula, sem o corpo do mtodo. Por exemplo:
public abstract void setHeight (double newHeight);

Mtodos abstratos s podem ocorrer em classes abstratas. A utilidade desta construo ser analisada na Seo 2.4. final: este um mtodo que no pode ser sobrescrito por uma subclasse.

36

Estruturas de Dados e Algoritmos em Java


static: este um mtodo que associado com a classe propriamente dita e no com uma instncia em particular. Mtodos static tambm podem ser usados para alterar o estado de variveis static associadas com a classe (desde que estas variveis no tenham sido declaradas como sendo final).

Tipos de retorno
Uma definio de mtodo deve especificar o tipo do valor que o mtodo ir retornar. Se o mtodo no retorna um valor, ento a palavra reservada void deve ser usada. Se o tipo de retorno void, o mtodo chamado de procedimento, caso contrrio, chamado de funo. Para retornar um valor em Java, um mtodo deve usar a palavra reservada return (e o tipo retornado deve combinar com o tipo de retorno do mtodo). Na seqncia, um exemplo de mtodo (interno classe Gnome) que tem a forma de uma funo:
public boolean isMagical ( ) { return magical; }

Assim que um return executado em uma funo Java, a execuo do mtodo termina. Funes Java podem retornar apenas um valor. Para retornar mltiplos valores em Java, deve-se combin-los em um objeto composto cujas variveis de instncia incluam todos os valores desejados e, ento, retornar uma referncia para este objeto composto. Alm disso, pode-se alterar o estado interno de um objeto que passado para um mtodo como outra forma de retornar vrios resultados.

Parmetros
Os parmetros de um mtodo so definidos entre parnteses, aps o nome do mesmo, separados por vrgulas. Um parmetro consiste em duas partes: seu tipo e o seu nome. Se um mtodo no tem parmetros, ento apenas um par de parnteses vazio usado. Todos os parmetros em Java so passados por valor, ou seja, sempre que se passa um parmetro para um mtodo, uma cpia do parmetro feita para uso no contexto do corpo do mtodo. Ao se passar uma varivel int para um mtodo, o valor daquela varivel copiado. O mtodo pode alterar a cpia, mas no o original. Quando se passa uma referncia do objeto como parmetro para um mtodo, ento essa referncia copiada da mesma forma. preciso lembrar que se podem ter muitas variveis diferentes referenciando o mesmo objeto. A alterao da referncia recebida dentro de um mtodo no ir alterar a referncia que foi passada para o mesmo. Por exemplo, ao passar uma referncia g da classe Gnome para um mtodo que chama este parmetro de h, ento o mtodo pode alterar a referncia h de maneira que ela aponte para outro objeto, porm g continuar a referenciar o mesmo objeto anterior. O mtodo, contudo, pode usar a referncia h para mudar o estado interno do objeto, alterando assim o estado do objeto apontado por g (desde que g e h referenciem o mesmo objeto).

Mtodos construtores
Um construtor um tipo especial de mtodo que usado para inicializar objetos novos quando de sua criao. Java tem uma maneira especial de declarar um construtor e uma forma especial de invoc-lo. Primeiro ser analisada a sintaxe de declarao de um construtor: modificadores tipo nome(tipo0 parmetro0, ..., tipon1 parmetron1) {
// corpo do construtor . . . }

Conceitos Bsicos de Programao Java

37

V-se que a sintaxe igual de qualquer outro mtodo, mas existem algumas diferenas essenciais. O nome do construtor name, deve ser o mesmo nome da classe que constri. Se a classe se chama Fish (peixe), ento o construtor deve se chamar Fish da mesma forma. Alm disso, um construtor no possui parmetro de retorno seu tipo de retorno o mesmo que seu nome implicitamente (que tambm o nome da classe). Os modificadores de construtor, indicados acima como modifiers, seguem as mesmas regras que os mtodos normais, exceto pelo fato de que construtores abstract, static ou final no so permitidos. Por exemplo:
public Fish (int w, String n) { weight w; name n; }

Definio e invocao de um construtor


O corpo de um construtor igual ao corpo de um mtodo normal, com um par de pequenas excees. A primeira diferena diz respeito ao conceito conhecido como cadeia de construtores, tpico discutido na Seo 2.2.3 e que no importante a esta altura. A segunda diferena entre o corpo de um construtor e o corpo de um mtodo comum que o comando return no permitido no corpo de um construtor. A finalidade deste corpo ser usado para a inicializao dos dados associados com os objetos da classe correspondente, de forma que os mesmos fiquem em um estado inicial estvel quando criados. Mtodos construtores so ativados de uma nica forma: devem ser chamados atravs do operador new. Assim, a partir da ativao, uma nova instncia da classe automaticamente criada, e seu construtor ento chamado para inicializar as variveis de instncia e executar outros procedimentos de configurao. Por exemplo, considere-se a seguinte ativao de construtor (que corresponde tambm a uma declarao da varivel myFish*):
Fish myFish new Fish (7, "Wally");

Uma classe pode ter vrios construtores, mas cada um deve ter uma assinatura diferente, ou seja, devem ser distinguveis pelo tipo e nmero de parmetros que recebem.

O mtodo main
Certas classes Java destinam-se a ser utilizadas por outras classes, e outras tm como finalidade definir programas executveis**. Classes que definem programas executveis devem conter um outro tipo especial de mtodo para uma classe o mtodo main. Quando se deseja executar um programa executvel Java, referencia-se o nome da classe que define este programa, por exemplo, disparando o seguinte comando (em um Shell Windows, Linux ou UNIX):
java Aquarium

Neste caso, o sistema de execuo de Java procura por uma verso compilada da classe Aquarium (aqurio), e ento ativa o mtodo especial main dessa classe. Esse mtodo deve ser declarado como segue:
public static void main(String[ ] args) { // corpo do mtodo main . . . }

* N. de T. Meu peixe. ** N. de T. Utiliza-se a expresso programa executvel (stand-alone program) neste contexto para indicar um programa que executado sem a necessidade de um navegador, no se referindo a um arquivo binrio executvel.

38

Estruturas de Dados e Algoritmos em Java


Os argumentos passados para o mtodo main pelo parmetro args so os argumentos de linha de comando fornecidos quando o programa chamado. A varivel args um arranjo de objetos String; ou seja, uma coleo de strings indexadas, com a primeira string sendo args[0], a segunda sendo args[1] e assim por diante. (Falaremos mais sobre arranjos na Seo 1.5.)

Chamando um programa Java a partir da linha de comando


Programas Java podem ser chamados a partir da linha de comando usando o comando Java seguido do nome da classe Java que contm o mtodo main que se deseja executar, mais qualquer argumento opcional. Por exemplo, o programa Aquarium poderia ter sido definido para receber um parmetro opcional que especificasse o nmero de peixes no aqurio. O programa poderia ser ativado digitando-se o seguinte em uma janela Shell:
java Aquarium 45

para especificar que se quer um aqurio com 45 peixes dentro dele. Neste caso, args[0] se refere string "45". Uma caracterstica interessante do mtodo main que permite a cada classe definir um programa executvel, e um dos usos deste mtodo testar os outros mtodos da classe. Desta forma, o uso completo do mtodo main uma ferramenta eficaz para a depurao de colees de classes Java.

Blocos de comandos e variveis locais


O corpo de um mtodo um bloco de comandos, ou seja, uma seqncia de declaraes e comandos executveis definidos entre chaves { e }. O corpo de um mtodo e outros blocos de comandos podem conter tambm blocos de comandos aninhados. Alm de comandos que executam uma ao, tal como ativar um mtodo de algum objeto, os blocos de comandos podem conter declaraes de variveis locais. Essas variveis so declaradas no corpo do comando, em geral no incio (mas entre as chaves { e }). As variveis locais so similares a variveis de instncia, mas existem apenas enquanto o bloco de comandos est sendo executado. To logo o fluxo de controle saia do bloco, todas as variveis locais internas do mesmo no podem mais ser referenciadas. Uma varivel local pode ser tanto um tipo base (tal como int, float, double), como uma referncia para uma instncia de alguma classe. Comandos e declaraes simples em Java sempre se encerram com ponto-e-vrgula, ou seja um ;. Existem duas formas de declarar variveis locais: tipo nome; tipo nome = valor_inicial; A primeira declarao simplesmente define que o identificador, nome, de um tipo especfico. A segunda declarao define o identificador, seu tipo e tambm inicializa a varivel com um valor especfico. Seguem alguns exemplos de inicializao de variveis locais:
{ double r; Point p1 new Point (3, 4); Point p2 new Point (8, 2); int i 512; double e 2.71828; }

Conceitos Bsicos de Programao Java

39

1.3

Expresses

Variveis e constantes so usadas em expresses para definir novos valores e para modificar variveis. Nesta seo, discute-se com mais detalhes como as expresses Java funcionam. Elas envolvem o uso de literais, variveis e operadores. Como as variveis j foram examinadas, sero focados rapidamente os literais e analisados os operadores com mais detalhe.

1.3.1

Literais
Um literal qualquer valor constante que pode ser usado em uma atribuio ou outro tipo de expresso. Java admite os seguintes tipos de literais: A referncia para objeto null (este o nico literal que um objeto e pertence classe genrica Object por definio). Booleano: true e false. Inteiro: o default para um inteiro como 176 ou -52 ser do tipo int, que corresponde a um inteiro de 32 bits. Um literal representando um inteiro longo deve terminar por um L ou l, por exemplo, 176L ou -52l, e corresponde a um inteiro de 64 bits. Ponto flutuante: o default para nmeros de ponto flutuante, tais como 3.1415 e 10035.23, ser do tipo double. Para especificar um literal float, ele deve terminar por um Fou um f. Literais de ponto flutuante em notao exponencial tambm so aceitos, como por exemplo, 3.14E2 ou 0.19e10; a base assumida 10. Caracteres: assume-se que constantes de caracteres em Java pertencem ao alfabeto Unicode. Normalmente, um caractere definido como um smbolo individual entre aspas simples. Por exemplo, a e ? so constantes caractere. Alm desses, Java define as seguintes constantes especiais de caracteres:
\n \b \f \

(nova linha) (retorna um espao) (alimenta formulrio) (aspas simples)

\t (tabulao) \r (retorno do carro) \\ (barra invertida) \" (aspas duplas)

Strings: uma string uma seqncia de caracteres entre aspas duplas, por exemplo, o que segue um string literal
"cachorros no sobem em rvores"

1.3.2

Operadores
As expresses em Java implicam em concatenar literais e variveis usando operadores. Os operadores de Java sero analisados nesta seo.

O operador de atribuio
O operador-padro de atribuio em Java =. usado na atribuio de valores para variveis de instncia ou variveis locais. Sua sintaxe : varivel = expresso

40

Estruturas de Dados e Algoritmos em Java


onde varivel se refere a uma varivel que pode ser referenciada no bloco de comandos que contm esta expresso. O valor de uma operao de atribuio o valor da expresso que atribuda. Sendo assim, se i e j so declaradas do tipo int, correto ter um comando de atribuio como o seguinte:
i j 25; // funciona porque o operador avaliado da direita para a esquerda

Operadores aritmticos
Os operadores que seguem so os operadores binrios aritmticos de Java: adio subtrao * multiplicao / diviso % operador mdulo O operador mdulo tambm conhecido como o operador de resto, na medida em que fornece o resto de uma diviso de nmeros inteiros. Com freqncia, usamos mod para indicar o operador de mdulo, e o definimos formalmente como: n mod m de maneira que n mq r, r

para um inteiro q e 0 r n. Java tambm fornece o operador unrio menos ( ), que pode ser colocado na frente de qualquer expresso aritmtica para inverter seu sinal. possvel utilizar parnteses em qualquer expresso para definir a ordem de avaliao. Java utiliza ainda uma regra de precedncia de operadores bastante intuitiva para determinar a ordem de avaliao quando no so usados parnteses. Ao contrrio de C++, Java no permite a sobrecarga de operadores.

Operadores de incremento e decremento


Da mesma forma que C e C++, Java oferece operadores de incremento e decremento. De forma mais especfica, oferece os operadores incremento de um ( ) e decremento de um ( ). Se tais operadores so usados na frente de um nome de varivel, ento 1 somado ou subtrado varivel, e seu valor empregado na expresso. Se for utilizado depois do nome da varivel, ento primeiro o valor usado, e depois a varivel incrementada ou decrementada de 1. Assim, por exemplo, o trecho de cdigo
int i 8; int j i ; int k i; int m i ; int n 9 i

atribui 8 para j, 10 para k, 10 para m, 18 para n e deixa i com o valor 10.

Operadores lgicos
Java oferece operadores padro para comparaes entre nmeros: menor que menor que ou igual a igual a

Conceitos Bsicos de Programao Java


! diferente de maior que ou igual a maior que

41

Os operadores e ! tambm podem ser usados com referncias para objetos. O tipo resultante de uma comparao boolean. Os operadores que trabalham com valores boolean so os seguintes: ! negao (prefixado) && e condicional || ou condicional Os operadores booleanos && e | | no avaliaro o segundo operando em suas expresses (para a direita) se isso no for necessrio para determinar o valor da expresso. Este recurso til, por exemplo, para construir expresses booleanas onde primeiro se testa se uma determinada condio se aplica (tal como uma referncia no ser null) e, ento, se testa uma condio que geraria uma condio de erro, se o primeiro teste falhasse.

Operadores sobre bits


Java fornece, tambm, os seguintes operadores sobre bits para inteiros e booleanos: & | ^ complemento sobre bits (operador prefixado unrio) e sobre bits ou sobre bits ou exclusivo sobre bits deslocamento de bits para esquerda, preenchendo com zeros deslocamento de bits para a direita, preenchendo com bits de sinal deslocamento de bits para a direita, preenchendo com zeros

Operadores operacionais de atribuio


Alm do operador de atribuio padro (=), Java tambm oferece um conjunto de outros operadores de atribuio que tm efeitos colaterais operacionais. Esses outros tipos de operadores so da forma: varivel op = expresso onde op um operador binrio. Esta expresso equivalente a varivel = varivel op expresso excetuando-se que, se varivel contm uma expresso (por exemplo, um ndice de arranjo), a expresso avaliada apenas uma vez. Assim, o fragmento de cdigo
a[5] 10; i 5; a[i ] 2;

deixa a[5] com o valor 12 e i com o valor 6.

Concatenao de strings
As strings podem ser compostas usando o operador de concatenao ( ), de forma que o cdigo
String rug "carpet"; String dog "spot"; String mess rug dog; String answer mess "will cost me"

"dollars!";

42

Estruturas de Dados e Algoritmos em Java


ter o efeito de fazer answer apontar para a string
"carpetspot will cost me 5 dollars!"

Esse exemplo tambm mostra como Java converte constantes que no so string em strings, quando estas esto envolvidas em uma operao de concatenao de strings.

Precedncia de operadores
Os operadores em Java tm uma dada preferncia, ou precedncia, que determina a ordem na qual as operaes so executadas quando a ausncia de parnteses ocasiona ambigidades na avaliao. Por exemplo, necessrio que exista uma forma de decidir se a expresso 5+2*3 tem valor 21 ou 11 (em Java o valor 11). A Tabela 1.3 apresenta a precedncia dos operadores em Java (que, coincidentemente, a mesma de C).
Precedncia de operadores Smbolos exp exp exp exp +exp exp exp !exp (type) exp */%
instanceof

2 3 4 5 6 7 8 9 10 11 12 13

Tipo operadores ps-fixados operadores pr-fixados cast (coero) mult./div. soma/subt. deslocamento comparao igualdade e bit a bit xor bit a bit ou bit a bit e ou condicional atribuio

! & ^ | && || expresso booleana? valor se true : valor se * / % &

Tabela 1.3 As regras de precedncia de Java. Os operadores em Java so avaliados de acordo com a ordem acima se no forem utilizados parnteses para determinar a ordem de avaliao. Os operadores na mesma linha so avaliados da esquerda para a direita (exceto atribuies e operaes prefixadas, que so avaliadas da direita para esquerda), sujeitos regra de avaliao condicional para as operaes booleanas e e ou. As operaes so listadas da precedncia mais alta para a mais baixa (usamos exp para indicar uma expresso atmica ou entre parnteses). Sem parnteses, os operadores de maior precedncia so executados depois de operadores de menor precedncia. Discutiu-se at agora quase todos os operadores listados na Tabela 1.3. Uma exceo notvel o operador condicional, o que implica avaliar uma expresso booleana e ento tomar o valor apropriado, dependendo de a expresso booleana ser verdadeira ou falsa. (O uso do operador instanceof ser analisado no prximo captulo.)

1.3.3

Conversores e autoboxing/unboxing em expresses


A converso uma operao que nos permite alterar o tipo de uma varivel. Em essncia, podese converter uma varivel de um tipo em uma varivel equivalente de outro tipo. Os conversores

Conceitos Bsicos de Programao Java

43

podem ser teis para fazer certas operaes numricas e de entrada e sada. A sintaxe para converter uma varivel para um tipo desejado a seguinte: (tipo) exp onde tipo o tipo que se deseja que a expresso exp assuma. Existem dois tipos fundamentais de conversores que podem ser aplicados em Java. Pode-se tanto converter tipos de base numrica como tipos relacionados com objetos. Agora, ser discutida a converso de tipos numricos e strings e a converso de objetos ser analisada na Seo 2.5.1. Por exemplo, pode ser til converter um int em um double de maneira a executar operaes como uma diviso.

Conversores usuais
Quando se converte um double em um int, pode-se perder a preciso. Isso significa que o valor double resultante ser arredondado para baixo. Mas pode-se converter um int em um double sem esta preocupao. Por exemplo, considere o seguinte:
double d1 3.2; double d2 3.9999; int i1 (int)d1; int i2 (int)d2; double d3 (double)i2;

// i1 tem valor 3 // i2 tem valor 3 // d3 tem valor 3.0

Convertendo operadores
Alguns operadores binrios, como o de diviso, tero resultados diferentes dependendo dos tipos de variveis envolvidas. Devemos ter cuidado para garantir que tais operaes executem seus clculos em valores do tipo desejado. Quando usada com inteiros, por exemplo, a diviso no mantm a parte fracionria. No caso de uso com double, a diviso conserva esta parte, como ilustra o exemplo a seguir:
int i1 3; int i2 6; dresult (double)i1 / (double)i2; dresult i1 / i2;

// dresult tem valor 0.5 // dresult tem valor 0.0

Observe que a diviso normal para nmeros reais foi executada quando i1 e i2 foram convertidos em double. Quando i1 e i2 no foram convertidos, o operador / executou uma diviso inteira e o resultado de i1 / i2 foi o int 0. Java executou uma converso implcita para atribuir um valor int ao resultado double. Vamos estudar a converso implcita a seguir.

Conversores implcitos e autoboxing/unboxing


Existem casos onde o Java ir executar uma converso implcita, de acordo com o tipo da varivel sendo atribuda, desde que no haja perda de preciso. Por exemplo:
int iresult, i 3; double dresult, d dresult i / d; iresult i / d; iresult (int) i / d; 3.2; // dresult tem valor 0.9375. i foi convertido para double // perda de preciso - isso em um erro de compilao; // iresult 0, uma vez que a parte fracionria ser perdida.

Considerando que Java no executar converses implcitas onde houver perda de preciso, a converso explcita da ltima linha do exemplo necessria. A partir do Java 5.0, existe um novo tipo de converso implcita entre objetos numricos, tais como Integer e Float, e seus tipos bsicos relacionados, tais como int e float. Sempre que um ob-

44

Estruturas de Dados e Algoritmos em Java


jeto numrico for esperado como parmetro para um mtodo, o tipo bsico correspondente pode ser informado. Neste caso, o Java ir proceder uma converso implcita chamada autoboxing, que ir converter o tipo base para o objeto numrico correspondente. Da mesma forma, sempre que um tipo base for esperado em uma expresso envolvendo um objeto numrico, o objeto numrico ser convertido no tipo base correspondente em uma operao chamada de unboxing. Existem, entretanto, alguns cuidados a serem tomados no uso de boxing e unboxing. O primeiro que se uma referncia numrica for null, ento qualquer tentativa de unboxing ir gerar um erro de NullPointerException. Em segundo, o operador == usado tanto para testar a igualdade de dois valores numricos como se duas referncias para objetos apontam para o mesmo objeto. Sendo assim, quando se testa a igualdade, deve-se evitar a converso implcita provida por autoboxing/unboxing. Por fim, a converso implcita de qualquer tipo toma tempo, logo devemos minimizar nossa confiana nela se performance for um requisito. Cinrcunstancialmente, existe uma situao em Java em que apenas a converso implcita permitida, que na concatenao de strings. Sempre que uma string concatenada com qualquer objeto ou tipo base, o objeto ou tipo base automaticamente convertido em uma string. Entretanto, a converso explcita de um objeto ou tipo base para uma string no permitida. Portanto, as seguintes atribuies so incorretas:
String s String t String u (String) 4.5; "Value = " 22; // Isso est errado! (String) 13; // Isso est errado! // Isso est errado!

Para executar converses para string, deve-se, ao invs disso, usar o mtodo toString apropriado ou executar uma converso implcita via operao de concatenao. Assim, os seguintes comandos esto corretos:
String s String t String u "" 4.5; // correto, porm, mau estilo de programao "Value = " 13; // correto Integer.toString(22); // correto

1.4

Controle de fluxo
O controle de fluxo em Java similar ao oferecido em outras linguagens de alto nvel. Nesta seo, revisa-se a estrutura bsica e a sintaxe do controle de fluxo em Java, incluindo retorno de mtodos, comando condicional, comandos de seleo mltipla, laos e formas restritas de desvios (os comandos break e continue).

1.4.1

Os comandos if e switch
Em Java, comandos condicionais funcionam da mesma forma que em outras linguagens. Eles fornecem a maneira de tomar uma deciso e ento executar um ou mais blocos de comandos diferentes baseados no resultado da deciso.

O comando if
A sintaxe bsica do comando if a que segue:
if (expr_booleana)

comando_se_verdade
else

commando_se_falso

Conceitos Bsicos de Programao Java

45

onde expr_booleana uma expresso booleana e comando_se_verdade e comando_se_falso podem ser um comando simples ou um bloco de comandos entre chaves ({ e }). Observa-se que, diferentemente de outras linguagens de programao, os valores testados por um comando if devem ser uma expresso booleana. Particularmente, no so uma expresso inteira. Por outro lado, como em outras linguagens similares, a clusula else (e seus comandos associados) so opcionais. Existe tambm uma forma de agrupar um conjunto de testes booleanos como segue:
if (primeira_expresso_booleana)

comando_se_verdade
else if (segunda_expresso_booleana)

segundo_comando_se_verdade
else

comando_se_falso Se a primeira expresso booleana for falsa, ento a segunda expresso booleana ser testada, e assim por diante. Um comando if pode ter qualquer quantidade de clusulas else if. Por exemplo, a estrutura a seguir est correta:
if (snowLevel 2) { goToClass( ); comeHome( ); } else if (snowLevel 5) { goSledding( ); haveSnowballFight( ); } else stayAtHome( );

Comando switch
Java oferece o comando switch para controle de fluxo multivalorado, o que especialmente til com tipos enumerados. O exemplo a seguir indicativo (baseado na varivel d do tipo Day da Seo 1.1.3).
switch (d) { case MON: System.out.println("This is tough."); break; case TUE: System.out.println("This is getting better."); break; case WED: System.out.println("Half way there."); break; case THU: System.out.println("I can see the light."); break; case FRI: System.out.println("Now we are talking."); break; default: System.out.println("Day off!"); break; }

46

Estruturas de Dados e Algoritmos em Java


O comando switch avalia uma expresso inteira ou enumerao e faz com que o fluxo de controle desvie para o ponto marcado com o valor dessa expresso. Se no existir um ponto com tal marca, ento o fluxo desviado para o ponto marcado com default. Entretanto, este o nico desvio explcito que o comando switch executa, e, a seguir, o controle cai atravs das clusulas case se o cdigo dessas clusulas no for terminado por uma instruo break (que faz o fluxo de controle desviar para a prxima linha depois do comando switch).

1.4.2

Laos
Outro mecanismo de controle de fluxo importante em uma linguagem de programao o lao. Java possui trs tipos de laos.

Laos while
O tipo mais simples de lao em Java o lao while. Este tipo de lao testa se uma certa condio satisfeita e executa o corpo do lao enquanto esta condio for true. A sintaxe para testar uma condio antes de o corpo do lao ser executado a seguinte:
while (expresso_booleana)

corpo_do_lao No incio de cada iterao, o lao testa a expresso booleana, boolean exp, e ento, se esta resultar true, executa o corpo do lao, loop statement. Da mesma forma que o lao for, o corpo do lao tambm pode ser um bloco de comandos. Considere-se, por exemplo, um gnomo tentando regar todas as cenouras de seu canteiro de cenouras, o que faz at seu regador ficar vazio. Se o regador estiver vazio logo no incio, escrevese o cdigo para executar esta tarefa como segue:
public void waterCarrots( ) { Carrot current garden.ndNextCarrot ( ); while (!waterCan.isEmpty ( )) { water (current, waterCan); current garden.ndNextCarrot ( ); } }

Lembre-se que ! em Java o operador not.

Laos for
Outro tipo de lao o lao for. Na sua forma mais simples, os laos for oferecem uma repetio codificada baseada em um ndice inteiro. Em Java, entretanto, pode-se fazer muito mais. A funcionalidade de um lao for significativamente mais flexvel. Sua estrutura se divide em quatro sees: inicializao, condio, incremento e corpo.

Definindo um lao for


Esta a sintaxe de um lao for em Java
for (inicializao; condio; incremento)

corpo_do_lao onde cada uma das sees de inicializao, condio e incremento podem estar vazias.

Conceitos Bsicos de Programao Java

47

Na seo inicializao, pode-se declarar uma varivel ndice que ser vlida apenas no escopo do lao for. Por exemplo, quando se deseja um lao indexado por um contador, e no h necessidade desse contador fora do contexto do lao for, ento declara-se algo como o que segue
for (int counter 0; condio; incremento)

corpo_do_lao que declara uma varivel counter cujo escopo limitado apenas ao corpo do lao. Na seo condio, especifica-se a condio de repetio (enquanto) do lao. Esta deve ser uma expresso booleana. O corpo do lao for ser executado toda a vez que a condio resultar true, quando avaliada no incio de uma iterao potencial. Assim que a condio resultar false, ento o corpo do lao no ser executado e, em seu lugar, o programa executa o prximo comando depois do lao for. Na seo de incremento, declara-se o comando de incremento do lao. O comando de incremento pode ser qualquer comando vlido, o que permite uma flexibilidade significativa para a programao. Assim, a sintaxe do lao for equivalente ao que segue: inicializao; while (condio) { comandos_do_lao incremento;
}

exceto pelo fato de que um lao while no pode ter uma condio booleana vazia, enquanto que um lao for pode. O exemplo a seguir apresenta um exemplo simples de lao for em Java:
publi void eatApples (Apples apples) { numApples apples.getNumApples ( ); for (int 0; numApples; ){ eatApple (apples.getApple ( )); spitOutCore ( ); } }

Neste exemplo, a varivel de lao foi declarada como int 0. Antes de cada iterao, o lao testa a condio numApples e executa o corpo do lao apenas se isso for verdadeiro. Por ltimo, ao final de cada iterao, o lao usa a expresso para incrementar a varivel do lao antes de testar a condio novamente. Desde a verso 5.0, Java inclui o lao for-each, que ser discutido na Seo 6.3.2.

Laos do-while
Java tem ainda outro tipo de lao alm do lao for e do lao while padro o lao do-while. Enquanto que os primeiros testam a condio antes de executar a primeira iterao com o corpo do lao, o lao do-while testa a condio aps o corpo do lao. A sintaxe de um lao do-while mostrada a seguir:
do

corpo_do_lao
while (condio)

Mais uma vez, o corpo do lao pode ser um comando ou um bloco de comandos, e a condio ser uma expresso booleana. Em um lao do-while, repete-se o corpo do lao enquanto a expresso resultar verdadeira a cada avaliao. Suponha-se, por exemplo, que se deseja solicitar uma entrada ao usurio e posteriormente fazer algo til com essa entrada. (Entradas e sadas em Java sero examinadas com mais detalhes

48

Estruturas de Dados e Algoritmos em Java


na Seo 1.6.) Uma condio possvel para sair do lao, neste caso, quando o usurio entra uma string vazia. Entretanto, mesmo neste caso, pode-se querer manter a entrada e informar ao usurio que ela saiu. O exemplo a seguir ilustra o caso:
public void getUserInput( ) { String input; do { input getInputString( ); handleInput(input); } while (input.length( ) 0); }

Observe-se a condio de sada do exemplo. Mais especificamente, est escrita para ser consistente com a regra de Java que diz que laos do-while se encerram quando a condio no verdadeira (ao contrrio da construo repeat-until usada em outras linguagens).

1.4.3

Expresses explcitas de controle de fluxo


Java tambm oferece comandos que permitem alteraes explcitas no fluxo de controle de um programa.

Retornando de um mtodo
Se um mtodo Java declarado com o tipo de retorno void, ento o fluxo de controle retorna quando encontra a ltima linha de cdigo do mtodo ou quando encontra um comando return sem argumentos. Entretanto, se um mtodo declarado com um tipo de retorno, ele uma funo e dever terminar retornando o valor da funo como um argumento do comando return. O exemplo seguinte (correto) ilustra o retorno de uma funo:
// Verica um aniversrio especco public boolean checkBDay (int date) { if (date Birthday.MIKES_BDAY){ return true; } return false; }

Conclui-se que o comando return deve ser o ltimo comando executado em uma funo, j que o resto do cdigo nunca ser alcanado. Existe uma diferena significativa entre um comando ser a ltima linha de cdigo a ser executada em um mtodo ou ser a ltima linha de cdigo do mtodo propriamente dita. No exemplo anterior, a linha return true; claramente no a ltima linha do cdigo escrito para a funo, mas pode ser a ltima linha executada (se a condio envolvendo date for true). Esse comando interrompe de forma explcita o fluxo de controle do mtodo. Existem dois outros comandos explcitos de controle de fluxo que so usados em conjunto com laos e com o comando switch.

O comando break
O uso tpico do comando break tem a seguinte sintaxe simples:
break;

usado para sair do bloco internamente mais aninhado dos comandos switch, for, while ou do-while. Quando executado, um comando break faz com que o fluxo de controle seja desviado para a prxima linha depois do lao ou switch que contm o break.

Conceitos Bsicos de Programao Java

49

O comando break tambm pode ser usado de forma rotulada para desviar para o lao ou comando switch de aninhamento mais externo. Neste caso, ele tem a sintaxe:
break label;

onde label um identificador em Java usado para rotular um lao ou um comando switch. Este tipo de rtulo s pode aparecer no incio da declarao de um lao; no existem outras formas de comandos go to em Java. O uso de um rtulo com comando break ilustrado no seguinte exemplo:
public static boolean hasZeroEntry (int[ ][ ] a) { boolean foundFlag false; zeroSearch: for (int i 0; i a.length; i ){ for (int j 0; j a[i].length; j if (a[i][j] 0) { foundFlag true; break zeroSearch; } } } return foundFlag; }

){

O exemplo acima usa arranjos que sero abordados na Seo 3.1

O comando continue
O outro comando que altera explicitamente o fluxo de controle em um programa Java o comando continue, que tem a seguinte sintaxe:
continue label;

onde label um identificador em Java usado para rotular o lao. Como j foi mencionado anteriormente, no existem comandos go to explcitos em Java. Da mesma forma, o comando continue s pode ser usado dentro de laos (for, while e do-while). O comando continue faz com que a execuo pule os passos restantes do lao na iterao atual (mas continue o lao se a condio for satisfeita).

1.5

Arranjos

Uma tarefa comum em programao a manuteno de um conjunto numerado de objetos relacionados. Por exemplo, deseja-se que um jogo de videogame mantenha a relao das dez melhores pontuaes. Em vez de se usar dez variveis diferentes para esta tarefa, prefere-se usar um nico nome para o conjunto e usar ndices numricos para referenciar as pontuaes mais altas dentro do conjunto. Da mesma forma, deseja-se que um sistema de informaes mdicas mantenha a relao de pacientes associados aos leitos de um certo hospital. Novamente, no necessrio inserir 200 variveis no programa apenas porque o hospital tem 200 leitos. Nestes casos, minimiza-se o esforo de programao pelo uso de arranjos, que so colees numeradas de variveis do mesmo tipo. Cada varivel ou clula em um arranjo tem um ndice, que referencia o valor armazenado na clula de forma nica. As clulas de um arranjo a so numeradas 0, 1, 2 e assim por diante. A Figura 1.6 apresenta o desenho de um arranjo contendo as melhores pontuaes do videogame.

50

Estruturas de Dados e Algoritmos em Java


Melhores pontuaes ndices

Figura 1.6 Desenho de um arranjo com as dez (int) melhores pontuaes de um videogame. Essa forma de organizao extremamente til, na medida em que permite computaes interessantes. Por exemplo, o mtodo a seguir soma todos os valores armazenados em um arranjo de inteiros:
/** Soma todos os valores de um arranjo de inteiros */ public static int sum(in [ ] a) { int total 0; for (int i 0; i a.length; i ) // observe-se o uso da varivel length total += a[i]; return total; }

Este exemplo tira vantagem de um recurso interessante de Java que permite determinar a quantidade de clulas mantidas por um arranjo, ou seja, seu tamanho*. Em Java um arranjo a um tipo especial de objeto, e o tamanho de a est armazenado na varivel de instncia length. Isto , jamais ser necessrio ter de adivinhar o tamanho de um arranjo em Java, visto que o tamanho de um arranjo pode ser acessado como segue: nome_do_arranjo.length onde nome_do_arranjo o nome do arranjo. Assim, as clulas de um arranjo a so numeradas 0, 1, 2, e assim por diante at a.length 1.

Elementos e capacidade de um arranjo


Cada objeto armazenado em um arranjo chamado de elemento do arranjo. O elemento nmero 0 a[0], o elemento nmero 1 a[1], o elemento nmero 2 a[2], e assim por diante. Uma vez que o comprimento de um arranjo determina o nmero mximo de coisas que podem ser armazenadas no arranjo, tambm pode-se referir ao comprimento de um arranjo como sendo sua capacidade. O trecho de cdigo que segue apresenta outro exemplo simples de uso de arranjos, que conta o nmero de vezes que um certo nmero aparece em um arranjo.
/** Conta o nmero de vezes que um inteiro aparece em um arranjo */ public static int ndCount(int[ ] a, int k) { int count 0; for (int e: a) { // observe-se o uso do lao foreach if (e == k) //deve-se vericar se o elemento corrente igua a k count++; } return count; }

Erros de limites
um erro perigoso tentar indexar um arranjo a usando um nmero fora do intervalo de 0 a a.length 1. Tal referncia dita estar fora de faixa. Referncias fora de faixa tem sido fre* N. de T. Apesar da expresso em ingls length indicar comprimento, mais comum entre programadores Java o uso da expresso tamanho do arranjo.

Conceitos Bsicos de Programao Java

51

qentemente exploradas por hackers usando um mtodo chamado ataque do estouro do buffer* comprometendo a segurana de sistemas de computao escritos em outras linguagens em vez de Java. Por questes de segurana, os ndices de arranjo so sempre verificados em Java para constatar se no esto fora de faixa. Se um ndice de arranjo est fora de faixa, o ambiente de execuo de Java sinaliza uma condio de erro. O nome desta condio ArrayIndexOutOfBoundsExceptions. Esta verificao auxilia para que Java evite uma srie de problemas (incluindo problemas de ataque de estouro de buffer) com os quais outras linguagens tem de lutar. Pode-se evitar erros de ndice fora de faixa tendo certeza de que as indexaes sempre sero feitas dentro de um arranjo a, usando valores inteiros entre 0 e a.length. Uma forma simples de fazer isso usando com cuidado o recurso das operaes booleanas de Java j apresentado. Por exemplo, um comando como o que segue nunca ir gerar um erro de ndice fora de faixa:
if ((i x 0) && (i a[i]; a.length) && (a[i] 2) )

pois a comparao a[i] sucedidas.

5 s ser executada se as duas primeiras comparaes forem bem-

1.5.1

Declarando arranjos
Uma forma de declarar e inicializar um arranjo a seguinte: tipo_do_elemento[] nome_do_arranjo = { val_inic_0, val_inic_1, ..., val_inic_N-1}; O tipo_do_elemento pode ser qualquer tipo base de Java ou um nome de classe e nome_do_arranjo pode ser qualquer identificador Java vlido. Os valores de inicializao devem ser do mesmo tipo que o arranjo. Por exemplo, considere-se a seguinte declarao de um arranjo que inicializado para conter os primeiros dez nmeros primos:
int[ ] primes {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

Alm de declarar um arranjo e inicializar todos os seus valores na declarao, pode-se declarar um arranjo sem inicializ-lo. A forma desta declarao a que segue: tipo_do_elemento[] nome_do_arranjo; Um arranjo criado desta forma inicializado com zeros se o tipo do arranjo for um tipo numrico. Arranjos de objetos so inicializados com referncias null. Uma vez criado um arranjo desta forma, pode-se criar o conjunto de clulas mais tarde usando a sintaxe a seguir: new tipo_do_elemento[comprimento] onde comprimento um inteiro positivo que denota o comprimento do arranjo criado. Normalmente, esta expresso aparece em comandos de atribuio com o nome do arranjo do lado esquerdo do operador de atribuio. Ento, por exemplo, o seguinte comando define uma varivel arranjo chamada a e, mais tarde, atribuem-se mesma um arranjo de dez clulas, cada uma do tipo double, que ento inicializado:
double[ ] a; // ... vrios passos ... a = new double[10]; for (int k=0; k a.length; k++) { a[k] = 1.0; }
* N. de T. Em ingls, buffer overflow attack.

52

Estruturas de Dados e Algoritmos em Java


As clulas do novo arranjo a so indexadas usando o conjunto inteiro {0,1,2, ..., 9} (lembre-se que os arranjos em Java sempre iniciam a indexao em 0), e, da mesma forma que qualquer arranjo Java, todas as clulas deste arranjo so do mesmo tipo double.

1.5.2

Arranjos so objetos
Arranjos em Java so tipos especiais de objetos. Na verdade, esta a razo pela qual pode-se usar o operador new para criar uma nova instncia de arranjo. Um arranjo pode ser usado da mesma forma que qualquer outro objeto de Java, mas existe uma sintaxe especial (usando colchetes, [ e ]) para se referenciar a seus membros. Um arranjo Java pode fazer tudo que um objeto genrico pode fazer. Como se trata de um objeto, o nome de um arranjo em Java , na verdade, uma referncia para o lugar na memria onde o arranjo est armazenado. Assim, no existe nada de to especial em se usar o operador ponto e a varivel de instncia length, para se referir ao comprimento de um arranjo como no exemplo a.length. O nome a, neste caso, apenas uma referncia ou ponteiro para o arranjo subjacente. O fato de que arranjos em Java so objetos tem uma implicao importante quando se usa nomes de arranjos em expresses de atribuio. Quando se escreve algo tal como
b a;

em um programa Java, na verdade significa que agora tanto b como a se referem ao mesmo arranjo. Ento, ao se escrever algo como
b[3] 5;

se est alterando a[3] para 5. Este ponto crucial demonstrado na Figura 1.7.

Alterao resultante da atribuio b[3] = 5;

Figura 1.7 Desenho da atribuio de um arranjo de objetos. Apresenta-se o resultado da atribuio de b[3] = 5; depois de previamente ter executado b = a.

Clonando um arranjo
Se, por outro lado, for necessrio criar uma cpia exata do arranjo a e atribuir esse arranjo para a varivel arranjo b, pode-se escrever:
b a.clone( );

que copia todas as clulas em um novo arranjo e o atribui a b, de maneira que este aponta para o novo arranjo. Na verdade, o mtodo clone um mtodo predefinido de todo objeto Java, e cria uma cpia exata de um objeto. Neste caso, se ento escrever-se
b[3] 5;

o novo arranjo (copiado) ter o valor 5 atribudo para a clula de ndice 3, mas a[3] ir permanecer inalterado. Demonstra-se esta situao na Figura 1.8.

Conceitos Bsicos de Programao Java

53

Alterao originria da atribuio b[3] = 5;

Figura 1.8 Demonstrao da clonagem de um arranjo de objetos. Demonstra-se o resultado da atribuio b[3] = 5 aps a atribuio b = a.clone( );. Detalhando, pode-se afirmar que as clulas de um arranjo so copiadas quando o mesmo clonado. Se as clulas so de um tipo base, como int, os valores so copiados. Mas se as clulas so referncias para objetos, ento essas referncias so copiadas. Isso significa que existem duas maneiras de referenciar tais objetos. As conseqncias deste fato so exploradas no Exerccio R-1.1.

1.6

Entrada e sada simples


Java oferece um conjunto rico de classes e mtodos para executar entrada e sada. Existem classes para executar projetos de interfaces grficas com o usurio, incluindo dilogos e menus suspensos, assim como mtodos para a exibio e a entrada de texto e nmeros. Java tambm oferece mtodos para lidar com objetos grficos, imagens, sons, pginas Web e eventos de mouse (tais como cliques, deslocamentos do mouse e arrasto). Alm do mais, muitos desses mtodos de entrada e sada podem ser usados tanto em programas executveis como em applets. Infelizmente, detalhar como cada um desses mtodos funciona para construir interfaces grficas sofisticadas com o usurio est alm do escopo deste livro. Entretanto, em nome de uma maior abrangncia, descreve-se nesta seo como se pode fazer entrada e sada simples em Java. Em Java, a entrada e sada simples feita atravs da janela console de Java. Dependendo do ambiente Java que se est empregando, esta janela pode ser a janela especial usada para exibio e entrada de texto, ou a janela que se utiliza para passar comandos para nosso sistema operacional (tais janelas costumam ser chamadas de janelas de console, janelas DOS ou janelas de terminal).

Mtodos de sada
Java oferece um objeto static embutido chamado System.out, que envia a sada para o dispositivo de sada-padro. Alguns sistemas operacionais permitem aos usurios redirecionar a sada-padro para arquivos ou at mesmo como entrada para outros programas, embora a sada-padro seja a janela de console de Java. O objeto System.out uma instncia da classe java.io.PrintStream. Essa classe define mtodos para um fluxo buferizado de sada, o que significa que os caracteres so colocados em uma localizao temporria, chamada buffer, que esvaziada quando a janela de console estiver pronta para imprimir os caracteres.

54

Estruturas de Dados e Algoritmos em Java


Mais especificamente, a classe java.io.PrintStream fornece os seguintes mtodos para executar sadas simples (usamos base_type para indicar qualquer um dos possveis tipos bsicos): print(Object o): imprime o objeto o usando seu mtodo toString; print(String s): imprime a string s; print(base_type b): imprime o valor de b conforme seu tipo bsico; println(String s): imprime a string s, seguida pelo caractere de nova linha.

Um exemplo de sada
Considere, por exemplo, o seguinte trecho de cdigo:
System.out.print("Java values: "); System.out.print(3.1415); System.out.print(,); System.out.print(15); System.out.println(" (double,char,int).");

Quando executado, este trecho de cdigo produz a seguinte sada na janela console de Java:
Java values: 3.1415,15 (double,char,int).

Entrada simples usando a classe java.util.Scanner


Assim como existe um objeto especial para enviar a sada para a janela de console de Java, existe tambm um objeto especial, chamado System.in, para executar a entrada de dados a partir da janela de console de Java. Tecnicamente, a entrada vem, na verdade, do dispositivo de entradapadro, o qual, por default, o teclado do computador ecoando os caracteres na janela de console de Java. O objeto System.in um objeto associado com o dispositivo de entrada padro. Uma maneira simples de ler a entrada usando este objeto utiliz-lo para criar um objeto Scanner, atravs da expresso:
new Scanner(System.in)

A classe Scanner inclui uma srie de mtodos convenientes para ler do fluxo de entrada. Por exemplo, o programa que segue usa um objeto Scanner para processar a entrada:
import java.io.*; import java.util.Scanner; public class InputExample { public static void main(Stringargs[ ]) throws IOException { Scanner s new Scanner(System.in); System.out.print("Enteryourheightincentimeters: "); oat height s.nextFloat( ); System.out.print("Enteryourweightinkilograms: "); oat weight s.nextFloat( ); oat bmi weight/(height*height)*10000; System.out.println("Yourbodymassindexis" bmi "."); } }

Quando executado, este programa gera o seguinte no console de Java:


Enter your height in centimeters: 180 Enter your weight in kilograms: 80.5 Your body mass index is 24.84568.

Conceitos Bsicos de Programao Java

55

Mtodos de java.util.Scanner
A classe Scanner l o fluxo de entrada e divide o mesmo em tokens, que so strings de caracteres contguos separados por delimitadores, que correspondem a caracteres separadores. O delimitador padro o espao em branco, ou seja, tokens so separados por strings de espaos, tabulaes ou nova-linha, por default. Tokens tanto podem ser lidos imediatamente como strings ou um objeto Scanner pode converter um token para um tipo base, se o token estiver sintaticamente correto. Para tanto, a classe Scanner inclui os seguintes mtodos para lidar com tokens:
hasNext( ): retorna true se e somente se existe mais um token no strings de entrada. next( ): retorna o prximo token do fluxo de entrada; gera um erro se no exis-

tem mais tokens.


hasNextType(Tipo): retorna true se e somente se existe mais um token no fluxo de entrada e

se pode ser interpretado como sendo do tipo base correspondente, Tipo, onde Tipo pode ser Boolean, Byte, Double, Float, Int, Long ou Short. nextType(Tipo): retorna o prximo token do fluxo de entrada, retornando-o com o tipo base correspondente a Tipo; gera uma erro se no existem mais tokens ou se o prximo token no pode ser interpretado como sendo do tipo base correspondente a Tipo. Alm disso, objetos Scanner podem processar a entrada linha por linha, ignorando os delimitadores e mesmo podem procurar por padres em linhas. Os mtodos para processar a entrada desta forma incluem os seguintes:
hasNextLine( ): retorna true se e somente se o fluxo de entrada tem outra linha de texto. nextLine( ): avana a entrada at o final da linha corrente e retorna toda a entrada

que foi deixada para trs. findInLine(String s): procura encontrar um string que combine com o padro (expresso regular) s na linha corrente. Se o padro for encontrado, ele retornado e o scanner avana para o primeiro caractere depois do padro. Se o padro no for encontrado, o scanner retorna null e no avana. Esses mtodos podem ser usados com os anteriores, como no exemplo que segue:
Scanner input new Scanner(System.in); System.out.print("Please enter an integer: "); while (!input.hasNextInt( )) { input.nextLine( ); System.out.print("Thats not an integer; please enter an integer: "); } int i input.nextInt( );

1.7

Um programa de exemplo
Nesta seo, ser descrito um exemplo simples de programa Java que ilustra muitas das construes definidas anteriormente. O exemplo consiste em duas classes: CreditCard, que define objetos que representam cartes de crdito; e Test, que testa as funcionalidades da classe CreditCard. Os objetos que representam cartes de crdito, definidos pela classe CreditCard, so verses simplificadas dos cartes de crdito tradicionais. Eles tm um nmero de identificao, informaes de identificao do proprietrio e do banco que os emitiram e informaes sobre o saldo corrente e o limite de crdito. No debitam juros ou pagamentos atrasados, mas restringem pagamentos que possam fazer com que o saldo v alm do limite de gastos.

56

Estruturas de Dados e Algoritmos em Java

A classe CreditCard
A classe CreditCard apresentada no Trecho de cdigo 1.5. Ela define cinco variveis de instncia, todas exclusivas, e possui um construtor simples que inicializa essas variveis. Ela tambm define cinco mtodos de acesso que permitem acessar o valor corrente dessas variveis de instncia. Evidentemente, as variveis de instncia poderiam ter sido definidas como pblicas, o que faria com que os mtodos de acesso fossem duvidosos. A desvantagem dessa abordagem direta, porm, que permite ao usurio modificar as variveis de instncia do objeto diretamente, enquanto que, em muitos casos como este, prefervel restringir a alterao de variveis de instncia a mtodos especiais chamados de mtodos de atualizao. No Trecho de cdigo 1.5, inclui-se dois mtodos de atualizao, chargeIt e makePayment. Alm disso, conveniente incluir mtodos de ao, que com freqncia definem as aes especficas do comportamento do objeto. Para demonstrar isso, define-se um mtodo de ao, o printCard, como um mtodo esttico, que tambm est includo no Trecho de cdigo 1.5.

A classe test
A classe CreditCard testada na classe Test. Observa-se aqui o uso de um arranjo de objetos CreditCard, wallet, e como se usam iteraes para fazer dbitos e pagamentos. Apresenta-se o cdigo completo da classe Test no Trecho de cdigo 1.6. Para simplificar, a classe Test no produz nenhum grfico elaborado, simplesmente envia a sada para o console de Java. Apresenta-se esta sada no Trecho de cdigo 1.7. Observa-se a diferena na maneira em que se utilizam os mtodos no-estticos chargeIt e makePayment e o mtodo esttico printCard.
public class CreditCard { // Variveis de instncia: private String number; private String name; private String bank; private double balance; private int limit; // Construtor: CreditCard(String no, String nm, String bk, double bal, int lim) { number no; name nm; bank bk; balance bal; limit lim; } // Mtodos de acesso: public String getNumber( ) { return number; } public String getName( ) { return name; } public String getBank( ) { return bank; } public double getBalance( ) { return balance; } public int getLimit( ) { return limit; } // Mtodos de ao: public boolean chargeIt(double price) { // Debita if (price + balance (double) limit) return false; // No h dinheiro suciente para debitar balance += price; return true; // Neste caso o dbito foi efetivado }

Conceitos Bsicos de Programao Java


public void makePayment(double payment) { // Faz um pagamento balance = payment; } public static void printCard(CreditCard c) { // Imprime informaes sobre o carto System.out.println("Number = " + c.getNumber( )); System.out.println("Name = " + c.getName( )); System.out.println("Bank = " + c.getBank( )); System.out.println("Balance = " + c.getBalance( )); // converso implcita System.out.println("Limit = " + c.getLimit( )); // converso implcita } }

57

Trecho de cdigo 1.5

A classe CreditCard.

public class Test { public static void main(String[ ] args) { CreditCard wallet[ ] = new CreditCard[10]; wallet[0] new CreditCard("5391 0375 9387 5309", "John Bowman", "California Savings", 0.0, 2500); wallet[1] new CreditCard("3485 0399 3395 1954", "John Bowman", "California Federal", 0.0, 3500); wallet[2] new CreditCard("6011 4902 3294 2994", "John Bowman", "California Finance", 0.0, 5000); for (int i 1; i 16; i ){ wallet[0].chargeIt((double)i); wallet[1].chargeIt(2.0*i); // converso implcita wallet[2].chargeIt((double)3*i); // converso explcita } for (int i 0; i 3; i ){ CreditCard.printCard(wallet[i]); while (wallet[i].getBalance( ) 100.0) { wallet[i].makePayment(100.0); System.out.println("New balance = " wallet[i].getBalance( )); } } } }

Trecho de cdigo 1.6


Number 5391 0375 9387 5309 Name John Bowman Bank California Savings Balance 136.0 Limit 2500 New balance 36.0 Number 3485 0399 3395 1954 Name John Bowman Bank California Federal Balance 272.0 Limit 3500 New balance 172.0 New balance 72.0

A classe Test.

58

Estruturas de Dados e Algoritmos em Java


Number 6011 4902 3294 2994 Name John Bowman Bank California Finance Balance 408.0 Limit 5000 New balance 308.0 New balance 208.0 New balance 108.0 New balance 8.0

Trecho de cdigo 1.7

Sada da classe Test.

1.8

Classes aninhadas e pacotes


A linguagem Java usa uma abordagem prtica e genrica para organizar as classes de um programa. Toda a classe pblica definida em Java deve ser fornecida em um arquivo separado. O nome do arquivo o nome da classe com uma terminao .java. Desta forma, a classe public class SmartBoard, definida em um arquivo chamado SmartBoard.java. Nesta seo, so apresentadas duas maneiras interessantes pelas quais Java permite que vrias classes sejam organizadas.

Classes aninhadas
Java permite que definies de classes sejam feitas dentro, isto , aninhadas dentro das definies de outras classes. Este um tipo de construo til que ser explorada diversas vezes neste livro na implementao de estruturas de dados. O uso principal de classes aninhadas para definir uma classe fortemente conectada com outra. Por exemplo, a classe de um editor de textos pode definir uma classe cursor relacionada. Definindo a classe cursor como classe aninhada dentro da definio da classe editor, mantm-se a definio destas duas classes altamente relacionadas juntas no mesmo arquivo. Alm disso, permite que ambas acessem os mtodos pblicos uma da outra. Um aspecto tcnico relacionado a classes aninhadas que classes aninhadas podem ser declaradas como static. Esta declarao implica que a classe aninhada est associada com a classe mais externa, mas no com uma instncia da classe mais externa, isto , um objeto especfico.

Pacotes
Um conjunto de classes relacionadas, todas pertencentes ao mesmo subdiretrio, pode ser um package (pacote) Java. Cada arquivo em um pacote se inicia com a linha:
package nome_do_pacote;

O subdiretrio que contm o pacote deve ter o mesmo nome que o pacote. possvel, tambm, definir um pacote em um nico arquivo que contenha diversas definies de classe, mas quando for compilado, todas as classes o sero em arquivos separados no mesmo subdiretrio. Em Java, pode-se usar classes que esto definidas em outros pacotes prefixando os nomes das classes com pontos (isto , usando o caractere .) que corresponde estrutura de diretrio dos outros pacotes.
public boolean Temperature(TA.Measures.Thermometer thermometer, int temperature) { // ... }

Conceitos Bsicos de Programao Java

59

A funo Temperature recebe a classe Thermometer como parmetro. Thermometer definida no pacote TA, em um subpacote chamado Measures. Os pontos em TA.Measures.Thermometer tm correspondncia direta com a estrutura de diretrio do pacote TA. Toda a digitao necessria para fazer referncia a uma classe fora do pacote corrente podese tornar cansativa. Em Java, possvel usar a palavra reservada import para incluir classes externas ou pacotes inteiros no arquivo corrente. Para importar uma classe individual de um pacote especfico, digita-se no incio do arquivo o seguinte:
import nome_do_pacote.nome_da_classe;

Por exemplo, pode-se digitar


package Project; import TA.Measures.Thermometer; import TA.Measures.Scale;

no incio do pacote Project para indicar que se est importando as classes TA.Measures.Thermometer e TA.Measures.Scale. O ambiente de execuo de Java ir procurar essas classes para verificar os identificadores com as classes, mtodos e variveis de instncia que se usa no programa. Tambm se pode importar um pacote inteiro utilizando a seguinte sintaxe:
import packageName.*;

Por exemplo:
package student; import TA.Measures.*; public boolean Temperature(Thermometer thermometer, int temperature) { // ... }

Nos casos em que dois pacotes tm classes com o mesmo nome, deve-se referenciar especificamente o pacote que contm a classe. Por exemplo, supondo que ambos os pacotes Gnomes e Cooking tenham uma classe chamada Mushroom (cogumelo). Se for determinado um comando import para cada pacote, deve-se especificar que classe se quer designar:
Gnomes.Mushroom shroom Cooking.Mushroom topping new Gnomes.Mushroom ("purple"); new Cooking.Mushroom ( );

Se no for especificado o pacote (ou seja, no exemplo anterior apenas foi empregada uma varivel do tipo Mushroom), o compilador ir sinalizar um erro de classe ambgua. Resumindo a estrutura de um programa Java, pode-se ter variveis de instncia e mtodos dentro de uma classe, alm de classes dentro de um pacote.

1.9

Escrevendo um programa em Java


O processo de escrever um programa em Java envolve trs etapas fundamentais: 1. projeto, 2. codificao, 3. teste e depurao. Cada uma ser resumida nesta seo.

60

Estruturas de Dados e Algoritmos em Java

1.9.1

Projeto
A etapa de projeto talvez o passo mais importante no processo de escrever um programa. na fase de projeto que se decide como dividir as tarefas do programa em classes, como essas classes iro interagir com os dados que iro armazenar e que aes cada uma ir executar. Um dos maiores desafios com o qual os programadores iniciantes se deparam em Java determinar que classes definir para executar as tarefas do seu programa. Ainda que seja difcil obter prescries genricas, existem algumas regras prticas que podem ser aplicadas quando se est procurando definir as classes: Responsabilidades: dividir o trabalho entre diferentes atores, cada um com responsabilidades diferentes. Procurar descrever as responsabilidades usando verbos de ao. Os atores iro formar as classes do programa. Independncia: definir, se possvel, o trabalho de cada classe de forma independente das outras classes. Subdividir as responsabilidades entre as classes de maneira que cada uma tenha autonomia sobre algum aspecto do programa. Fornecer os dados (como variveis de instncia) para as classes que tm competncia sobre as aes que requerem acesso a esses dados. Comportamento: as conseqncias de cada ao executada por uma classe tero de ser bem compreendidas pelas classes que interagem com ela. Portanto, preciso definir o comportamento de cada uma com cuidado e preciso. Esses comportamentos iro definir os mtodos que a classe executa. O conjunto de comportamentos de uma classe algumas vezes chamado de protocolo, porque espera-se que os comportamentos de uma classe sejam agrupados como uma unidade coesa. A definio das classes juntamente com seus mtodos e variveis de instncia determina o projeto de um programa Java. Um bom programador, com o tempo, vai desenvolver naturalmente grande habilidade em executar essas tarefas medida que a experincia lhe ensinar a observar padres nos requisitos de um programa que se parecem com padres j vistos.

1.9.2

Pseudocdigo
Freqentemente, programadores so solicitados a descrever algoritmos de uma maneira que seja compreensvel para olhos humanos, em vez de escrever um cdigo real. Tais descries so chamadas de pseudocdigo. Pseudo-cdigo no um programa de computador, mas mais estruturado que a prosa normal. Pseudo-cdigo uma mistura de lngua-natural com estruturas de programao de alto-nvel que descrevem as idias principais que esto por trs da implementao de uma estrutura de dados ou algoritmo. No existe, portanto, uma definio precisa de uma linguagem de pseudocdigo, em razo de sua dependncia da lngua natural. Ao mesmo tempo, para auxiliar na clareza, o pseudo-cdigo mistura lngua natural com construes de padro de linguagens de programao. As construes que foram escolhidas so consistentes com as modernas linguagens de alto nvel, tais como C, C++ e Java. Estas construes incluem: Expresses: usam-se smbolos matemticos padro para expresses numricas e booleanas. Usa-se a seta para esquerda () como operador de atribuio em comandos de atribuio (equivalente ao operador de Java) e o sinal de igual ( ) para o relacional de igualdade em expresses booleanas (equivalente ao relacional em Java). Declaraes de mtodos: Algoritmo nome(param1, param2, ... ) declara um nome de mtodo novo e seus parmetros.

Conceitos Bsicos de Programao Java

61

Estruturas de deciso: se condio, ento aes caso verdade [seno, aes caso falso]. Usa-se identao para indicar quais aes devem ser includas nas aes caso verdade e nas aes caso falso. Laos enquanto: enquanto condio, faa aes. Usa-se indentao para indicar quais aes devem ser includas no lao. Laos repete: repete aes at condio. Usa-se indentao para indicar que aes devem ser includas no lao. Laos for: for definio de varivel de incremento, faa aes. Usa-se identao para indicar que aes devem ser includas no lao. Indexao de arranjos: A[i] representa a i-sima clula do arranjo A. As clulas de um arranjo A com n clulas so indexadas de A[0] at A[n 1] (de forma consistente com Java). Chamadas de mtodos: objeto.mtodo(argumentos) (objeto opcional se for subentendido). Retorno de mtodos: retorn valor. Esta operao retorna o valor especificado para o mtodo que chamou o mtodo corrente. Comentrios: { os comentrios vo aqui }. Os comentrios so colocados entre chaves. Quando se escreve pseudo-cdigo, deve-se ter em mente que se est escrevendo para um leitor humano, no para um computador. Assim, o esforo deve ser no sentido de comunicar idias de alto-nvel, e no detalhes de implementao. Ao mesmo tempo, no se deve omitir passos importantes. Como em muitas outras formas de comunicao humana, encontrar o balanceamento correto uma habilidade importante, que refinada pela prtica.

1.9.3

Codificao
Como mencionado anteriormente, um dos passos-chave na codificao de um programa orientado a objetos codificar a partir de descries de classes e seus respectivos mtodos. Para acelerar o desenvolvimento dessa habilidade, sero estudados, em diferentes momentos ao longo deste texto, vrios padres de projeto para os projetos de programas orientados a objeto (ver Seo 2.1.3). Esses padres fornecem moldes para a definio de classes e interaes entre essas classes. Muitos programadores no fazem seus projetos iniciais em um computador, e sim usando cartes CRC. Componente-responsabilidade-colaborador, ou CRC, so simples cartes indexados que subdividem as tarefas especificadas para um programa. A idia principal por trs desta ferramenta que cada carto represente um componente, o qual, no final, se transformar em uma classe de nosso programa. Escreve-se o nome do componente no alto do carto. No lado esquerdo do mesmo, anotam-se as responsabilidades desse componente. No lado direito, listamse os colaboradores desse componente, isto , os outros componentes com os quais o primeiro ter de interagir de maneira a cumprir suas finalidades. O processo de projeto iterativo atravs de um ciclo ao/ator, onde primeiro se identifica uma ao (ou seja, uma responsabilidade) e, ento, se determina o ator (ou seja, um componente) mais adequado para executar tal ao. O processo de projeto est completo quando se tiver associado atores para todas as aes. A propsito, ao utilizar cartes indexados para executar nosso projeto, assume-se que cada componente ter um pequeno conjunto de responsabilidades e colaboradores. Esta premissa no acidental, uma vez que auxilia a manter os programas gerenciveis. Uma alternativa ao uso dos cartes CRC o uso de diagramas UML (Linguagem de Modelagem Unificada*) para expressar a organizao de um programa e pseudo-cdigo para expressar algoritmos. Diagramas UML so uma notao visual padro para expressar projetos orientados a

* N. de T. Unified Modeling Language.

62

Estruturas de Dados e Algoritmos em Java


objetos. Existem muitas ferramentas auxiliadas por computador capazes de construir diagramas UML. A descrio de algoritmos em pseudo-cdigo, por outro lado, uma tcnica que ser utilizada ao longo deste livro. Tendo decidido sobre as classes de nosso programa, juntamente com suas responsabilidades, pode-se comear a codificao. Cria-se o cdigo propriamente dito das classes do programa usando tanto um editor de textos independente (por exemplo emacs, WordPad ou vi) como um editor embutido em um ambiente integrado de desenvolvimento (IDE*), tal como o Eclipse ou o Borland JBuilder. Aps completar a codificao de uma classe (ou pacote), se compila o arquivo para cdigo executvel usando um compilador. Quando no se est usando um IDE, ento se compila o programa chamando um programa tal como javac sobre o arquivo. Estando em uso um IDE, ento se compila o programa clicando o boto apropriado. Felizmente se o programa no tiver erros de sintaxe, ento o processo de compilao ir criar arquivos com a extenso .class. Se o programa contiver erros de sintaxe, estes sero identificados, e se ter de voltar ao editor de textos para consertar as linhas de cdigo com problema. Eliminados todos os erros de sintaxe e criado o cdigo compilado correspondente, pode-se executar o programa tanto chamando um comando, tal como java (fora de um IDE), ou clicando o boto de execuo apropriado (dentro de um IDE). Quando um programa Java estiver executando dessa forma, o ambiente de execuo localiza os diretrios contendo as classes criadas e quaisquer outras referenciadas a partir destas, usando uma varivel especial de ambiente do sistema operacional. Essa varivel chamada de CLASSPATH, e a ordem dos diretrios a serem pesquisados fornecida como uma lista de diretrios, separados por vrgulas se em Unix/Linux ou por ponto-e-vrgulas se em DOS/Windows. Um exemplo de atribuio para a varivel CLASSPATH no sistema operacional DOS/Windows pode ser o seguinte:
SET CLASSPATH=.;C:\java;C:\Program Files\Java\

Um exemplo de atribuio para CLASSPATH no sistema operacional Unix/Linux pode ser:


setenv CLASSPATH ".:/usr/local/java/lib:/usr/netscape/classes"

Em ambos os casos, o ponto (.) se refere ao diretrio atual a partir do qual o ambiente de execuo foi chamado.

Javadoc
Para incentivar o bom uso de comentrios em bloco e a produo automtica de documentao, o ambiente de programao Java vem com um programa para a gerao de documentao chamado javadoc. Esse programa examina uma coleo de arquivos fontes Java que tenham sido comentados usando-se certas palavras reservadas, chamadas de tags, e produz uma srie de documentos HTML que descrevem as classes, mtodos, variveis e constantes contidas nestes arquivos. Por razes de espao, no se usa o estilo de comentrios do javadocs em todos os programas exemplificadores contidos neste livro, mas se incluiu um exemplo de javadoc no Trecho de cdigo 1.8, bem como em outros disponveis no site da Web que acompanha este livro. Cada comentrio javadoc um comentrio em bloco que se inicia com /**, termina com */ e tem cada linha entre estas duas iniciada por um nico asterisco, * que ignorado. Pressupe-se que o bloco de comentrio deve comear com uma frase descritiva seguida por uma linha em branco, e posteriormente por linhas especiais que comeam por tags javadoc. Um comentrio em bloco que venha imediatamente antes de uma definio de classe, uma declarao de varivel ou uma definio de mtodo processado pelo javadoc em um comentrio que se refere classe, varivel ou ao mtodo.
* N. de T. A abreviatura, j consagrada, corresponde expresso em ingls integrated development environment.

Conceitos Bsicos de Programao Java


/** * Esta classe dene um ponto (x,y) no altervel no plano

63

* * @author Michael Goodrich */


public class XYPoint { private double x,y; // variveis de instncia privada para as coordenadas /** * Constri um ponto (x,y) em uma localizao especca

* * @param xCoor A abscissa do ponto * @param yCoor A ordenada do ponto */


public XYPoint(double xCoor, double yCoor) { x = xCoor; y = yCoor; } /** * Retorna o valor da abscissa

* * @return abscissa */
public double getX( ) { return x; } /** * Retorna o valor da ordenada

* * @return ordenada */
public double getY( ) { return x; } }

Trecho de cdigo 1.8 Um exemplo de definio de classe usando o estilo javadoc de comentrio. Observa-se que esta classe inclui apenas duas variveis de instncia, um construtor e dois mtodos de acesso. As tags javadoc mais importantes so as seguintes: @author texto: identifica os autores (um por linha) de uma classe; @exception descrio do nome de uma exceo: identifica uma condio de erro sinalizada por este mtodo (ver Seo 2.3); @param descrio de um nome de parmetro: identifica um parmetro aceito por este mtodo; @return descrio: descreve o tipo de retorno de um mtodo e seu intervalo de valores. Existem outras tags como estas; o leitor interessado deve consultar a documentao online do javadoc para um estudo mais aprofundado.

Clareza e estilo
possvel fazer programas fceis de ler e entender. Bons programadores devem, portanto, ser cuidadosos com seu estilo de programao, desenvolvendo-o de forma a comunicar os aspectos importantes do projeto de um programa tanto para os usurios como para os computadores.

64

Estruturas de Dados e Algoritmos em Java


Alguns dos princpios mais importantes sobre bons estilos de programao so os seguintes: Usar nomes significativos para identificadores. Devem-se escolher nomes que possam ser lidos em voz alta, que reflitam a ao, a responsabilidade ou os dados que o identificador est nomeando. A tradio na maioria dos crculos de Java usar maisculas na primeira letra de cada palavra que compem um identificador, excetuando-se a primeira palavra de identificadores de variveis ou mtodos. Ento, segundo esta tradio, Date, Vector, DeviceManage identificam classes e isFull( ), insertItem( ), studentName e studentHeigth referem-se, respectivamente, a mtodos e a variveis. Usar constantes ou tipos enumerados em vez de valores. A clareza, a robustez e a manuteno sero melhoradas se forem includos uma srie de valores constantes em uma definio de classe. Estes podero ento ser usados nesta e em outras classes para fazer referncia a valores especiais desta classe. A tradio Java usar apenas maisculas em tais constantes, como mostrado abaixo:
public class Student { public static final int MIN_CREDITS 12; // crditos mnimos por perodo public static final int MAX_CREDITS 24; // crditos mximos por perodo public static final int FRESHMAN 1; // cdigo de calouro public static final int SOPHOMORE 2; // cdigo de aluno do primeiro ano public static final int JUNIOR 3; // cdigo para jnior public static final int SENIOR 4; // cdigo para snior // denies de variveis de instncia, construtores e mtodos seguem aqui... }

Indentar os blocos de comandos. Os programadores normalmente indentam cada bloco de comandos com quatro espaos; neste livro, entretanto, usam normalmente dois espaos, para evitar que o cdigo extravase as margens do livro. Organizar as classes conforme a seguinte ordem: 1. 2. 3. 4. constantes, variveis de instncia, construtores, mtodos.

Alguns programadores Java preferem colocar as declaraes de variveis de instncia por ltimo. Aqui, opta-se por coloc-las antes, de forma que se possa ler cada classe seqencialmente, compreendendo os dados com que cada mtodo est lidando. Usar comentrios para acrescentar significado ao programa e explicar construes ambguas ou confusas. Comentrios de linha so teis para explicaes rpidas e no precisam ser frases completas. Comentrios em bloco so teis para explicar os propsitos de um mtodo ou as sees de cdigo complicadas.

1.9.4

Teste e depurao
Teste o processo de verificar a correo de um programa; depurao o processo de seguir a execuo de um programa para descobrir seus erros. Teste e depurao so, em geral, as atividades que mais consomem tempo durante o desenvolvimento de um programa.

Conceitos Bsicos de Programao Java

65

Teste
Um plano de testes cuidadoso parte essencial da escrita de um programa. Apesar de a verificao da correo de um programa para todas as entradas possveis ser normalmente impraticvel, pode-se privilegiar a execuo do programa a partir de subconjuntos representativos das entradas. Na pior das hipteses, deve-se ter certeza de que cada mtodo do programa tenha sido testado pelo menos uma vez (cobertura de mtodo). Melhor ainda, cada linha de cdigo do programa deve ser executada pelo menos uma vez (cobertura de comandos). Em geral, as entradas dos programas falham em casos especiais. Tais casos precisam ser cuidadosamente identificados e testados. Por exemplo, quando se testa um mtodo que ordena (isto , coloca em ordem) um arranjo de inteiros, deve-se considerar as seguintes entradas: se o arranjo tiver tamanho zero (nenhum elemento); se o arranjo tiver um elemento; se todos os elementos do arranjo forem iguais; se o arranjo j estiver ordenado; se o arranjo estiver ordenado na ordem inversa.

Alm das entradas especiais para o programa, deve-se tambm analisar condies especiais para as estruturas usadas pelo programa. Por exemplo, usando-se um arranjo para armazenar dados, preciso ter certeza de que os casos-limite, tais como a insero/remoo no incio ou no fim do arranjo que armazena os dados, esto sendo convenientemente tratados. Se essencial usar conjuntos de testes definidos manualmente, tambm fundamental executar o programa a partir de grandes conjuntos de dados gerados randomicamente. A classe Random do pacote java.util oferece vrios mtodos para a gerao de nmeros randmicos. Existe uma hierarquia entre as classes e mtodos de um programa, induzida pelas relaes de ativador-ativado. Isto , um mtodo A est acima de um mtodo B na hierarquia, se A chamar B. Existem duas estratgias de teste principais, top-down e bottom-up, que diferem na ordem em que os mtodos so testados. O teste bottom-up executado desde mtodos de mais baixo nvel at os de mais alto nvel. Ou seja, mtodos de mais baixo nvel que no ativam outros mtodos so testados primeiro, seguidos pelos mtodos que chamam apenas um mtodo de baixo nvel, e assim por diante. Esta estratgia garante que os erros encontrados em um mtodo nunca so causados por um mtodo de nvel mais baixo aninhado no mesmo. O teste bottom-up executado do topo para a base da hierarquia de mtodos. Normalmente usado em conjunto com terminadores, uma tcnica de rotina de inicializao que substitui mtodos de mais baixo nvel por um tampo*, um substituto para o mtodo que simula a sada do mtodo original. Por exemplo, se o mtodo A chama o mtodo B para pegar a primeira linha de um arquivo, quando se testa A pode-se substituir B por um tampo que retorna uma string fixa.

Depurao
A tcnica mais simples de depurao consiste em usar comandos de impresso (usando o mtodo System.out.println(string)) para rastrear os valores das variveis durante a execuo do programa. Um problema desta abordagem que os comandos de impresso, por vezes, necessitam ser removidos ou comentados antes de o programa poder ser executado. Uma melhor abordagem executar o programa com um depurador, que um ambiente especializado para controlar e monitorar a execuo de um programa. A funcionalidade bsica

* N. de T. Em ingls, stub.

66

Estruturas de Dados e Algoritmos em Java


oferecida por um depurador a insero de pontos de parada* no cdigo. Quando um programa executado com um depurador, ele interrompe a cada ponto de parada. Enquanto o programa est parado, o valor corrente das variveis pode ser verificado. Alm de pontos de parada fixos, depuradores mais avanados permitem a especificao de pontos de parada condicionais, que so disparados apenas se uma determinada condio for satisfeita. As ferramentas-padro de Java incluem um depurador bsico chamado jdb, controlado por linhas de comando. Os IDEs para programao em Java oferecem ambientes de depurao avanados com interface grfica com o usurio.

1.10

Exerccios

Para obter ajuda e o cdigo fonte dos exerccios, visite java.datastructures.net.

Reforo
R-1.1 Suponha que seja criado um arranjo A de objetos GameEntry, que possui um campo inteiro scores, e que A seja clonado e o resultado seja armazenado em um arranjo B. Se o valor de A[4].score for imediatamente alterado para 550, qual o valor do campo score do objeto GameEntry referenciado por B[4]? Modifique a classe CreditCard do Trecho de cdigo 1.5 de maneira a debitar juros em cada pagamento. Modifique a classe CreditCard do Trecho de cdigo 1.5 de maneira a debitar uma taxa por atraso para qualquer pagamento feito aps a data de vencimento. Modifique a classe CreditCard do Trecho de cdigo 1.5 para incluir mtodos modificadores que permitam ao usurio modificar variveis internas da classe CreditCard de forma controlada. Modifique a declarao do primeiro lao for da classe Test do Trecho de cdigo 1.6 de maneira que os dbitos possam, mais cedo ou mais tarde, fazer com que um dos trs cartes ultrapasse seu limite de crdito. Qual esse carto? Escreva uma pequena funo em Java, inputAllBaseTypes que recebe diferentes valores de cada um dos tipos base na entrada padro e o imprime de volta no dispositivo de sada padro. Escreva uma classe Java, Flower, que tenha trs variveis de instncia dos tipos String, int e float representando, respectivamente, o nome da flor, seu nmero de ptalas e o preo. A classe pode incluir um construtor que inicialize cada varivel adequadamente, alm de mtodos para alterar o valor de cada tipo e recuperar o valor de cada tipo. Escreva uma pequena funo em Java, isMultiple, que recebe dois valores long, n e m, e retorna true se e somente se n mltiplo de m, isto , n mi para algum inteiro i. Escreva uma pequena funo Java isOdd, que recebe um int i e retorna true se e somente se i par. Entretanto, esta funo no pode usar operadores de multiplicao, mdulo ou diviso.

R-1.2 R-1.3

R-1.4

R-1.5

R-1.6

R-1.7

R-1.8

R-1.9

* N. de T. Em ingls, breakpoints.

Conceitos Bsicos de Programao Java


R-1.10 R-1.11

67

Escreva uma pequena funo em Java que receba um inteiro n e retorne a soma de todos os inteiros menores que n. Escreva uma pequena funo em Java que receba um inteiro n e retorne a soma de todos os inteiros pares menores que n.

Criatividade
C-1.1 C-1.2 Escreva uma pequena funo Java que recebe um arranjo de valores int e determina se existe um par de nmeros no arranjo cujo produto seja par. Escreva um mtodo Java que recebe um arranjo de valores int e determina se todos os nmeros so diferentes entre si (isto , se so valores distintos). Escreva um mtodo em Java que receba um arranjo contendo o conjunto de todos os inteiros no intervalo de 1 a 52 e embaralhe os mesmos de forma aleatria. O mtodo deve exibir as possveis seqncias com igual probabilidade. Escreva um pequeno programa em Java que exiba todas as strings possveis de serem formadas usando os caracteres c, a, r, b, o e n apenas uma vez. Escreva um pequeno programa em Java que receba linhas de entrada pelo dispositivo de entrada padro, e escreva as mesmas no dispositivo de sada padro na ordem contrria. Isto , cada linha exibida na ordem correta, mas a ordem das linhas invertida. Escreva um pequeno programa em Java que receba dois arranjos a e b de tamanho n que armazenam valores int e retorne o produto escalar de a por b. Isto , retorna um arranjo c de tamanho n onde c[i] a[i] b[i], para i 0,...,n 1.

C-1.3

C-1.4

C-1.5

C-1.6

Projetos
P-1.1 Uma punio comum para alunos de escola escrever a mesma frase vrias vezes. Escreva um programa executvel em Java que escreva a mesma frase uma centena de vezes: Eu no mandarei mais spam para meus amigos. Seu programa deve numerar as frases e acidentalmente fazer oito erros aleatrios diferentes de digitao. (Para aqueles que conhecem os mtodos de interface grfica com o usurio em Java.) Defina uma classe GraphicalTest que teste a funcionalidade da classe CreditCard do Trecho de cdigo 1.5, usando campos de entrada de texto e botes. O paradoxo do aniversrio diz que a probabilidade de duas pessoas em uma sala terem a mesma data de aniversrio maior que 50% desde que n, o nmero de pessoas na sala, seja maior que 23. Esta propriedade no realmente um paradoxo, mas muitas pessoas se surpreendem. Projete um programa em Java que possa testar esse paradoxo por uma srie de experimentos sobre aniversrios gerados aleatoriamente, testando o paradoxo para n 5, 10, 15, 20, ..., 100.

P-1.2

P-1.3

68

Estruturas de Dados e Algoritmos em Java

Observaes sobre o captulo


Para mais informaes sobre a linguagem de programao Java, indicamos ao leitor alguns dos melhores livros de Java: Arnold e Gosling [7], Campione e Walrath [19], Cornell e Horstmann [26], Flanagan [34] e Horstmann [51], assim como a pgina de Java da Sun (http://www. java.sun.com).