Você está na página 1de 480

Elogios ao Guia de estudos para programador e desenuoluedor em Jaua 2 certif cado pela S an@

"Kathy Sierra 6 uma das poucas pessoas no mundo que consegue fazer coisas complicadas parecerem murto simple;. E
como se isso nio fosse suficiente, ela consegue fazer com que assuntos mon6tonos paregam interessantes. Sempre fico
ansioso para ler o que Kathy escreve - ela 6 uma de minhas autoras favoritas".
- Paul IYheaton, Chefe de Aconpanbamento da JauaRanch.com

"Quem melhor para escrever um guia de estudos sobre Java do que Kathy Si_err.a, que reina soberana quando se trata de
treLamento emlava? Kathy Sierr-a conseguiu novamente - aqui est6 um guia de estudos que j6 poder6 lhe garantir a
cenifica$o!"
- Jamu Cabeta, Engenheiro de Sistenaq SCI

"O que mais aprecio em Kathy 6 seu esforEo p arafaznr comque todosnos lembremos de que estamos ensinando pessoas
. nio aoenas fa"endo uma palestra sobre Tava. Seu entusiasmo e vontade em oferecer um treinamento da mais alta
ffi;#i. frffi;; #.##T; ;;;, ;;;
i; -
.. rreza nio encontra paralelo na sunEd. s.* a""iar, h6 centenas de I

alunos que beneficiaram


se terem assistido
de a suas aulas" . i
,1

q
- Victor Peters, fandador da Next Snp Education e Inslrutor Certifcado Jaua pela Sun

"Quero agradecer Kathy pelo EXCELENTE guia de esudos. O livro 6 bem.escrito,.informa especificamente o que voc6
a
aJq. ri'U.r.ro.*"-..."d,conceito 6 explicaio de maneiraclaracom autilizagio deum exemplo davidareal' Da
**Jira sentir6 em uma sala de aula como se algu6m estivesse realmente lhe ensinando os conceitos
orr. foi escrito, voc6 se

diiil;;; e fria. As perguntas no final dos capftulos tamb€m slo MUTIo boas e estou certo de
maneiraformal
"ilde
que aju&rio os candidatos a passarem no tesi. Fique alerta para esse livro incrivelmente astuto".
- Atfred RaouJ Desenuoluedor de Solugdu na IYeb
i

O exame de certificagio da Sun cerramente nio foi como um passeio no parque' mas o material de Kathy permitiu nio s6
que eu Passasse no exame, mas que passasse bem!"
- Mary lqhetsel, Etpecial^ta S1nior em Tecnologla, Integragdo e Estrategla de Aplicagdes, Tbc St. Paal Corapaniet

"Ben demonstra uma aptidio comprovada e fantistica de transformar com-plexidade em simplicidade ao oferecer um
percurso dirigido no aprendizado do que 6 necessirio para o exame da certificaqXo".

- Thomas Bende6 Presidente, Gold Hi// Sofnaare Desing, Inc'

"por habilidade em expressar claramente conceitos complexos aos que assistem


sua a seus treinamentos' todos os alunos
cons€guem se tornar especialistas no que Ben tem a ensinar".
- DauidNdgq Diretor Geral, Ndge Astociatet

"Achei este livro exrremamente 6til para ajudar o candidato a passar no exame. Ele foi muito bem escrito, com a qtrantidade
ideal de come"."ri"r b.*-ftJ-oi p"At*r. .or' qrr. .'oo.? se esquega de que est6 estudando Para um teste tio dificil'
^Cit
ALTAMENTE RECOMENDADO!"
-Nico/e Y. McCallough

*Nunca me diveni tanto lendo um livro r6cnico quanto no caso deste aqui... Hoje de manhi, fiz o exame SCJP e consegu,i
ecertar 980/o(60 de 61). Esse sucesso nio teria sido possivel sem este livro!"
-Yaie Nagornl

,,EvfizoSCJp emJulho de 2004 e consegui 957o (58/.6l).Kathy e Ben t6m um estilo incrivel de escrever'
1.4
e

literdmente-grav"ra- ot.o.t..itos principais na minha cabega."


-Bhsshen P. Madan (Kansas, Estadot Uildos)

(
"Eu fiz meu teste de certificagio semana passada e fui aprovado com 95o/o de acertos. Se nio tivesse estudado por este livro,
teria poucas chances de obter um resultado tio bom. Obrigado, Kathy e Bert, pelo maravilhoso livro!"

-lon W. Knsting (Smatoga, Califomia, Estadot Unidos)

"Nio hesite em fazer deste livro o seu principal guia para preparar-se para o SCJP 1.4. Os autores fizeram um trabalho
magnifico ao apresentar os fatos imponantei qe pricisar6 sabei para o exame, ao mesmo rempo deixaram de lado
"oc6
toneladas de outras informag6es que,em outro contextb, seriam importantes, mas que vlo al6m do escopo deste livro.
Ambos os autores participaram da criagio das quest6es reais do exame, fornecendo iessa forma um valiosissimo insight
sobre a verdadeira natureza do que vocA.encontrari no exame. Ao contririo de muitos outros guias de cenificagio. Esti aqui
6 uma leitura p razerosa. Neste livro, at6 os mais enfadonhos objetivos da Sun sio combinadoi com um revigo.*t. bo.ri-
humor."

-Vad Fogel (Onlaia, Canadi.l


Ceftificagdo Sun@ para
Programador fAVA 5
Guia de Estudo
(tuame 310-055)

lGthy Sierra
Bert Bates
tv
Certilicagiio Sun@ para Programador Java 5- Guia de Estudo @xame 310-055)

Do original Sun@ Certified Programmer for JavarM 5 Study Guide (Exam 3 I 0-05 5) - Copyright @ 2006 da Editora Alta Books Ltda.
Authorized translation from the English language edition, entitled Sun@ Certified Programmer for JavarM 5 Srudy Guide (Exam
310-055), by Sierra & Bates, published by Osborne/MacGraw-Hill, publishing as The MacGraw-Hill Companies, Copyright @
2006 by Osborne/MacGra,v-Hill.

PORTUGUESE language edition published by Editora Alta Bool<s, Copyright @ 2006 by Editora Alta Bool{s.

Todos os direitos reservados e protegidos pela Lei 5988 de I4ll2l73. Nenhuma parte deste livro, sem autorizagdo pr6via por escrito
da editora, poderS ser reproduzida ou transmitida sejam quais forem os meios empregados: eletr6nico, mecanico, fotogr6fico, gravag5o
ou quaisquer outros.

Todo o esforgo foi feito para fornecer a mais completa e adequada informagdo, contudo a(s) editora(s) e o(s) autor(es) nAo assumem
responsabilidade pelos resultados e usos da informagdo fornecida. Recomendamos aos leitores testar a informagdo bem como tomar
todos os cuidados necess6rios (como o backup), antes da efetiva fiilizagdo. Este livro n6o contdm CD-ROM, disquete ou qualquer
outramidia.
Produgiio Editorial: Editora Alta Books
Coordenagflo Editorial: Fernanda Silveira
Thadugiio: Marcelo Soares
Revis6o: Fernanda Silveira
RevisEo T6cnica: Leonardo Rota-Rossi
Colaboragflo T6cnica: Gabriel Fairbanks, Leonardo Gangemi eAnderson Xavier
Diagramagiio : Aldenir Gil
Erratas e atualizag6es: Sempre nos esforgamos para entregar a voc6 leitor um livro livre de erros t6cnicos ou de conteido, por6m nem
sempre isto 6 conseguido, seja por motivo de alteragilo de software, interpretagdo ou mesmo quando alguns deslizes constam na
versdo original de alguns livros que traduzimos. Sendo assim, criamos em nosso site www.altabooks.com.br a seg6o Erratas, onde
relataremos, com a devida corregSo, qualquer erro encontrado em nossos livros.

Aviso e Renfncia: Este livro 6 vendido como est6, sem garantia de qualquer tipo, seja expressa ou implicita.

Marcas Registradas: Todos os termos mencionados e reconhecidos como Marca Registrada e/ou comercial sdo de responsabilidade
de seus proprietiirios. A Editora informa n6o esfar associada a nenhum produto e/ou fomecedor apresentado no livro. No decorrer
da obra, imagens, nomes de produtos e fabricantes podem ter sido utilizados e desde j5 a Editora informa que o uso 6 apenas
ilustrativo e/ou educativo, ndo visando lucro, favorecimento ou desmerecimento do produto/fabricante.

O c6digo de propriedade intelectual de l'de Julho de 1992 proibe expressamente o uso coletivo sem autorizagdo dos detentores
do direito autoral da obra, bem como a c6pia ilegal do original. Esta pratica generalizada nos estabelecimentos de ensino
provocam uma brutal bqixa nqs vendas dos livros ao ponto de impossibilitar os autores de criarem novas obras.

A McGraw-Hill/Osborne d uma entidade sem ligaEdes com a Sun Microsystems e ndo tem nenhum vinculo de afiliaqdo com a
illtima. Essa publicaqdo pode ser usada como auxllio na prepqraqdo dos alunos para o exame de certificagdo da Sun em
Java 2. Nem a Sun Microsystems ou a McGraw-Hill/Osborne garqntem que o uso dessa publicagdo assegurard sucesso no
exame em questdo. Sun, Sun Microsystems e o logotipo da Sun sdo marcas registradas da Sun Microsystems.Inc. nos Estados
Unidos e em outros paises. Java e todas as marcas relacionadas sdo marcas registradas da Sun Microsystems Inc. nos
Estados Unidos e em outros paises. A McGraw-Hill/Osborne ndo tem ligaqdo com a Sun Microsystems, Inc.

Rua Viriva Claudio,29l - Jacaft


Rio de Janeiro - RJ. CEP: 20970-031
TeI: 21 3278-8069/ Fax: 21 3277-1253
ESeitrrRl*|E
wu{w.osborne.Eorn
ww.altabooks.com.br
e-mail: altabooks@altabooks.com.br
JAVA 5V

ParaaComtrnida&Java
Sum6rio
capirulo | - DEclAnag6es E coNTRoLE DE AcEsSo.................................... I

ldentificodores e Polovros-chove........... ......... 2

Encontrondo Outros Closses ..................'...... 2

Objetivo para a Certificagio............ ............3


ldentificadores e JavaBeans (Objetivos 1.3 e 1.4) ....--.-.-.. 3

ldentificadores Legais ................... 3

Objetivo para a Certificagio.............. ..........6


Declarar Classes (Objetivo l. I do Exame) .....-.'............... 6

a
Outros Modificodores de Closses (N6o-re{erentes o Acesso)
Exercicio l- | Criando uma Superclasse Abstrata e uma Subclasse Concreta .....' | 0

Objetivo paraaCertificag6o............ .......... ll


Declarar lnterfaces (Objetivos l. I e 1.2 do Exame) ............. .'........ I I

Objetivo para a Certifi cagio ............ t4


Declarar Membros de Classes (Objetivos 1.3 e 1.4) ............ ........... 14

Membros Protecl eDefoult ....... 19


Deiolhes de Protect ................. n
Detolhes de Deioult....
Vori6veis Locois e Modificodores de Acesso ..................... 23

Argumentos Finol ...........


M6todos Abs
M6todos Synchronized ..'.......... 27

M6iodos com Listos de Argumentos Vori6veis (vor-orgs) .......-...-.......--.. 27

Declorondo Primitivos e Iniervolos de Primitivos


Refer6ncio
DeclorondoVori6veis de ............. 30
Voridveis de Instdncios ...........' 30
Vori6veis Locois (Automotic/Stock/Method) ......... ........-.... 3l
Declorog6es de Arroys ..........'.. 33
JAVA 5 VII
Voridveis e M6todos Stotic.........'.. ................ 35

Declorondo Construtores, M6todos eVoridveis em um enum .......... ...... 37

CAPITULO 2' ORIENTA€AO A OBf ETOS...................................o.......................... 49


Objetivo para a certificagSo ............. .........50
Beneffcios do encapsulamento (Objetivo 5. I do exame) ................ 50

Objetivo para a Certificagio


Heranga, E-Um, Tem-Um (Obletivo 5.5 do Exame) .....52
Relacionamentos E-Uy e TEM-UM ............55

Objetivo para a Certifica9io.............. ........58


Polimorfismo (Obietivo 5.2 do Exame) .......58

Objetivo para a Certi{ica9io............ ..........60


Subscrevendo / Sobrecarregando (Obfetivos 1.5 e 5.4 do Exame) ................... 60

Chomondo o versOo do superclosse de um m6todo subscrito ............... 63


Exemplos de subscrilos de m6iodo v6lidos e ndo-v6lidos ................ ..... U

Sobrecorgos v6lidos ................ &


Chomqndo m6todos sobrecorregodos ............. ................ 65
Polimorfismo em m6todos sobrecorreqodo e subscrilo ....... &
Objetivo para a Certificagio ............ ,.............68
Conversio de Vari6veis de Refer6ncia (Objetivo 5.2 do Exame) ....68

Objetivo para a certificagio ............. .........7 |


lmplementando uma Interface (Obietivo 1.2 do exame) ................71

Objetivo para a certificag6o ............. 74


Tipos de retorno v5lidos (obfetivo 1.5 do exame) ........74

Tipos de retorno de m6todos sobrecorregodos............. ..... 74


A Subscrig6o e os Tipos de Retorno, e Retornos Covorionies ................. 75

Objetivo para a certificag6o ............. .........77


Construtores e instanciaEio (Objetivos I .6 e 5.4 do exame) .........77
Aspeclos bdsicos do construtor .................... 77
Codeiqdeconslrulores................. ..............77
Regros dos construtores .............. ................ 78
ldentifcando se um constru
Como voc6 pode ter o certezo de que um conslrutor podr6o ser6 criodo? ................ 79
O que oconlecer6 se o conslruiuor do superclosse tiver orgumentos?........... ..........80
vlll
Objetivo para a Certificagio
Vori6veis e m6todos stotic .......... ................. 85
...........
Acessondo vori6veis e m6todos stotic ................... 85

Objetivo para a Certificagio............................. ..........88


Acoplamento e Coesao (Objetivo 5. I do Exame) ........ 88

CAPiTuLo 3 - ATR|BU1C6ES.........r....r.....,..-... ......r.o.....o........................ f 0f


J

Pilha e Heap - Uma Revisio .... 102

Objetivo para a certificagio ............. ........ 103


Literais, Atribuig6es e Vari6veis (Objetivos I .3 e 7.6 do Exame) ... 103

Literois de ponto flutuonte .......1U

Literois
Volores literois poro strings......... ................ 05

Convers6o detipos primitivos .................... ]07

AtribuiE6es de vori6veis de refer6nciq .......... I l0

Usando umavari6vel ou elemento de array que nlo tenha sido

Vori6veis de instdncio de tipo primiiivo e de obieto .......... I 13


Voridveis de instdncio primitivos ................. 1.l3
Vori6veis de insi6ncio de refer6ncio o obietos ..........-....... I 13
Vori6veis de instdncio de orroy ................... I 14
Tipos primitivos e obielos locois (de pilho, outom6ticos) ...................... I l5

Refer6ncios de Obietos 1ocois.......... ........... I 16

Airibuindo umo vori6vel de refer6ncio o ouiro .................117


Objetivo para a Certificag6o............ ........ | | I
Passando varieveis para m6todos (Objetivo 7.3 do exame) .......... I l8

AlinguagemJavausaasemnnticadepassagemporvalor? ............ l19

Objetivo para a certificagio ...122


DedaraEio, construgao e inicializaEio de arrays (objetivo 1.3 do exame) ..... |-22

Declorondo um orroy de tipos primitivos .....122

Construindo orroys unidimensionois ...........123


Construindo orroys multidimensionqis .........124
JAVA 5 IX
lniciolizondo elementos em um loop ........... ...................126
Declorondo, construindo e inciolizondo em umo linho .......... .............126
Construindo e iniciolizondo um orrov on6nimo ...........127
AtribuiEoes v6lidos poro os elemenlos do orroy . .............128
Arroys de tipos primitivos............... ............ l2B
Arroys de referGncio o obietos ....................129
.|30
AtribuiE6es de vori6veis de refer6ncio de orroys unidimensionois .............. ...............
Atribuigoes de vori6veis de re{er6ncio de orroys multidimensionois ............ ..............
'130

Blocos de Iniciolizo96o ..............

Objetivo para a certificagio ............. t33


Usando classes wrapper (Objetivo 3. I do exame) 133

Osconstrutoreswrqpper .........133
Os m6todos volueOf0 ... ... ............. ]34
Usando os utilitidos de conversio das classes wrapper .............. | 34

.l35
porseXrx$ e volueOffl . .... .. ............

to/rxxStringfl (bose bindrio, hexodecimole octol) .............136

Boxing, ::, e equolsfl .......... 137


Onde Pode ser Usodo o Boxing .................. l3B
Objetivo para a Certifica96o............ ........ | 39
Sobrecarregando (Objetivos 1.5 e 5.4 do Exame) ...... 139
Sobrecorregondo do Moneiro Di{icil- Correspond6ncio de M6todos r39
Sobrecorgo com Boxing e Vor-orgs r40
Ampliondo Vori6veis de Refer6ncio 141
Sobrecorgo no CombinoE6o de AmplioE6o com Boxing 141
Sobrecorgo em CombinoE6o com Vor-orgs 142

Objetivo para a certificagio


Coleta de lixo (Objetivo 7.4 do exame) .... 143
Vis6o total do gerenciamento da mem6ria e da coleta de lixo ............... ............ 143

Quondo o coletorde lixo 6 execulodo? ............ ..............144


Como o coletor de lixo funciono? ..144
Escrevendo um c6digo que torne os objetos explicitamente qualificados

Anulondo umo refer6ncio ............... ...........144


Reotribuindo umo voridvel de referGncio ......145
lsolondo umo refer6ncio ............... .............146
ForEondo o coleto de lixo .......146
Fozendo umo limpezo ontes do coleto do lixo - o m6todo finolize( ) .. ... ....... l4B
Cuidodos relocionodos com finolizefl ......... . . .......... 148

Objetivo para a certificageo ..........


Operadores Java (Objetivo 7.6 do exame) .................. 162
Operodores deAtribuiE6o ......162
Operodores de AtribuigdoCompostos .........162
x
lguoldode de tipos pdmilivos ...........'..'..-..'164
lguoldode de vori6veis de referGncio ..."...... 165
lguoldode poro Enums r65
Operodorde comporog6o inslonceo{ .......... 166
Erro de CompiloE6o de instqnceof ................. ...............-167

O Operodor Resto (%) .'......... 168


Operodor de concotenoE6o de strings
Acr6scimo edecr6scimo ......... ]70
Ooerodor condicionol. ..........'171
Operodores L6gicos ...............172
Operodores Bitwise (N6o Coem no Exome!) ...................172
OperodoresL6gicosdeAbrevioE6o................ .....'........'172
Operodores l6gicos (que n6o s6o de obrevioE6o) ...........174
Operodores L6gicos ^ e !........... ..............174
Resumo para a certificagio

cApiTULo 5 - coNTRoLE DE FLUxo, ExcEg6es E AssERTlvAs...o............. 183


Objetivo para a ceftificagio ....... t84
Escrevendo o c6digo usando instruE6es if e switch
(Objetivo 2. I do exame) .......... 184

Express6es v6lidos poro instruE6es if ............ .................. 186

Breokeopossogemcompletoemblocosswitch......... .....190
defoult
A instruE6o cose .........192
Exercicio 5- | Criando

Objetivo para a certificagio ... 193


Loops e lteradores (Objetivo 2.2 do exame) .............. 193

O LoopforBdsico .................,l95
LoopforBdsico: Declorog6oeiniciolizoE6o................ .....|95
.|95
Loop for Bdsico: Express6o condicionol (booleono) .........
LoopforBdsico: Express6ode iterog6o.. ......196
LoooforB6sico:Corocleristicosdolooofor.............. ......196
O Loop forAprimorodo (poro Arroys) .........197

Objetivo para a certificagio


Manipulando exce96es (objetivos 2.4 e 2.5 do exame) ................. 20 |

Manipulando uma hierarquia inteira de classes de exceg6es .........208


JAVA 5 XI

Objetivo para a Certifica9io.............. ......214


Erros e ExceE6es Comuns (Objetivo 2.6 do Exame) ...................214
De Onde V6m os ExceE6es .....214
JVM
Exceg6es LonEodos pelo .....................214
ExceE6es LonEodos Progromolicomente ......... .................215
Um Resumo dos ExceE6es e Erros poro o Exome .............215
Objetivo para a certificagio ...216
Ti'abalhando com o mecanismo de assertivas
(Objetivo 2.3 do exame) ..........216

Regros dos express6es de ossertivos ............... ................218

ldentificodorx Polovro-Chove ................ ....219


Usqndo o Versdo 5 de lovo e iovoc ............219
Compilondo um C6digo Alenio ds Assertivos 219

Aiivondo ossertivos no tempo de execuc6o ...220


Desotivondo ossertivos no tempo de execuEdo ................220
AtivoE6o e desotivoE6o seletivo ..................22|.

N6o use ossertivos ooro volidor orqumentos de um m6todo o0blico. ..................222


Use os ossertivos poro volidor orgumentos de um m6todo privodo. ......222
N6o use ossertivos poro volidor orgumenios de linho de comondo .......222
N6o use ossertivos, mesmo em m6iodos p0blicos, poro procuror instrug6es cose que sobe que nunco ocorre16o ..222
N6o use express6es ossedivos que possom cqusor efeitos coloteroisl ....223

CAPITULO 6 - STRINGS, E/S, FORMATACAO E PARS|NG.................................237


Objetivo para a ceftificagSo ............. .......238
String, StringBuilder e StringBuffer (Objetivo 3. I do exame) ......... 238

Strings s6o obietosinolter6veis ...................238


Fatos importantes relacionados aos objetos String e a mem6ria .......................24 |

Criondo novos slrings ............242


M6todos importon'les do closse String......... ..............242

StringBufferx StringBuilder ......244


Usondo StringBuffereStringBuilder .............245
StringBuilder
M6todos importantes das classes StringBuffer e ......245
Objetivo para a Certificagio.. 246
NavegaEio de Arquivos e E/S (Objetivo 3.2 do Exame) ...............246
Criondo Arquivos com o Closse File ............. .................247
Usondo FileWriter e FileReoder ..................249
Combinondo Closses de E/S ......................250
Trobolhondo com Arquivos e Direi6rios .......252

Objetivo para a Certifica9io.............. ......254


SerializagSo (Objetivo 3.3 do Exame) ........254
xil
ObiectlnputStreom
Trobolhondo com ObiectOutputStreom e ................255
Gr6ficos de Obietos ...............256
reodObieci
Usondo wrileObiect e ............... 258
Seriolizog6o
Como o HeronEo Afeto o .........260
................
A SeriolizoEoo n6o 6 poro Est6ticos ...............262
Objetivo para a Certificasio..............
Datas, Nrimeros e Moeda (Objetivo 3.4 do Exame) ...263
Trabalhando
Orquestrondo Closses Relocionodos o Dotos e Nimeros .... ...............263

A Closse Colendor .................265


A Closse DoleFormol .............266

A Closse NumberFormot ............... ............270


Objetivo para a Certificagio............ ........27 |
Parsing, Tokenizag6 e Formatagao (Objective 3.5 do Exame) .......271

Buscqs Usondo Melocorocreres ......................., ,,,,.........'273


Buscos Usondo Quqnti{icooores ................
O Ponto Pr6-definido .............275
Quonti{icodores Gononciosos.............. ......275
Colidem
Quondo Metocorocleres e Strings .....................276
Padr6es...
Locaf izando Dados atrav6s da Correspond6ncia de ....277

Tokens e Delimitodores ................ ..............279


Tokenizondo com String.splitfl ......... ......279
Tokenizondo com Sconner ..............280

cApiTuLo7-GENfRlcosEcoNfuNToso.........o...o.ooo......o.o...................oo........zgs
Objetivo para a certificagio ............. .......296
Subscrevendo hashCode( ) e equals( ) (objetivo 6.2 do exame) ...296

O que significor6 o n6o subscriEdo de equolsfl ... ....... . ...............297


lmplemenlondo um m6fodo equols( ) .. ...............298
O conlroto de equols( ) ................. ............300

hoshing
Entendendo os c6digos de ............300
................
lmplementondo hoshCodefl ......30'l
O conlroto de hoshCodefl ... ........302
Objetivo para a certificag6o ............. .......304
Conjuntos (Objetivo 6. I do exame) .......... 304

Interfoces e closses chove do estruturo de coniuntos ........304

A Interfoce Se1.............. .........307

A Interfoce Queue........ ..........308


JAVA 5 XIII
Objetivo para a Ceftificag6 o .................. 309
Usando a Estrutura dos Conjuntos (Objetivo 6.5 do Exame) ....... 309

Clossificondo Coleg6es ....... .. . 3l O


A Interfoce Comporoble ................... 312
Clossificondo com Comporotor .............. ....3j3
ClossificondocomoClosseArroys........ .....315
Fozendo Buscos em Arroys e em Coniuntos .............. ......315
ConverJendo Arroys em Listos e de Voltq em Arroys ..........3j7

...................
Usondo o Cfosse PriorityQueue ..................322
Vis6o Gerql dos M6iodos poro Arroys e Coniuntos. .....32g
VisSo Gerql dos M6todos poro Lisl, Set, Mop e Queue...... ..............324
Objetivo para a Certificagio ..........32s
Tipos Gen6ricos (Objetivos 6.3 e 6.4 do Exame) .........325

Gen6rico
Criondo o suo Pr6prio Closse ......342
Criondo M6todos Gen6ricos ......................345

cAPiTULo 8 - ctAssEs 1NTERNAS...................................................................... 36 |


Objetivo para a certificagiio ............. .......362
Classes

lnslonciondo umo closse interno ................3U


Referenciando a instincia interna ou externa de dentro da classe interna ...........365
Objetivo para a certificagio ...366
Classes internas locais de m6todo .............366
O que um objeto interno local de m6todo pode ou n?rofazer ..................... 367
Objetivo Para a ceftificagao ............. ................ 368
Classes internas an6nimas ........369

Objetivo para a certificagio ...373


Classes est6ticas aninhadas ....... 323
xtv
CAPiTULO 9 - THREADS............o..o.........................................................................383
Objetivo para a certificagSo ............. .......384
Definindo, instanciando e iniciando threads
exame)
(Obletivo 4. I do .......... 384

Criando um thread ............... 385

Objetivo para a Certificagio............ ........393


Estados e Transig6es de Threads (Objetivo 4.2 do Exame) .......... 393

Criando

Objetivo para a certificagio ............. .398


Sincronizando o c6digo (Objetivo 4.3 do exame) ....... 398

O oue ocontecer6 se um threod n6o puder obter o bloqueio? """"'405


Ent6o, Quondo Eu Preciso Sincronizor? ..."' 405
Closses Seguros em ReloEdo o Threods """' 407

Objetivo para a certificagio .............


lnteragio entre os threads (Objetivo 4.4 do exame) "409
Usando notifyAll( ) quando houver a possibilidade de muitos threads estarem esperando ...'.4 |3

Usondo woit( ) em um Loop " " 414

Exercicio 9-l: Criondo um threod e coloconoo-o em suspensfio..........'... """""""'428


Exercicio 9-2: Sincronizondo um bloco de c6digo ..""""' 429

cApiTULO l0 - DESENVOLVIMENTO ........o.............o..o...............o..........oo............ 43 |

Objetivos para a Certificag5o............ ......432


Usando os comandos iavac e java (Obietivo 7.2 do Exame) ...-..." 432

Comoilondo com -o ..............432

Usondo os Propriedodes de Sistemo """""' 434


Lidondo com Argumentos de Linho de Comondo """""" 435

Closspoths
Declorondo e Usondo """""""' 436
Pocoleseo Procuro """""""'436
JAVA 5 )ry
Cominhos Relotivos e Absolutos ...... ....438
Objetivo para a Certifi cagio .............. 439
Arquivos JAR (Objetivo 7.5) .....439

Usondo .../ye/lib/ext com Arquivos JAR........... .............440


Objetivo para a Certifi cagio .............. ..............441
Usando lmportaE6es Est6ticas (Objetivo 7.1 do Exame) ..............441

APENDICE A..o..o.......o............................................................................................... 45 |
Requisitos do sistema ...............452
lnstalando e executando o MasterExam ....452

Suporte t6cnico ......452


xvl
Sobre os Colaboradores
Sobre os Autores
exame SCJP paralaval. Sierra trabalhou como instrutora sAnior da Sun e' em
Kathy Sierra foi desenvolvedora-lider do
1997, fundou oJavaranch.com, a maiorcomunidade sobreJava nalnternet. Os seus livros recordistasdevendassobreJava
jireceberam v6rios prAmios da revista Sofrware Development Magazine, e ela 6 tamb6m membrofundador do programa
Java Champions da Sun.
Bert Bates tem sido desenvolvedor-lider de virios exames de certificagio da Sun, incluindo o SCJP paraJava 5. Ele tamb6m
6 moderador de um f6rum emJavaranch.com, e tem desenvolvido softwares por mais de 20 anos. Bert 6 co-autorde
diversos livros recordistas de vindas sobreJava, e 6 membrofundador do programaJava Champions da Sun.

Sobre a Equipe de Revisio T6cnica


(Ele tem mais paci6ncia
Johannes deJong tem sido o lider das nossas equipes de revislo t6cnica por muito, muito tempo.
do que qualquer pessoa qrre conhecemos.) Neste livro, ele liderou a maior equipe que j6 formamos. Nossos sinceros
t"goitttes volunt6rioi, que foram inteligentes, trabalhadores, pacientes e muito, muito detdhistas!
"gmd..i-entot "or
Rob Ross, Nicholas Cheung, Jane Griscti, Ilja Preuss, Vincent Brabant, Kudret Serin, Bill Seipel Jing Yr' GinuJacob
George, Radiy4 LuLrrr-MazaAnshu Mishia, Anandhi Navaneethakrishnan, Didier Varon, Mary McCartney, Harsha
Pherwani, Abhishek Misra e Suman Das.

Sobre o LearnKey
O karnKey fornece conrerido de aprendizado que respeita o ritmo do aluno, e apresenta solug6es de distribuigio de
muldmidia para aprimorar habilidades pessoais e produiirridade empresarial. O_ LearnKey apresenta a maior biblioteca de
conterido di treinamento multimidia existent., fottt.." rlm dinAmico aprendizado, rico em diversas
"'q.r"l "o, "irrrro, animadas. O site do LearnKey na web 6
ilustrag6es
midias, como videoclips, 6udio, grificos totalmenfe animados e
www.kamKey.aorrl

Os Astros da Revisio T6cnica


Nio sabemos quem trabalhou mais, mas podemos contar as edig6es feitas por cada revisor (e o fizemos!) - entio, na ordem
de mais edig6es feitas, n6s orgulhosamente apresentamos os nossos superastros.

Em primeiro lugar, ashonras vio para Kristin Stromberg - toda vez que voc6 vir um pon193-vilgula sendo usado
.orrit"-.rrt., alradega a Kristin. Em seguida vem Burk Hufnagel, que_ consertou mais c6digos d9 que estamos.dispostos a
admitir. Bill MiJtekkie Gian Franco Caiula corrigiram todos oJtipos dc erros que jogamos para eles - 6timo trabalho,
pessoal! Devender Thareja certificou-se de que nidest6vamos usando giria demais, e Mgk Sgrlzler manteve o bom humor.
ivfiU{ Z"it i" e Seema Manivannan fizerani impoftantes correg6es no livro todo, e Marilyn de Queiroz e Valentin Crettaz
novamente fizeram um trabalho espetacular (novamente salvando os nossos pescogos).
Marcelo Onega, Jef Cumps (outro veterano) , Andrew Monkhouse e Jeroen Sterken completam o nosso time de
rnp.r"rtror - o*brigado a todos voc6s. Jim Yingst panicipou da equipe de criagio do exame da Sun, e nos ajudou a escrever
algumas das quest6es mais dificeis do livro (muahahaha).

Como sempre, toda vez que voc6 vir uma plgina bem esc ita, agradegaaos nossos revisores e, se encontrar um erro' com
toda ceneza 6 por culpa dos autores. Ah sim,i um agradecimento final aoJohannes. VocA 6 demais, cara!
JAVA 5 )O/II

Agradecimentos
Kathy e Bert gostariam de agradecer as pessoas a seguir:
r Topas
1s egssoas
incrivelmente esforgadas da Osborne: Tim Green, Jim Kussow, Jody McKenzie e Jennifer Housh por
toda.a ajuda e por serem tXo compreensivas e pacientes - bem, certo, nem tio pacientes assim - mas muito
profissionais e o grupo mais agrad6vel de pessoas com quem sepoderiaesperartrabalhar.
I Os nossos anjos Solveig Haugland e Midori Batten, por virem nos salvar quando realmente esr6vamos em apuros!
r Akuns dos profissionais de software e amigos que nos ajudaram nos dias iniciais: Tom Bender, Peter Loerincs, Craig
Matthews, Dave Gustafson, konard Coyne, Mbrgan Poner e Mike Kavenaugh.
r Acima de tudo, a maravilhosa e talentosa equipe de cenificagio da Sun Educational Services, principalmente o Gerente
do Progtama de Cenificagio, Steve ('Gooie') Moore e a pessoa mais persistente que ji conhecemos quando se trata de
-
condrsio, Evelyn Cartagena (paraMnspelo rec6m-nascido, Evelyn).
r Nossos melhores amigos e especialistas emJava, Bryan Basham, Kathy Collina e SimonRoberts.
I As criangas, Eden e Skyler, por ficarem horrorizadas que os adultos - fora da escola - estivessem estudando tanto para
umexame.
r O chefe doJavaranch Trail, Paul \(heaton, por manter a melhor comunidadeJava da Internet.
I Todos os outros instrutores antigos e atuais de Java da Sun Ed por aju&rem a torn ar o aprendizado dessa linguagem
um1 expel6nciadivenida, (para nomear apenas alguns) : Alan Petersen, Jean Tordella, Georgianna MJa$ier,
_incluindo
Antho-ny Orapallo, Jacqueline Jones, James Cubeta, Teri Cubaa, Rob '$7eingruber, John Nyquist, AsJk Perumaiiar,
Steve Steltin_g,\a;reZaffery, KimberlyBobrow, Keith Ratliffe o conhecedordeJavamais dedicado einspiradordo
planeta,,JariPaukku.
r Darren e Mary, obrigado por nos manter sios e por nos ajudar com os nossos novos amigos peludos, Andi e Kara.
r Finalmente, Eric e Beth Freeman pelo incentivo continuo.
)o/il1

Preficio
O principal objaivo deste liwo 6 ajud6-lo a se preparar e passar no exame de cenificagio SCJP da Sun Microrystems referente
aJava 5. A boanoticia 6 que o exame tende a t6picos que a maioria dos desenvolvedoresJava encontrarlo nos seus
"borda.
tiabalhos. A noticia desafiadora 6 que o exame Java 5 tem escopo bem mais amplo do que o seu antecessor, o exame Java
1.4. Os novos objetivos passam poi muitas das-APIs mais utiliiadas emJava. A palavri-chave aqui 6 "passam por". A
intengio dos criadores io ex"*. foi qn representasse a certeza de que o candidato ente nde osfundanenns de
APIs, tais como aquelas usadas para E/S "diarquivos
"provagXo e express6es regulares. Este livro segue o miximo psssivel tanto o
escopo quanto a profundidade do exame real. Pbr exemplo, ap6s ler este livro voc6 provavelmente nXo vai acordar no outro
di" *-b ,rtn go* d. ,.gr*, mas, se estudar o material, e sair-se bem nos testes individuais, voc6 ter6 um entendimento
bisico de regei e se sairilemno exame. Depois de terminareste livro, voc|tericeneza de que estudoutodos os objetivos
estabelecidos pela Sun para o exame.

N este livro
Este livro foi organizado de maneira a otimizar o seu aprendizado dos t6picos abodados pelo exame SClPJava- f . Sempre
que possivel, n6-s organizamos os capitulos seguindo os objetivos da Sun, mas em.alguns casos misturamos objetivos ou
os repeumos parcialirente p"r" os t-6picos em uma ordem mais adequada para o esnrdo do material.
"prrs"nt"t

Em cada capitulo
N6s criamos um conjunto de blocos constituintes dos capitulos que chamario sua atengio.para itens importantes,
reforgarXo pontos deiestaque e fornecerXo dicas riteis para a hora do exame. Veja o que voc6 encontrar6 em cada capinrlo:
I Cada capitulo comegar6 com os Obietivos da Certificag5o - 9-guq vocA precisa saber para passar na seglo do exame que
tratar do t6pico refeiente ao capinrlo. Os objetivos serio identificados dentro do capinrlo por seus cabegdhos, portanto'
voc6 sempre saber6 qual6 o objetivo quando o vir!
I A notas Observag6es para o exame chamario a atengio para informag6es e possiveis armadilhas relacionadas ao
exame. LJma vez que eit6vamos na equipe que criou o exame, sabemos pelo que voc6 vai passar!
I As notas Ao trabalho descreverXo aspectos priticos de t6picos da certificagXo que podem nio aparecer no exame, mas
que serlo riteis no mundo real.
I Os exercicios priticos foram incluidos no decorrer dos capitulos. Eles o ajudario a aprimorar as aptid6es,que
possivelmenteirXo enfocadas no exame. NXo se limite a leios exercicios! Eles fornecem a pritica na execugio com a
qual voc6 teri que estar familiarizado. Aprender fazendo 6 uma maneira eficaz de aumentar sua capacidade.

I A segXo Nas salas de aula descrever6 as quest6es que surgem com mais freqiiAncia em cenirios de treinamento em salas
de aula. Essas barras laterais lhe darXo uma perspe&iva vfiosa sobre t6picoJ relativos i cenificagio e aos produtos. Elas
ressaltario alguns dos problemas mais comunJe confusos que os alunos encontram quando fazem um curso deJava.

P&R
I O Resumo para a Certificagio 6 uma revisio sucinta do capitulo e uma reiteraglo dos pontos importantes
relacionados ao exame.
I O Exercicio Mpido no finalde cada capitulo 6 umalistade verificaEio com os principais pontos do capitulo. Pode ser
usado para uma revisio de ultima hora.
I O Teste Individual oferece perguntas que simulam os t6picos, a estrutu ra e a naltezadas perguntas encontradas no
exame de certificagio. As resposras a essas perguruas, assim como suas explicag6es, podem ser encontradas no final de
cada capitulo. Aoiaznr oTeie Individual, depois da concluslo de cada capinrlo, vod reforgar6 o que aprendeu nele ao
mesmo tempo em que se fam liarizarS, coma estrutura das perguntas do exame.
JAVA 5 XIX

lntrodu96o
Organizagio
Este livro foi organizado de maneiraa servircomo um estudo aprofundado sobre o exame de Programador Cenificado
pela Sun na PlataformaJava 5 tanto para profissionais experientes na linguagem quanto para os que estiverem nos est6gios
iniciais de vi#ncia com as tecnologias Java. Cada capinrlo aborda um dos aspectos principais do exame, com Anfase em
perguntas como "por que" e'!olo" pJggramar na linguager-nJava. O livro tamb6m inclui um estudo detalhado dos itens
essenciais para obter uma avaliagio positiva no projeto enviado para o exame de DesenvolvedorJava Certificado pela Sun.

O que esse livro n6o 6


Neste livro voc6 nio encontrar6 um guia para iniciantes no aprendizado de Java. Todas as suas piginas sio dedicadas
somente a ajud6-lo a passar nos exames. Se voc6 for iniciante emJava, sugerimos que demore algum ternpo aprendendo os
aspectos b6sicos e nXo passe para esse livro at6 que saiba como escrever, compilar e executar programas Java simples. No
entanto, nio pressupomos nenhum nivel de conhecimento anterior dos t6picos individuais abordados. Em outras
palavras, em todos os t6picos discutidos (direcionados exclusivamente pelos objetivos reais do exame), paftimos da
suposigio de que voc6 ainda nio os conhece. Portanto, o consideramos iniciante nos t6picos indivi duais, mas ndo na
linguagemJava.

Tamb6m nio pretendemos ao mesmo tempo em que o preparamos para o exaffrc tund-|t un especialista n@lcto en Jaua.Esse 6
um guiade esrudos para o a(ame da cenifica$o e sua missio 6 muito clara.Isso nXo querdizer que apreparaSo para o exame
nio o ajudari a se tornar um programador Java mais avangado! Pelo contririo, mesmo os mais experientes desenvolvedores
Javageralmente relatam que o fato deterque se prepararpara o exame de cenificaSo ostornouprogramadores mais
informados e completos do que seriam sem o estudo dirigido para o exame.

No site
Para obter mais informag6es sobre os arquivos para download, consrlte o Apdndice A.

Algumas sugest6es
Quando tiver terminado de ler este livro, reserve algum te mpo parafazer uma revisio completa. Seria bom se voc6
retornasse ao livro v6rias vezes e fizesse uso de todos os m6todos que ele oferece para revisar o material:

L RebiatodososExerciciotRtipidotoupegaaalgu|mparalhefazcrasperguntas.Voc6tamb6mpodeusarosexercicioscomo
uma maneira de fazer uma revisio ripida antes do exame. Ou criar alguns cart6es pedag6gicos em fichas 3x5 contendo o
material dos Exercicios R6pidos.
Z Reteia todat as notas da segdo Alerta no Exame. Lembre-se de que essas observag6es foram escritas por autores que ajudaram
a criar o exame. Eles sabem com o que voc6 se deparar6 - e com o que dwe tomar cuidado.

3. Refapa wTestetIndiuidaais.Fazer os testes logo ap6s ter lido o capitulo 6 uma boa id6ia, porque as perguntas ajudario a
reforgar o que voc6 acabou de aprender. No entanto, uma ideia melhor ainda 6 voltar posteriormente e responder todas
as perguntas do livro de uma s6 vez. Imagine.que est6 fazendo o exame real. (Quando percorrer as perguntas pela
primeira vez, anote suas respostas em.um.pedago. de papel separado. Dessa forma, voc6 poderi responder as perguntas
quantas vezes precisar at6 que se sinta familiarizado com o material).

4. fez os exercicios quando leu cada capitulo? Se nlo os fez, faga-os agora! Esses exercicios foram
Faga ot exercicios.Voc6
elaborados para abordar t6picos do exame e nio hi maneira melhor de conhecer esse material do que praticando.
Certifiquese de compreender porque est6 executando cada etapa de cada exercicio. Se houver algo que nio tiver
entendido, releia essa se$o do capinrlo.

Introdugio ao material do livro


O exameparaProgramadorJavaCertificado pelaSun (SCJP, Sun CertifiedJavaProgrammer) 6consideradoumdos mais
dificeis (se nXo for a mais dificil) do segmento de inform6tica e podemos dizer a panir de nossa experiAncia que boa parte
dos candidatos fazem o teste sem o preparo necess6rio. E estamos falando de pessoas que ji conhecemJava muito bem e
que ji a usam em programagio h6 anos! Como programadores, ten&mos a aprender somente o que precisamos para
concluir nosso projeto atual, dados os prazos impraticiveis, geralmente associados. Mas esse exame tentarA avaliar seu
conhecimento totd da linguagemJava e nio apenasas partes com as quais voc6 se familiarizou em seu trabalho.

Somente a experiAncia nio o far6 chegar ao final do exame com uma nota que o aprove, porque mesm o o quevoc| arba qrrc
conhece pode funcionarde formaumpouco diferente do que imagina. Nio 6 o bastante conseguirque seuc6digo funcione
corretamente;voc|prccisacompreender os fundamentos bisicos de maneiraprofunda e com abrang6ncia suficiente para
xx
abordar tudo que possa surgir durante o uso da linguagem.
O Exame de Desenvolvedor Certificado pela Sun 6 rinico no universo de certificaglo em inform6tica, porque naverdade ele
avaliar6 sua habilidade como desenvolvedor, em vez de simplesmente seu conhecimento da linguagem ou das ferramentas.
Se tomar um DesenvolvedorJ avaCenificado envolve, por defini$o, experiAncia em desenvolvimento.

Quem se importa com certificag6es?


Os empregadores se impoftam. Os recrutadores de executivos. Os programadores. O exame de programador da Strn tem
sido considerado a cenificaglo que mais se popularizou no universo da inform6tica e a quantidade de candidatos que o faz
continua a crescer a cada ano. Passar nesse exame provar6 tr& itens importantes para um empregador atual ou futuro: que
voc6 sabe das coisas; que sabe como estudar e se preparar para um teste desafiador; e, acima de tudo, que conhece a
linguagemJava. Se um empregador tiver que optar entre um candidato que passou no exame e outro que nlo tenha
passado, ele saberi que o programador cenificado nio precisar6 se demorar no aprendizado da linguagemJava.

Mas isso significa que vocA realmente poderi desenvolver sofrwares emJava? Nio necessariamente, mas 6 uma boa
vantagem inicial. Para demonstrar efetivamente sua habilidade no desenvolvimento (em vez de apenas seu conhecimento da
linguagem) , voc6 deve corsiderar o Exame de Desenvolvedor, do qual receberi atarela decriar um programa, do inicio ao
fim, e envi6-lo para um avaliador que o examinar6 e lhe dari uma nota.

Programa de certificagio da Sun


Atualmente, h6 oito exames de cenificagio emJava. Os exames de Associado,ProgramadoreDesenuoluedoresteo associados com
aJava Standard Edition. Os exames de Componentet IYeb, Ca@onentes de Negocin, Smigos IYeb e Proletista Empresarial estl.o
associados com aJava Enterprise Edition . O exane de Aplicatiuot Mriueis est6 associado com aJava Micro Edition.

Os exames de Associado, Programador, Componentes'Web, Componentes de Neg6cios, Servigos \il7eb e Aplicativos


M6veis sio exclusivamente de mriltipla escolha e do tipo arrastar-e-soltar, e sXo feitos em um centro de testes, enquanto os
exames de Desenvolvedor e de Projetista envolvem o envio de um projeto.

O exame de associado (CX-3 l0-0 | 9)


Associado Java Certificado pela Sun (SCJA)

O exame de Associado foi elaborado para candidatos que acabaram de iniciar uma carreira em desenvolvimento &
aplicativos ou em ger6ncia de projetos de software usando tecnologiasJava. Este exame testa conhecimento bisico de
conceitos de programagio orientada a objetos, os fundamentos de LIML, os fundamentos da linguagem de programagio
Java e o conhecimento geral de plataformas e tecnologiasJava. E$e exame nio tem nenhum pr6requisito.

O exame de programador (CX-3 10.035)


ProgramadorJava Certificado pela Sun paraJava 5 (SCJP)

O exame de Programador foi projaado paratestar seu conhecimento na propria linguagem de programagio Java. Ele requer
um conhecimento aprofundado da sintaxe da linguagem, dos conceitos principais e de uma pequena quantidade de
interfaces de programagXo de aplicativos (APIs, Application Programming Interfaces). Este exame tamb6m testa o
conhecimento intermediirio de conceitos de projetos orientados a objetos. Nio avaliarinenhuma questio relacionada ao
projeto ou arquitetura do programa e nio perguntar6 por que uma abordagem 6 melhor do que a outra, mas, em vez disso,
estarApreocupadoseaabordagem dadafuncionariemumasitua$oespecifica.Estee:<ameniotemnenhumpr6requisito.

O exame de desenvolvedor (CX-3l0-252A CX-3 | 0-027)


DesenvolvedorJava Cenificado pela Sun paraJava 5 (SCJD)

O exame de Desenvolvedor tem inicio onde o exame de Programador termina. Ser6 necess6rio passar no exame de
Programador antes que voc6 possa se dedicar ao exame de Desenvolvedor. Esse exame requer o desenvolvimento de um
programa real e, em seguida, uma justificativa para as decis6es tomadas no projeto. Ele foi elaborado para testar sua
compreensio do motivo pelo qual cenas abordagens sio melhores que outras em determinadas circunstAncias e para avaliar
sua habilidade em seguiruma especificagio e implementarum programa correto, funcional e amig6vel.

O exame de Desenvolvedor 6 composto de duas panes: a tarefa de criagXo de um projeto e um exame com quest5es
dissenativas como acompanhamento. Seri dado um periodo & tempo ilimitado para conclusio do projeto, por6m,
quando este for enviado, os candidatos terio que ir a um centro de testes e fazer um pequeno exame de acompanhamento
comquest6esdissertativas, elaborado, principalmente, paravalidareverificar sef.oram eletquem o projetaram e construiram.
JAVA 5 XXI
O exame de Desenvolvedor de componentes da Web (CX-3 10-08 l)
Desenvolvedor de Componentes da \ilfleb Cenificado pela Sun na PlataformaJava EE (SC\7CD)
O exame de desenvolvedor da \fleb tem como alvo as pessoas que estiverem usando o JSP $ava Server Pages) e o servlet da
tecnologiaJavap.ar3criaraplicativos\fleb.Ele foi baseado nas eipecificag6es do Servlet i ao jSn a.fUa"rna'JavaEnterprise
Edition fava EE). Parafazrr esteexame, 6 necessirio que o candidato seja um ProgramadoiJava Cenificado pela Sun. ^

O exame de Desenvolvedor de Componentes de Neg6cios (CX-3 l0-090)


Desenvolvedor & Componentes de Neg6cios Certificado pela Sun na Pl ataformaJavaEE (SCBCD)
O exame de desenvolvedor de componentes de ne.g6cios foi elaborado para os candidatos que estejam usando a tecnologia
Java.EJB para criaraplicativos de camada de neg6cios. O exame se baseii na especificaglo f;n deirnida naJava Enterprise*
Edition flava EE). Para fazer este exame, 6 necessirio que o candidato seja um ProgramadorJava Certificado pela Sun.

O exame de Desenvolvedor de Servigos Web (CX-3 lO-220)


Desenvolvedor de Servigos \feb Certficado pela Sun na PlataformaJava EE (SCDIWS)
O exame de servigos web tem como alvo os candidatos que estejam criando aplicativos com tecnologiasJava EE eJava \7eb
Services Developer Pack. Para fazer este exame, 6 necessi.rio que o candidato seja um ProgramadorJaia Clrtificado pela Sun.

o exame de Projetista (cX-3 | 0-05 | , cx-3 | 0-300A, cx-3 | 0-06 | )


Projetista Empresarial Cenificadopara a Tecnolo 1gr_J2EE (SCEA)
Essa certificagXo se destina a projetistas empresariais e, ponanto, nio requer que o candidato passe no exame de
Programador. O exame de Projetista tem tr6s panes: uma prova de mriliipla escolha baseadaim conhecimentos, um
projeto de arquitetura e um teste de acompanhamento com quest6es dissertativas. VocA precisa passar na prova de multipla
escolha antes de se registrar e receber a tarefa do projeto.

O exame M6vel (CX-3 | 0-0 | l)


Desenvolvedor & Aplicativos M6veis Certi{icado pela Sun paraJava ME (SCMAD)
O exame de. dese1,volv9d91{e aplicativos m6veis 6 para candidatos que esejam criando aplicativos para telefones celulares
ou outros dispo_sitivos habilitados paraJava. O e_xame aborda a espeiificagio Java Technology for 'rt/ireless Indusry
[T\fl),
-
a API lil/ireless Messaging e as APh Mobile M edia.Parafaznr este exame, 6 necess6rio que o iandidato seja um SCJir.

Fazendo o exame de Programador


Em um mundo ideal, vocA seria avaliado-p-or seu conhecimento efetivo em um assunto e nio simplesmente pelas respostas
gu9. d9y a.varias perguntas de um e*ame. Mas a vida nXo 6 perfeita e nem 6 pritico avaliar o conhecimento de v6rias p.iro".
individualmenre.
Na maioria de seus exames de cenificaglo, a Sun avalia os candidatos usando um servigo de teste baseado em computador e
operado pela SyJvan Promet'ic. Esse servigo 6 bem popular na indfstria e usado por v6rios programas de cenificag?o de
outros fornecedores, incluindo o CNE da Novell e b MCSE da Microsoft. Gragas a grande luaitidade & filiais daSylvan
Prometric, os exames podem ser administrados em todo o mundo, geralmente na riesm" cidade do candidato.
Geralmente, os exames da Sylvan Prometric apresentam um funcionamento semelhante para todos os fornecedores. No
entanto, h6 um fato imponante a se conheceriobre os exames da Sun: eles usam o formaio tradicional de te*e da Sylvan
Prometric e nio o adotado recentemente. Isso d6 ao candidato uma vantagem, j6 que o formato tradicional permiteque as
repostas sejam revisadas e refeitas durante o teste.

oBSERVAQ6TS pene O E)GME

Muitos candidatos expeientes em testes ndo voltam ds respostas para aberi-las a menos que tenham ama boa raqdo parafaqer isso. Sti altere
t'tlila rePorta qaando achar que pode ter interpretado mal ou se enganado na primeira kitura que
feq de ama perganta. O neruositmo pode
faler com que uoci encontre ama ugunda rerpotta para cada perganta deixando a cotrcta de lado.

Para desencorajar.a simples memorvaglo,os exames da Sun apresentam um conjunto potencialmente disinto de perguruas
para candidatos diferentes. Na elaboragio do exame, centenas de perguntas sio compiladas e aprimoradas pot t.tt"doi.t
beta. Desse co{gnto volumoso, sio extraidx as perguntas referentei a cada objetivo que, posteriormente, sio reunidas em
v6rias vers6es diferentes do exame.
xxtl
Cada exame da Sun tem uma quantidade especifica de perguntas (o exame de Programado r conr6:mT2 Perguntas) e uma
duragio para o teste (175 min.ttos p"t" o r*ame de Programador). Normalmente, otempo destinado ao teste 6 generoso' O
rcmpo remanescente 6 sempre exiLido no canto da tela-de teste, junto com a quantidade de perguntas que faltam. Se ele
expirar durante o exame, o ieste seri encerrado e as respostas incompletas serio consideradas incorretas.
No final do exame, seu teste ser6 imediatamente avaliado e o resultado exibido na tela. As notas obtidas em cada assunto
tamb6m serio fornecidas, mas o sistema nio indicar6 que pe{guntas especificas est avamincorretas. Um relat6rio seri
impresso automaticamente na mesa do inspetor para que voc6 possa arquiv6Jo. A nota do teste 6 transmitida
eletronicamente para a Sun.

oBSERVAQ6ESpeneTE)(AME
puando uocd n sentir confurc ao retponderpergantas de nilltipla escolha, use seu rascunho para anotar as duat ou h€s respostas que
conddera as mais pttadaeit e, em seguida, vtblinbe a @osta qw acha que possiuelmente i a corwta. Aqai utui un exemplo de como fcani seu
rascanho qaando uocljd tiuerpercorido 0 terte t/ma ueg

2l.BouC

)3.AouC

Iso uriexlrenamente titil paa uocl marcar a petgilflta e darpmsseguinenta Posteriorrzente, podeni retomar e resgatar inediatamente na
raciocinio deonde parou, Enpregte esa timica para euitar ter que reler e reaualiar ar pergantas. Voc6 tambim tenl que usar seu raseanho em
perguntat de andio nrnplexo, baseadas em texto, para criar imagens de nodo a compreender aelhor a qtestdo, Esa ticnica senl
especialmente itil se aocd tiuer naisfacilidadt em c@tar conceitot uisualmente,

Formato das perguntas


Os exames da Sun sobre Java apresentam as perguntas no formato de mriltipla escolha o v de arrxtar-e-soltar. Em vers6es
anteriores, quando lhe era apresentada uma que$io de mtltipla escolha, voc0 nXo sabia quantas respostas estavam corretas'
por6m, a cada versXo do exame, as respostas ie tornaram mais dificeis, de modo que, atualmente, a pergunta informa
quanras respostas t6m que ser selecion-adas. As perguntas do Teste Individual, encontrado no final de cada capitulo, t6m
quase o meimo formato, redagXo e nivel de dificuldade das perguntas do exame real, com duas exceg6es:

r Sempre que possivel, as nossiu quest6es NAO lhe dirio quantas respostas corretas existem (diremos "marque todas as
corretas"). Faremos isso para lhe ajudar a dominar o material. Alguns alunos experientes com testes poderiam eliminar
t
.r tpott"s erradas se soubessem o nrlrmero de respostas corretas. Tamb6m 6 possivel, quando vocd sabe quantas e$eo
corretas, escolher as respostas mais plausiveis. Masb nosso trabalho 6 p repar!-lo paraas dificuldades que encontrarA no
enamereal!
I O exame real normalmente numera as linhas de c6digo de cada questio. N6s normalmente nlo as numeramos - a
principal razio 6 para termos espago para adicionar comentirios onde necessirio. No exame real, quando uma listagem
de c6&go comegar pelo 1, isso indicique se trata de um arquivofonte inteiro. Se a listagem comegar por um nfmero
maiordo que 1, significa que se trata de um arquivo-fonte parcial. Quando se tratar de um arquivo-fonte parcial, as$una
sempre q.ri a parte ausente do c6digo est6 correta (por exemplo, a nio ser qrre esteja dito explicitamente o contririo, voc6
pode assumir que um arquivofonte parcial tem as instrug6es impon e package corretas).

Quest6es de Arrastar-e-Soltar
Embora muitos outros exames de certificagio Java da Sun venham usando quest6es de arrastar-e-soltar h6 v{rios anos, esta
6 a primeira versio do exame SCJP que inclui esse tipo de questio. Como discutimos anteriormente, as questSes do exame
que voc0 recebe sio sorteadas aleatoriamente, mas voce pode esperar que cercade2) a25olo das quest6es serXo do tipo
arrastar+soltar,
As quest6es arrastar+soltar normalmente consistem de tr6s comPonentes:

I Um cenirio Uma pequena descrigXo da tarefa que voc6 deverireaJizar.

I Uma tarefa parcidmente redizada Uma listagem de c6digo, uma tabela ou uma irvore de diret6rios. A tarefa
parcialmente realizxla conter6 espagos em bran6, indicadoJcom caixas (normalmente amarelas). Essas caixas devefro
ser preenchidas para se complet ar atarefa.

I Um conjunto de fragmentos r€presentando respostas possiveis VocA clica nos fragmentos (normalmente caixas
azuis) e os arrasta para o espago em branco correto. O cenario da questio lhe diri se voc6 pode reutilizar fragmentos.

A maioria das quest6es de arrastare.sohar teri cerca de 4 a L0 espagos em branco para serem preenchidos, e normalmente
mais fragmenros do que o necess6rio (alguns fragmentos sio deixados sem utilizagio). As quest5es de arrastar-e-soltar
freqiientemente sio as mais complexas do exame, e o ntlmero de possiveis combinag6es de respostas as tornam quase
impossiveis de "chutar".
JAVA 5 XXIII
oBSERVAe6rspeneonl<eME
No que n ,trto fu questdes de arrastar-e-soltar, h,l um grande problena com o software de teste em muitos dos centros Pmmetric em todo o

mundo. Em geral, o nfhaare lbe penzite reuisar at questdes que jd respondeu qilantas aerys quiw.

No caso dasqautdu de arrastar-e-so/tar, entretanto, maitos candidatos tim relatado qae, se eles pedirem para reuer a questdo, o nfwaru
aPaga a rerpo$a anteioreil CUIDADO! Ati qae ese problena s/a nrrigido, recomendamos qae aocd mantenba uma lista de quait quutdet
sdo de anastar-e-so/ta6 para que ndo reuise rma sem qaerer. Outra boa iddia d anotar as rerpostat duse tiPl de qilesfil, de modo qile se iltua

for @agada, nrificil drgitar noaanente a rerporta.

Isso nos rerlete a ouho problema que os candidatos tdm re/atado. O cenhx de teste deueia lhefornecer o ruateria/ necesnirio para que uoei
pora traba/har nas questdes En
algurc casos, os centrosfomeeeram marcadores e qaadm in@ropriadog por urem peqilefllr
por escrito.
denais e dficeis de uvr efetiuamente. Rtcomendamos qae uoc6 aeifque, antes do dia do examq se receber,l do cenhv kpis ou caneta e pelo
menos algumatfolhar de papel en branco.

Dicas para a hora do exame


H5,72 pergontas no exame 31G055 $ava 5). VocA ter6 que acertar pelo menos 43 delas para passar - acima de 59 por cento.
Essas informag6es estio zujeitas a alterag6es. Confirme sempre
O tempo para conclusio do exame ser6 de quase tr€s horas.
com a Sun emwww.suned.sun.com, antes deprestar o exame.
. VocA pode responder as perguntas em qualquer ordem e tamb6m pode volt ar paramarcol suas respostas depois que tiver
percoirido otlste. Nio hi penalidades para as respostas erradas, ponanto, 6 melhor marcar uma resposta do que deixar uma
Perguntaem branco,
Uma estrat6gia adequada ao fazer o exame 6 percorr€Jo uma vez e responder todas as perguntas que souber de imediato.
F.m seguida, voc6 poder6 voltar e responder as outras. Responder uma pergunta pode fazer com que se lembre como
responder a anterior.
Seja muito cuidadoso com os exemplos de c6digos. Primeiro, procure erros na sintaxe, conte as chaves, sinais de ponto e
virgula e par6nteses e ceftifique-se se h6 a mesma quantidade desses simbolos na abeftura e no fechamento. Procure erros na
colocagio de letras maiusculas e outros problemas de sintaxe antes de tentar descobrir qual a fungXo do c6digo.
Muitas das perguntas do exame dependerio de minricias da sintaxe. Voc6 precisar6 de um conhecimento consistente da
linguagemJava para que seja bem sucedido.

Dicas que podem ser aplicadas no estudo para o exame


Antes de tudo, reserve bastante tempo para o estudo. AJava 6 uma linguagem de programagio complexa e voc€ nio pode
esperar apreender tudo que precisa siber em uma revisio ripida feita em uma inica sessio de estudo. Trata-se de um campo
que vai sindo m.lhor corttpreendido com o tempo, atrarr6s do estrrdo de um assunto e posterior aplicagXo do
Conhecimento. Elabore uma programagio de estudo e atenha-se a ela, m as seja razoivel com a carga atribuida,
principalmente se estiver estudando ao mesmo tempo em que executa suas tarefas di6rias no trabalho.

Uma t6cnica ficil, que pode ser usada nos estudos para os exames de cenificagio, 6 a dedica$o durante 15 minutos di6rios.
Simplesmente, est;de aurante um minimo de 15 minutos todo dia. E um compromisso infimo, por6m, significativo. Se_
houver um dia em que voc6 nXo consiga se concentrar, entio, pare quando chegar aos 15 minutos. Se em outro dia o estudo
fluir muito bem, est^ude mais. Se a quintidade de dias em q,re i.rdo fluir bem fo-r maior, suas chances de ser bem sucedido
serio bastante altas.
E r.comendivel que voc6 use can6es pedag6gicos ao se preparar para o exame de Programador . O canio
"lt"-.trt. 6 simplesmente uma ficha 3X5 ou 4X6 com uma pergunta na frente e a resposta atris. Crie voc6 mesmo esses
pedag6gico
cart6is quando passar por um capinrlo e inclua qualquer item que considere precisar de mais memorizagio ou tempo de
pr6tica. Com elis, voc6 pode se iuto -avaliar fazendo a leitura da pergunta, buscando a reposta na mem6ria e depois virando
o cartio para ver se acertou. Ou pedir a outra pessoa que o ajude, segurando o cartio com o lado da pergunta virado para
voc6 e verificando a reposta em seguida. A maioria de nossos alunos achou esses cart6es extremamente iteis,
principalmente porqui sio tio pequenos que enquanto vod estiver estudando, poderi lev6-los para qualquer lugar. No
entanto, 6 melhor nlo us6-los ao dirigir, exceto quando parado no sinal vermelho. Levarnos os nossos para todos os
lugares - o consult6rio m6dico, restaurantes, teatros, onde puder imaginar.

Os grupos de e$udo para a certificaglo 6 outro recurso excelente e vocA nXo encontrar6 uma comunidade maior ou mais
participativa do que nos f6runs Big Moose Sallon do javaranch.com. Se tiver uma pergunta relacionada a este livro, ou de
qualquer outro eiame simulado com o qual se deparar, ao envi|-laparaumf6rum sobre a certificagXo voc6 obteri a resposta,
em quase todos os casos, dentro de um fi4 e na maioria das vezes, em algumas horas. VocA nos encontrari por [6 (os
autore$ v6rlsvezes por semana, ajudando as pessoas que estXo iniciando.sua jornada de preparagXo para o exame. (Voc6
nio conseguiri pensar em nada que soe tao bem como a p alavra"jornada" quando estiver se preparando para o exame).
Finalmente, recomendamos que voc6 escreva v6rios pequenos programas emJava! Durante a escrita deste livro, n6s
escrevemos centenas de pequenos programas, e se voc6 der ouvidos ao que dizem os candidatos mais bem-sucedidos (tipo
aqueles com m6dia 987o), eles sempre relatam que escreveram muito c6digo como pane do estudo.
xxtv
Agendando seu exame
Os exames slo contratados na propria Strn, mas sio agendados diretamente com a Sylvan Prometric. Para locais fora dos
Estados Unidos, o nimero de contato de onde voc6 estiver poder6 ser encontrado no site Web da Sylvan, que fica no
enderego http :/ /www.2tex.com. Os representantes da Sylvan poderio agendar seu exame, mas nio terio informag6es
sobre osprogramas de cenificagXo. Perguntas sobre a certificaglo devem ser dirigidaspara o depanamento de Treinamento
Internacional da Sun. Esses representantes estio suficientemente familiarizados com os exames para encontri-los por
nome, mas ser6 melhor se voc6 tiver o nrimero do exame especifico ) mio quando falar com eles. Afinal, voc6 nlo iria gostar
se lhe agendassem e cobrassem o exame errado.

Os exames podem ser agendados at6 com um ano de anteced6ncia, embora isso nio seja realmente necess6rio. Geralmente,
agendA-lo com uma ou duas semanas de anteced6ncia seri o suficiente para voc6 reservar o dia e a hora que preferir. No
momento do agendamento, os operadores procurario centros de teste em sua irea. Por conveniOncia, eles tamb6m poderio
informar em que centros de teste voc6 j6 esteve.

Quando voc6 se registrar no exame, o n{rmero de sua identificag1o ser6 solicitado. Esse nrimero ser6 usado no envio dos
resultados de seu exame para a Sun. E importante que voc6 use o mesmo nrimero de identificaglo sempre que se registrar,
para que a Sun possa acompanhar seu progresso. As informag6es de enderego fornecidas quando vocA se registrar pela
primeira vez tamb6m serio usadas pela Sun para enviar os certificados e outros materiais relacionados. Nos Estados
Unidos, geralmente o n{rmero de seu seguro social 6 usado como nrimero de identificagio. No entanto, a Sylvan pode lhe
fomecer um nirmero exclusivo de identificacio.

Chegando no local do exame


Como em qualquer teste, voc6 fic arS"tentado afaz.er uma revisio r6pida na noite anterior. Resista a essa tentagio. Voc6 jl deve
conhecer o material a essa altura e se estiver muito sonolento pela manhi, nio se lembrari o que esnrdou. Tenha uma boa
noite de sono.

Chegue cedo no exame; isso lhe dar6 tempo para relaxar e revisar os fatos essenciais. Aproveite a opornrnidade pa ra rever
suas notas. Se estiver cansado de estudar, talvez possa comegar seu exame alguns minutos antes. Por outro lado, nio
recomendo chegar tarde. Seu teste poderia ser cancelado ou voc6 pode nio ter tempo nrficiente para concluir o exame.

Quando chegar no centro de testes, voc6 teri que se inscrever com o inspetor do exame. Para se inscrever, ser6 preciso
fornecer dois tipos de identificagio. Os tipos aceitos sio identificag6es emitidas pelo governo (por exemplo, passaporte
ou habilitagio de motorista), cart6es de cr6dito e crach6s de empresas. Sua fotografia deve consrar em uma das
identificag6es. Eles s6 estario se certificando se voc6 nio enviou, em seu lugar, seu vizinho brilhante emJava, a quem
pagou para fazer o exame.

Al6m de um c6rebro repleto de informag6es, vod nio precisar6levar nada mais para o exame. Na verdade, seu c6rebro ser6
tudo que poder6 levar! Todos os testes devem ser feitos com os livros fechados, o que significa que voc6 nio precisa levar
nenhum material de consulta. Tamb6m nXo poderi levar nenhuma nota ao sair da sala do exame. O inspetor do teste lhe
forneceri papel e caneta. Alguns centros & teste podem fornecer uma pequena prancheta em vez disso. Recomendamos que
voc6 leve uma garrafad'|goa. Duas horas 6 muito tempo para manter seu c6rebro em atividade e ele funcionar6 melhor se
estiver bem hidratado.

Deixe seu pager e telefone no carro ou desligue-os. Eles s6 deixario a situagio mais tensa, ji que nio sio permitidos na sala
do exame e talvez ainda possam ser ouvidos se tocarem fora da sala. Bolsas, livros e outros materiais devem ser deixados
com o inspetor antes que voc6 entre na sala do exame.

IJma vez na sala de testes, o inspetor se conectar6 com seu exame e vocO ter6 que verificar se seu nrimero de identificagio e o
ntmero do exame esteo corretos. Se for a primeira vez que voc6 estiver fazendo um teste da Sun, poder6 selecionar um
tutorial resumido existente no software do exame. Antes de o teste comegar,. serio dadas informag6es sobre o exame,
incluindo a duragio, a quantidade de perguntas e a nota exigida para passar. E bastante prov6vel que seja pedido que voc€
responda a uma breve pesquisa antes de o exame propriamente dito comeEar. Essapesquisa lhe perguntar6. sobre o seu
nivel de experiAncia em Java. O tempo que voc6 gastar n a pesquisa nio ser6 retirado do tempo propriamente dito do seu
teste - nem voc6 ter6 mais tempo se responder a pesquisa rapidamente. Lembre-se tamb6m de que as quest6es no seu
exarne ndo serio modificadas dependendo dx respostas que der i pesquisa. Em seguida, o rel6gio comegar6 a funcionar e a
diversioteriinicio.
O sofrware do teste 6 executado no rVindows, mas vod nXo ter6 acesso a 6rea de trabalho principal ou a qualquer acess6rio.
O exame ser6 apresentado em tela cheia, com somente uma pergtrnta por tela. Os bot6es de navegagio permitirio que voc6
se mova para baixo ou para cima entre as perguntas. No canto superior direito da tela, contadores mostrario a quantidade
de perguntas e o tempo remanescentes. O mais importante 6 que haver6 uma caixa de selegio chamada Mark no canto
superior esquerdo da tela - essa ser6 uma ferramenta importantissima, como explicaremos na segio seguinte.
JAVA 5 x)O/
T6cnicas para fazer o teste
Sem um plano de ataque, os candidatos serio subjugados pelo exame ou serio deixados para tris e ficario sem rempo.
Geralmente, quando.estamos familiarizados co- o material, o tempo estipulado 6 mais io que suficiente para a conclusio
^
do exame. O truque 6 nio perder tempo em algum problema especiiico.

O objetivo 6bvio de um exame 6 que as.perguntas sejam respondidasde maneira eficaz, mesmo que ourros aspecros
possam distraiJo. Aqui estlo algumas dicas paraf.azer o exzLme mais eficientemente.

Avalie o desafio
Primeiro, d6 uma passada r6pida por todas as perguntas do exame. Elimine as f6ceis, respondendo.as imediatamente. Leia
rapidamente.cada pergunta, observando seu tipoi assunto. Como diretriz, tente gastar^menos do que 25 por cento de seu
tempo nessa leitura.
Essa etaPa permitil6 q.ue vogQ
ryalie o escopo e a complexidade do exame, lhe ajudando a dererminar como conrrolar seu
tempo' Tamb6m dari uma id6ia de onde encontrar possiveis respostas para algumas das perguntar. As ,r.zes, redagio Je
umapergunta pode darpistas ou trazer a sua mem6iia outrapergurua. "

Se voc6 nXo estiver totalmente ceno de sua reposta a uma pergunta, responda assim mesmo, mas marque a caixa Mark para
indig.ar W9
fve
fazer uma revisio.posterior nela. Caso voc6 fiqrr. r.*
i.ntpo, pelo menos ter6 forneci'do r pri*.ir" t fjrt"
que lhe veio i cabega, em vez de deix6Ja em branco.

Em segundo lugar- rwise todg o teste, empregando a percepglo que obteve na primeira leitura. Por exemplo, se o teste
inteiro parecer dificil, voc6 saberi que nio poder6 gastar mais de circa de ,r- *irr.rto .- cada pergunta. Dirrij, o ..*po e*
pequenos blocos - Por exemplo, "Preciso responder L0 perguntas a cada 20 minutos".
Nesse estigio, provavelmente seri uma boa id6ia saltar as pergunras que exigirem mais rempo, marcando-as para a pr6xima
leitura. Tente terminar essa fase antes de chegar a 5G6O por cJnto doiempJdo teste.
Em terceiro lugar, leia todas as perguntas que voc6 marcou para revisar, usando o botlo Review Marked da tela de revisio de
Perguntas. Essa etapa inclui uma segunda leitura de todas as perguntas cujas respostas foram dadas sem cerreza, assim
como responder as que exigem maistempo e que ,rocA posteigori at6 agora. Responda como achar melhor esse conjunto de
perguntas ate que as tenha responctldo por completo.

Se voc6 estiver mais seguro para responder uma pergunta que marcou, desmarquea agora. Do contririo, deixe-a marcada.
V6 trabalhando nas perguntas que exigirem mais tempo, principalmente as qrr. n ..tiit"rcm de c6lculos manuais.
-
Desmarque-as quando estiver satisfeito com a resposia.

Ao final dessa etapa, voc6 ter6 respondido todas as pergpntas do_teste, apesar de nlo te r ceneza em alzumas das respostas.
Seficar sem tempo na pr6xima etipa nio perder6 pbntos pela falta de uma pergunta. Estar6 bem se aiida tiver 1O-2b por
cento de tempo remanescente.

Revise suas respostas


Agora voc6 est6tranqiiilo! Respondeu a todas as perguntas e estA pronto par afazer smaverificaglo apurada. Faga outra
leitura (sim, mais uma) em todo o teste (embora talvez seja uma^boa id6ia nio revisar as quest6ls de arrastar-e-soltar!),
relendo rapidamente cadapergunta e sua resposta.
Repasse as perguntas cuidadosamentg-qais rlma vez para procurar "pegadinhas". Fique panicularmente arento para as que
incluirem a opgio "N5o 6cotttpil"t".Eseja alenapara pistas de riliirnahora. VocO j6 eiti bem familiarizado com quase
todas as perguntas a essa altura e pode encontrar algumas pistas que nio tinha visto antes.

O grande final
Quando estiverconfiante de todas as respostas, termine o exame enviando-o para avaliagio. Depois, do que parecerio os LO
segundos mais longos de sua vida, o software do teste retornar6 sua nota. Geialmente, ela 6 exibida em um gr6fico de
barras, que mostra a nota minima exigida, a nota obtida e um indicador PASS/FAIL.

Sevoc6 estiver curioso, poder6 ver sua m6dia de pontos nesse momento. Nio serio apresentadas as repostas a pergunras
as perguntasserio reunidas em categorias e serio registradoirenrltados para c.d, cat"gorl. Ett.
especificas; em vez disso,
detalhe tamb6m estari em um relat6rio que teri sido impresJo auromaticaminte na mesa do inspetor do exam?.

Quando voc6 sair do local do exame, ter6 que deixar seu rascunho para tris ou entreg6Jo ao inspetor. (Alguns centros de
teste registram o nfmero de folhas que sio fornecidas, para tetem certezade que tod-as serio devolvidas). Em troca, vocp
receber6uma c6pia do relat6rio do teste.

Esse relat6rio terl a marca do centro de testes gravada e voc6 deve guardiJo em um local seguro. Normalmente, os
resultados sio transmitidos automaticamente para a Sun, mm podi r.r q.te voc6 precise doielat6rio emitido para provar
que Passou no exame.
x)o/r
Em algumas semanas, a Sun lhe enviar6 um pacote pelo correio contendo um bonito cenificado, um alfinete de lapela e
uma carta. Tamb6m podem lhe enviar instrug6es di como contratar o tabalho artistico para criaSo de um logotipo que
voc6 poderiusar em cart6es de visitapessoais.

Fazendo novamente o teste


Se voc6 nio passar no exame, nio perca a esperanga. Tente aproveitar o que ganhou com a experiAncia e preParese Pararcntar
,ro1r"rn.rrr..'Considere.se um po.tco -"is informado. Voc€ conhece o fbrmato do teste um Pouco melhor e o relat6rio
mostrari que ireas vod precisa fortalecer.
Se fizer o teste mais uma vez sem demora, provavelmente voc€ se lembrari de virias das Perguntas que pode ter errado.
Isso o ajudari a concentrar seus estudos na area certa'

Paraconcluir,lembrese que as ceftificag6es daSun sXo vdiosas, pois sio dificeis deobter. Afinal, se qudquerpesoa
conseguisse, que valor teria? No final das contas, 6 necessirio uma atitude adequada e muito esnrdo, mas voc6 pode faz&lol
I
DeclaraE6es e
Controle de
"'
Acesso

Oblerlvos pqru o
Gerrlflcqf6o:

I Decloror Closses e Interfoces


I Desenvolver Inlerfoces e Closses
Abstroct
I Usor Primitivos, Arroys, Enums e
ldentificodores Legois
I Usor M6todos Stotic, NomeoEdo
JovoBeons e Vor-Args
I Exercicios R6pidos

P&R Teste lndividuol


2 Copitulo 1 : DecloroE6es e Conirole de Acesso

N6s partiremos do principio de que, uma vez que esti planejando obter a cettificagio, voc€ i6 sabe o bisico deJava. Caso seja
completamente iniciante na linguagem, este capinrlo - e o restante do livro - ser6 confusq entio, certifique-se de que voc6
sabe pelo menos o b6sico da linguagem antes de mergulhar neste livro. Dito isso, comegaremos com uma revisio para
refrescar a sua mem6ria sobreJava, caso tenha estado afastado da Jinguagem por algum tempo. i

Revisio de fava
Um programa emJava € principalmente uma colegdo de objetos falando com outros obf etos por meio da invocagio dos .

m6todos uns dos outros. Cada objeto 6 de um tipo, e esse tipo 6 definido por uma classe ou uma interface. A maioria dos
programas emJava usa uma colegio de objetos de muitos tipos diferentes.
I Classe Um modelo que descreve os tipos de estado e de comportamento que os objetos do seu tipo podem ter.
I ObietoNomomentodaexecugio,quandoaM6quinaVirtualJavaflavaVirtualMachine,ouJVlvf eflcontt^^p^l^.rra-
chave new, ela usa a classe aproprtadapara criar um objeto que seri uma instAncia dessa classe. Esse obieto ter6 o seu
pr6prio estado e ter6 acesso a todos os comportamentos definidos pela sua classe.
I Estado (vari6veis de instdncias) Cada objeto (instdncia de uma classe) ter6 o seu conjunto rinico de vari6veis de
instAncias conforme definido na classe. Coletivamente, os valotes atribuidos is variiveis de instincias de um obieto
compdem o estado do objeto.
I Comportamento (m6todos) Quando um programador cria uma classe, ele cria m6todos para essa classe. E nos
m6todos que a l6gica da classe 6. armazentda. Nos m6todos, o verdadeiro rabalho € rczLzado. E neles que os
algoritmos sio executados e que os dados s6o manipulados.

ldentificadores e Palavras-chave
Todos os componentes deJava de que acabamos de falar - classes, vari6veis e m6todos - precisam de nomes. EmJava,
esses nomes sio conhecidos como identificadores e, como seria de se esperar, existem regtas dizendo como devem ser os
identificadoresJava permitidos. Independentemente do que 6 permitido, no entanto, os programadoresJava (e a Sun)
cianmconveng6esparaafiome giodem6todos,vari6veiseclasses.Comotodasaslinguagensdeprogramagdo,Javatem
um coniunto de palavras-chaves internas. Essas palavras-chave nio podem ser usadas como identificadores. Mais adiante
neste capitulo, veremos os detalhes sobte essas regras e conveng6es de nomeagio, e sobre as palavtas-chaveJava.

Heranga
Fundamental pataJava e outras linguagens orientadas a objetos 6 o conceito de hetanga, que permite ao c6digo definido em
uma classe ser reutilizado em outras classes. EmJava, voc6 pode definir uma supetclasse geral (mais abstract), e depois
estend,3-la com subclasses mais especificas. A superclasse nio sabe nada sobre as classes que herdam dela, mas todas as
subclasses que herdam da superclasse ptecisam declarar explicitamente a relagdo de heranga. Uma subclasse que herda de uma
superclasse recebe automaticarnente as vari6veis de instAncias acessiveis e os m6todos definidos pela superclasse, mas 6
tamb6m livre para substituir m6todos da superclasse para definir comportamentos mais especificos.

Por exemplo, :uma npercIasse Carro poderia definir m6todos gerais comuns a todos os autom6veis, mas uma Jrlklasse
Ferrari poderia substituir o m6todo acelerar ( ) .

Interfaces
Um poderoso companheiro da heranga 6 o uso das interfaces. Ainterface 6 uma esp6cie de superclasse 100% abstricE
que define os m6todos que uma subclasse deve suportat, mas ndo como esse suporte deve ser implementado. Fm odtras
pilavras,umainterfaceAnimal poderiadeclanr que todas as classes de implementagio de Animal devem ter um m6todo
comer ( ) ,mas ainterfaceAnimalnlo fornecenenhumal6gicaparaom6todo comer ( ) .Isso significaque ftcaacargo
das classes que implementam ainterface Animal a definigio do c6digo para como cada tipo particular de Animal se
comporta quando o seu m6todo comer ( ) 6 invocado.

Encontrando Outras Classes


Como veremos mais adiante no livro, 6 uma boa id6ia manter a coesio das suas classes. Isso significa que cada classe deve tet
um coniunto bem definido de responsabilidades. Por exemplo, se fosse criar um progtam de simulagio de um zool6gco,
voc6 representaria javalis com uma classe, e visitantes do zool6gico com outra. Al6m disso, voc6 poderia ter uma classe
Tratadot de Animais, uma classe Vendedor de Pipoca e assim por diante. A questio 6 que voc€ nio deve ter uma classe que
tenha comportamentos deJavali e Vendedor de Pipoca ao mesmo tempo (falaremos mais sobre isso no Capitulo 3).

At6 mesmo programasJava simples usam obietos de muitas classes diferentes: algumas que voc6 criou, e algumas criadas
por outros (tais como as classesJava API da Sun).Jwa orgatizaas classes em pacotes, e usa declaragdes import pan dar
aos programadores uma forma consistente de gerenciat anomeagdo das classes de que precisam e o acesso a elas. O exame
aborda v6rios conceitos relacionados aos pacotes e ao acesso a classes; exploraremos os detalhes neste e em outros capitulos.
JAVA 5 3

Al_r r. ..t.
\Joleilvo poro o Lentttcocoo
^

ldentificadores e favaBeans (Objetivos 1.3 e 1.4)


l.J Detenuoluer cddigo que dulare, inicialiqe e ase primitiuos, atraJs, enumr e objetos como uaridueis stat ic, de instdncias e locais. Ahn
disto, usar identifcadoret legais para nomes de uaridaeis.

l.4Desenuoluercddigoquedularemdtodosstatic en1o-sLaLic'e,seapropriado,usarnomesdemdtodosqueobedegamaospadrdu
Aldm disso, desenuo/uer nidigo que declare e t/se ama /ista de argamentos de extensio uai,iiel.
de nomeagdo JauaBeans.

Lembre-se de que, quando listamos um ou mais Objetivos pata a Certtftcagdo no livro, como acabamos de fazer, isso
significa que as seg6es a seguir abordario pelo menos parte desses objetivos. Alguns objetivos serio abordados em
v6rios capitulos diferentes, de modo que voc€ ver6 o mesmo obietivo em mais de um lugar do livro. Por exemplo, esta
segio cobre declarag6es, identificadores e nomeagioJavaBeans, mas o uso do que voc€ vai declant ser6.abordado em
capitulos posteriores.
Assim, comegaremos com os identificadotesJava. Os tr6s aspectos dos identificadoresJava que abordaremos aqui sio:
I Identificadores Legais As regras que o compilador usa para determinar se um dado nome 6legal.

I Conveng6es de C6digo Java da Sun As recomendag6es da Sun para nomeagio de classes, vari6veis e m6todos.
Normalmente n6s obedecemos a esses padr5es em todo o livro, exceto quando estivermos tentando lhe mostrar como
seria uma questio dificil do exame. Nio lhe ser6o feitas perguntas sobre as Conveng6es de C6digoJava, mas
recomendamos enfaticamente que os programadores as usem.

I Padr6es de NomeagdoJavaBeans Os requisitos de nomeagio da especificagioJavaBeans. Nio 6 preciso estudar a


especificagioJavaBeans pata o exarne, mas voc6 precisa saber algumas regras b6sicas de nomeagSoJ"rrrB.*, q.r.
abordaremos neste capitulo.

ldentificadores Legais
Tecnicamente, os identificadores legais devem ser compostos apenas de caracteres Unicode, nrimeros, simbolos de moedas e
caracteres de conexio (como underscores). O exame nio mergulha nos detalhes de quais falras do coniunto de caracteres
Unicode qualificam como letras e digitos. Assim, por exemplo, vocd n6o precisar{ saber que os drgrtos em Tibetano v6o de
\u0420 at6 \u0f29. Eis aqui as regras que voc6 precisa saber:
I Osidentificadoresdevemcomegarcomumaletra,umcifrio($)ouumcaracterdeconexdo,comoounderscore(_).Os
identificadores nio podem comegar com um nfmerol
I DePois do primeiro c^r^cter,os identificadores podem conter qualquer combinagio de letras, caracteres de moedas,
caracteres de conexio ou nfmeros.

I Na pr6tica, nio h6limite para o nrimero de caracteres que um identificador pode conter.
I Nio se pode usar uma palavta-chaveJava como identificador. A Tabela 1-1 lista todas as palavras-chave Java. incluindo
uma novidade da versio 5.0, enum.

I Os identificadores emJava si.o case-sensitive; foo e Foo sio dois identificadores diferentes.
Seguem alguns exemplos de identificadores legais e ilegais; primeirq identificadores legais:
I nf a .

int gc,'
int 2 w;
int _$;
int eis_um_nome_bastant.e_detalhado3ara_um_identif icador ;
Os seguintes sdo ilegais (agora voc€ ji sabe o por qud):

int :Jr;
i ht -A .

int e#;
I nr I .

anE. /9,.
4 Copftulo 1 : Declorog6es e Conlrole de Acesso

Tobelo 1-l Listo Completo de Polovros-Chove Jovo (ossert odicionodo em 1 .4, enum odicionodo em 1 .5)

abstract boolean break byte case catch

char class const ^^nl_


i nlra default do

double else extends final finally float


for :Jvuv if implements import instanceof
int interface long nati-ve package
hri rt^l-a protected public return short staEic
strictfp super switch synchronized this throw
throws trans]-enE Ery void voLatile while
asserE enum

Conveng6es de C6digo lava da Sun


Pelas estimativas da Sun, ao longo da vida de um c6digo padrdo,2\oh do esforgo ser6 despendido na criagio e no teste
ftil
originais 6e 66digo, e 80% do esforgo seri despendido na manutengio e nas melhorias subseqiientes do c6digo. Concordar
com um coniunto de padr6es e programiJo aiudaadiminuir o esforgo envolvido em testar, fazer amanutengio e
melhorar qualquer c6digo. A Sun criou um con,unto de padr6es de programagdopanJavaepublicou esses padr6es em um
documento inteligentemente chamado de "Convengdes de C6digoJ ava",o qualvoc6 pode encontrar em iava.sun.com.
Trata-se de um 6timo documento, curto e f6cil de ler, que recomendamos enfaticamente.

Dito isso, vocd ver6 que muitas das quest6es do exame nio seguem as conveng6es de c6digo, devido is limitag6es do
programa de provas que 6 usado para minisftar o exame internacionalmente. Uma das boas coisas sobte as certificag6es da
Sun 6 que os exames sio administrados uniformemente em todo o mundo. Para se conseguir isso, as listagens de c6.ligos
que voc€ ver6 no exame real freqiientemerite sio bem bagungadas, e nlo seguem os padr6es de c6digo da Sun. Panprepat|-
lo pam o exame, n6s freqtientemente iremos apresentar listagens de ssdigos com uma aPar€ncia igualmente bagungada,
usando apenas dois espagos depatdgnfo em vez dos quatro espagos do padrio Sun'

N6s tamb6m bagungaremos nossas chaves de forma artificial, e, em alguns casos, colocatemos v6rias declatag6es na mesma
linha... oh nio! Por exemplo:
1. class Wombat implements Runnable {
2, private int i;
3. public synchronized void runO i
4. if (i*5 l= 0) { i++; i
5. for(int x=0; x<5; x++, i++)
6. { if (x > 1) Thread.yield0 ; }
7. System.out.print (i + " ") ;
8)
g. public st.atic void main(string[] args) t -
l-0. Wombat n = new wombat O ;
11. for(int x=100; x>0; --x) { new Thread(n).startO; }

L2. ) )
Considere-se avisado - voc€ ver6 v6rias listagens de c6digos, quest6es simuladas e quest6es de exames reais que serio
doentias e incompreensiveis dessa maneira. Ningu6m quer que voc6 escreva seu c6digo desse ieito. Nem o seu empregador,
nem os s..,s colegas de trabalho, nem n6s, nem a Sun e nem a equipe de elaboragdo do exame! Esse tipo de c6digo foi
criado apenas para que conceitos complexos pudessem ser testados usando-se uma ferramenta de provas universal. O rinico
padrio que 6 seguido tanto quanto possivel no exame rcaL6. o dos padr6es de nomeagio. Eis os padr6es de nomeagio
recomendados pela Sun, e que usamos no exame e na maior parte do livro:

I Classes e interfaces A primeira letra deve ser maifscula e, se v6rias palavras forem escritas iuntas para formar o nome, a
primeira leta d e cadapalavrainterna deve ser mairiscula (um formato chamado em inglBs de "camelCase'). Para classes,
os nomes devem normalrnente ser substantivos. Por exemplo:

Dog / /Cachorro
JAVA 5 5
Account / /Conta
Print.Wrj-ter / / Impressora
Para interfaces, os nomes devem normalmente ser adletivos, como:

Runnable //Execut6vel
Serializable / / Seria]-:-z5ivel
I M6todos A primeira letra deve set minriscula, e depois as regras camelCase normais devem ser usadas. Al6m disso, os
nomes devem normaknente ser pares de verbo-substantivo. Por exemplo:
getBalance / /obterBalango
doCalculat ion / / fazerC6lculo
setCustomerName / /de f inirNomeDoCl iente
I VariSveis Como nos m6todos, o formato camelCase deve ser usado, comegando com uma letra minriscula. A Sun
recomenda usar nomes curtos e significativos, o que nos parece uma boa id6ia. Alguns exemplos:
buttonWidth / / LarguraDoBotSo
accountBal ance / / balanqoDaConta
myString //minhaString
I ConstantesAsconstantesJavasdocriadasmarcando-sevariiveiscomostatic efinal.Elasdevemsernomeadas
usando-se leftas maifsculas com cafacteres underscore como seoaradores:

MIN_HEIGHT / /ALTURA_MINIMA

Padr6es favaBeans
A especificagioJavaBeans foiciadapanajudar os desenvolvedores a criarem componentesJava que possamser facilmente
usados por outros desenvolvedores em uma ferramenta de Ambiente de Desenvofvimento Integrado ("Integtated
. Development Environment, ou IDE), como o Eclipse ou o NetBeans. Como um programadorJava, voc6 desejard usar
componentes daAPIJava, mas seria excelente se voc€ pudesse tamb6m comp?br o componenteJava que quisesse no
"Mercado Beans", aquela loja de software queficana sua rua. E,-depois de enconffar os componentes, voc6 gostaria de
poder acessi-los atrav6s de uma ferramenta de desenvolvimento de forma tal que nio precise escrever todo o seu c6digo do
zero. Ao usar regras de nomeagio, a especificagdoJavaBeans ajuda a garantir que as ferramentas podetio reconhecer e usar
componentes criados por diferentes desenvolvedores. AAPIJavaBeans 6 um tanto complexa, mas voce s6 precisar6 estudar
alguns fundamentos para o exame.

Primeiramente,JavaBeans sio classesJava que tem propriedades. Para os nossos prop6sitos, pense nas propriedades como
vati6veis de instdncias private. Umavez que sdo private, a rinica maneira pela qual podem ser acessadas de fota da
sua classe 6 atav€s de m6todos da classe. Os m6todos que modificam o valor de uma propriedade sio chamados m6todos
tetter, e os m6todos que obt6m o valot de uma propriedade s6o chamados m6todos geLter. As regtas de nomeagio
JavaBean que vocd precisar6 saber par o exame sio as seguintes:

Regras de Nomeagao de Propriedades favaBean


I Se a propriedade r'do fot booleana, o prefixo do m6todo getter deve ser get. Por exemplq getsize ( ) 6 um
nome getterJavaBeans v6lido para uma propriedade chamada "size." Tenha em mente que voc6 n6o precisa ter uma.
vari6vel chamada size (embora alguns IDEs v6o esperar que voc6 tenha). O nome da propriedade 6 inferido a partir dos
t getters e setters, e nZo-atrav6s de quaisquer vari6veis da sua classe. O que vocd ir6 retornat a partir de gets i ze ( )
fica a seu critdrio.

I Se a ptopriedade for booLeana, o prefixo do m6todo getter 6 ou get ou is. Por exemplo, tanto
getSt.opped ( ) quanto isstopped ( ) sio nomesJavaBeans vilidos pataum^ propdedade booleana.

I O ptefixo do m6todo setter deve ser set. Por exemplo, setsize ( ) 6 o nomeJavzBeanv|Idopar^lma
propriedade chzmada s i z e.
I Pa:,a ter o nome completo de um m6todo getter ou settef, passe a primeira letra do nome da propriedade para
mairiscula e depois anexe o prefixo apropriado (get, is ou set).
I As assinaturas de m6todos setter devem ser marcadas como public, com um tipo de retorno void e um
argumento que represente o tipo da propriedade.
I As assinaturas de mdtodos getter devem ser marcadas como pubL ic, nio usar argumentos e ter um tipo de
retorno que bata com o tipo do argumento do mdtodo s et ter pan a ptopiedade em questao.
Em segundo lugar, a especificagiloJavaBean tem suporte a euentos, os quais permitem aos componentes notificarem uns aos
outros quando algo acontece. O modelo de eventos geralmente 6 usado em aplicag6es GUI quando urn evenro, como urn
clique do mouse, 6 comunicado para muitos outros objetos que possam ter cgisas a fazet qtando ocore um clique do
6 Copftulo 1 : DecloroE6es e Controle de Acesso

mouse. Os objetos que recebem ainfornagdo de que ocorreu um dado evento sio chamados de /isteners. Para o exame, voc€
precisa saber que os m6todos usados pata adicionar ou remover listeners de um evento devem tamb6m seguir padr6es de
nomeacio JavaBean:

Regras de Nomeagao de Listeners favaBean


I Os nomes de m6todos listeners usados para"reg|strar" um listener com ulna fonte de eventos devem usar o prefixo
add, segu.ido do tipo do listener. Por exemplo, addActionlistener ( ) 6 um nome v6fido para um m6todo que
uma fonte de eventos dever6 permitir a outros registrarem para eventos Act ion.

I Nomes de mdtodos listeners usados para remover ("desregistrar") um listener devem usar o prefixo remove, seguido
do tipo do listenel (usando-se as mesmas regras que o m6todo add de registro).
I O tipo de listener a ser adicionado ou removido deve ser passado como o argumento para o m6todo.
Alguns exemplos de assinaturas de mdtodos JavaBean vdl-idas:
public void setMyValue(int v)
public int getMyValue ( )
nrrlrl i a lrnnl
ysv4+v aan i cM\/ql-.1-rrc | )

public void addMylistener (MyListener m)


public void removeMylistener (MyListener m)

Alguns exemplos de assinaturas de m6todosJavaBezn inuilidar


void setCustomerName (String s) t
/ / nrcai sa sFr nrrl-r1ic
t ylvvlve

public void modifyMyValue(int v) / / n6.o se pode usar 'modify'


public void addXlistener{MyListener m) I
/ / crra
I eLLv da l- inn d. l-iStenef

oB SERYAQoBS pene O EXAME

O objetiuo diqque uoci precisa saber os identifcadoru legais para nzmes de uaridueis, mas as regras s6o ar nermas para TODOS os
sd
componentes Jaua. Assim, lenbre-rc d.e que un identifcador legalpara ilma aariduel tanbdn d legalpara un nitodo ou uma classe.
Entretanto, uocd deue distinguir entre os identifcadores legais e as conuengdes de norueagdo, tais como o: padrdet JauaBeafls, q//e indican cono
um determinado componente Jaua deue ser nomeado. En outras palauras, uocd deue ser capaqde reconheeer qae um dado identifcador d legal

mesml qile e/e ndo se conforme a padrdes de nomeapdo. Se a qaestdo do exame estiuer lhe perguntando sobre conuengdes de nomeapdo - e ndo

tzmente se um dado identifcador iri conpilar - os JauaBeaw serdo mendonados explidtamente.

Obietivo poro o Certificogdo

Declarar Classes (Objetivo l. I do Exame)


/.1 Desenuoluernidigo que dulare classes (incluindo claset absLracL e todas atformas de classu aninhadat), intefaces e enilm!, e

incluir o uso apropriado de dularagdes package e inport (incluindo irportagdu utriticas).


I
Ao escreve c6digo emJava, voc€ est6 escrevendo classes ou interfaces. Dentro dessas classes, como voc€ sabe, eistem
variiveis e m6todos (al6m de algumas outras coisas). O-- rSdq qq$o-vsc6 dgclara ag.qu?! 4g_q.q9!:.m(t9dgq 9 varj|y-etg cfsta.-
dramatic4lnente o qg4portamentadoseirc6digo. Pot exemplo, trlr!-lqeto.daJ:ublic pode set acessado a pattit do
c6dig:o que. es-tep Sgdandg em qualqu-er p4-r19 da s.ua,apliesa.g No entanto, l9-ve*-narcar esse m6todo coma pdlf4le-rg]g
&sapar*er?dg.pfo!_ggrAgh,res (94etoo ds glagpe qa qual f.oi-de.clarado). Para este objetivo, estudaremos as formas pelas
quais vocd pode declarar e modificar (ou nio) uma classe. Voc€ perceber6 que abordaremos os modificadores em um nivel
extremo de detalhe, e, embora saibamos que voc6 j6 es td famt\arizado com eles, comegaremos pelo b4sico. A maioria dos
programadoresJava pensa que sabe como todos os modificadores funcionam,m s,ao examinar cuidadosamente a questao,
descobre que nio sabem (ou pelo menos nio no nivel exigido pelo exame). Existem sutis disting6es em toda parte, entao
rer ceftezzabsoluta de que domina totalmente todos os assuntos dos objetivos desta segZo antes de fazet o
::;:....O"

Regras de Declarageo pa;ra Arquivos-Fonte


Antes de mergulhalrnos nas declatagSes de classes, fagamos uma breve revisdo das regras associadas com a declaragio de
classes, declarag6es import e declarag6es package em um arquivo-fonte:
JAVA 5 7
I 56 pode haver uma classe publ i c em cada arquivo de c6digo-fonte.
r Os comentirios podem aparecer no inicio ou no fim de qualquer linha no arquivo do c6digo-fonte;
eles sio
independentes de quaisquer regras de posicionamento diicutidas aqui.

f lsiaul,er-Jpa-clas,sepubli-cemumarquiv.o-o..-el^"rg"*odevesere.mesmodaclassepubfic.por
exemplo, uma classe declandacomo public cl-ass Dos
chamado Dog. j ava.
{ } precisa esrar em rr- ".qrlirro'd. c6digo-fonte
I Se a classe ltzet panede um pacote, a declaragio package deve estar na primeira linha do arquivo do c6digo-fonte, antes
de quaisquerdeclarag6es import que estejam presentes.

r Se houver declarag6es import, elas devem frcar enhe a declangdo package (se houver) e a declaragio da classe. Se nio
houver uma declatagdo package, entio a(s) declaragzo(5es) impoit deie(m) estar na(s)
primeirals; Iinha(s) do arquivo
do c6digo-fonte. Se n6o houvet declaragSes package nem import, a declatagiodu.t"i..
d.rr..sti na primeira linha do
arquivo do c6digo-fonte.
.,!
r
\, r As declarag6es import e package aplicam-se a todas as classes denffo de um arquivo de c6digo-fonte. Em outras
p palavras' nio 6 possivel declarar multiplas classes em um atquivo e t6las em diferentes
pacot;s, ou usar diferentes
importag6es.
\
".\ I Um arquivo pode ter mais de uma classe nio-public.
( I Arquivos que nio tenham classes pub 1 i c podem ter um nome que nio seja o mesmo de nenhuma
das classes do arquivo.
No Capitulo 10' discutitemos mais de talhes sobre as regras envolvidas com a dec langdoe o uso de importag6es, pacotes e
um recurso novo doJava 5, importag6es estAticas.

Declarag6es e Modificadores de Classes


Embora classes aninhadas (freqientemente chamadas de internas) caiam no exame,
deixaremos as declarag6es de classes
aninhadas para o Capitulo 8. Voc€ vai adorar esse capinrlo. Niq s6riq vai mesmo. O
c6digo seguinte 6 uma declaraqio de
classe simples:

class Myclass { }
Esse.c6digo iri compilat sem ptoblemas, mas yqgepqdelamb€lq adeio.nar
rao-digga4tr-es antes da de cla.r-ag,oda classe. Os
modificaderes ee dividemsnc duas..patsgp_r-ias :
r public,prolecLe4 pLivate.
_!t_"-aiq..aores de ac€sso:
I M-odificadoresquen6ose.r,eferemaacesso(incluindo strictfp, f inal eabstract).
Examinaremos os modificadores de acesso ptimeiro para que voc6 aprenda como restringir
ou permitir acesso a uma classe
que criar'o controle de acesso emJava 6 um pon.o porque pusterrr q\la$a ea.rtrok;de acesso (niveis dg qgesso)
--plicado
f0olep r-H#fI(!!frkdrcde-ageccq. Qqpa4q nivpl de-coqtrsle de acesso (cha-mado de acesso def ault oudep)iote){o
guq v-o-c€ oblim qual-{o ndo usa nenhunraostr€l-modi-fic4do{qs de acesso. E,m'outras
palavras, gggp13rr., m6todo ..'
Vgrpy..el{g inst{gci4 quevo-g6 {eclatar tem um controle Jieacisrq
-d.pqndentemente d;voc€ indi} um explicitamente ou
0.69' Embora tgd-g! 9-9^qF4trq gontrole; fg acesso (o que significa todos os tr€s modificadores) foncion
emparaa maroria das
declarag5es de m6todos e de variiveis, uma classipode.ser declarada.apenaS,.co5n,gcesso
pubt"ic ou d,ef ault; os outros
dois niveis de controle de acesso nio se aplicam paia classes, como voc6 ver6 adiante.

AO TRABALHO

Jaua d uma linguagen cenlrada n\Epa.rote|; os derenuoluedoret asrumiram qae,para uma boa organiqagdo e controle do escopo de nomes,
uocdpreferiria colocar todat as suas clasres empacotes. Eles estauam certoi, e iocd deuefaryr
i:i neino. Inagine o seguintepesadelo: trds
diferentet progmnadorer' na flrerma efitprestT, mas traba//tando em diferentes partu
de in prolen, escreuen ,oin o* una clasrc chamada
Utlities' Se essas trfu classes lJtilities ndo ,iuerem sido deltyadas in nenhin pacot, ,^pbrito, e utiuerem
no clasrpath, uoci ndo terd
nenhana maneira de diler ao compilador ou a
lwtL qual /as trds estd tentand) referencior. A Sun recomenda qae os desenuolaedoret
usem n1mes de doninio reuerso, anexados colr o nlme da diuisdo e oa doprojeto. Porexeupl0,
f ft 0 ltvne do siu doniniofor
geeksanonltmous'cLm' e estiaer traba/hando no aidigo do clienlepara oprograna
TwelaePoiitOStEt, aoc6 daria ao Jeil pacote ,/m //,me
camo com'geeksan0nlm0us.rteps.client. Isso modifcaria o oori do su) classe pnra
,o*.grr/"roronlroa1sEt.c/ient.(Jtilities. Ainda
astim, uocd poderia ter klisdes de nomer dentro da rila emprera, se ndo inuentai os
uus pidprios ujor*^ de' nomeagdo, mar
garantidamente ndo hausnl colisdes nm clasu duenuolaidas.fo* d: saa empreM
lassinlido qrr)/o, ngn* a conuengdo de nomeagdo da
Sury se e/as ndo o17(erem, bem, coisas bastante desagradriuiis poden aconticer). '

Acesso a Classes
o que significa acessar uma classe? Q-uando dizemos qug o g{dig-o-de uma classe.(a classe A) tem acesso a ou-tra-Gla-csE-E),
if gl-stgilfisa-Su-eaclAS!94-p-oi9g:9r-r1!tl.dlsp.g',rniq9coie4q;*
I Criar uma instdncia da classe B.
8 Copftulo 1 : DecloroE6es e Controle de Acesso

a E:ttdpfZd6Xq,!.(em outras palavras, tornar-se uma subclasse da classe B).

I Acessarcertos m6todos e da classe B, dependendo do controle de acesso desses m6todos


vari6veis dentro .:_:,:::____,".;_r. e variiveis.

l-.i.a
pritica, acesso signific a uisibilidadp. Se. a c-lasse A nio puder uera classeB,o nivel de acesso dos m(lodos e variiveis dentro
da classe B n6o farS,dtfercnga; a classe A nio ter6 como acessar esses m6todos e vari6veis.
Esse6o
ASr.SgD_ =faprll-Upaclagge-comaqggq-gdefaul-t naotemnenhummodificadorprecedendo-a{radeclaragio!
iontrole de acesso que vo.e oUte- quando nio digrta um modificador na declaragdo daclzsse. Pense no acesso defaul-t
como um acesso de nivel de pacote, porque ulna class-e-com acesso de f aul t s6 pode ser vista por classes de dentro do
rnesmopacote.Porexemplo,seaclasseAeaclasseBestiveremempacotesdiferentes,eaclasseAtiveracessodefault,a
classe B nio set6 capazdJ criar uma instAncia da classe A, e nem mesmo declarar uma varidvel ou tipo de retorno da classe A.
Na verdade, a classe B precisa fingir que a classe A nem sequer existe, ou o compilad or ir6. reclamar. Observe o seguinte
arquivo-fonte:
package cert;
class eeverage { i
Agora observe o segundo arquir,'o-fonte:
package exam. stuff;
import cert . Beverage,'
class Tea extends Beverage { }

Como voc6 pode ver, a superclasse (Beverage) est6 em um pacote diferente da subclasse (Iea). A declaragio import no alto
do arquivo Tea esti tentando (cruze os dedos!) importar a classe Beverage. O arquivo Beverage compila sem problemas,
mas, quando tentamos compilar o arquivo Tea, obtemos algo como:

Can,t access class cert.Beverage. Class or interface must be public, in same package'
or an accessible member c1ass.
import cert.Beveraget
Tezndo compila porque a sua superclasse, Beverage, tem acesso def ault e est6 em um pacote diferente. Fora usat nomes
de classes totalmente qualificados, o que abordaremos no Capitulo 10, existem duas coisas que vocd pode fazet pan
consertar isso. Voc6 poderia colocar ambas as classes no mesmo pacote, ou poderia declarar Beverage como publ ic, como
descrito na seg6o seguinte.
Dessa
Quando v_oc_e yrgm? ques.t6o com lp"gga complexa,.certifique-se de olhar os modificadores de acesso primeiro.
uma classe de f aul- t
,forma, se descobrir uma violagio de acesso (por exemplo, uma classe do pacote A tentando acessar
do pacote B), yoc6 saber6 que o c6digo nao vai compilat, entio nio precisa nem se dar ao trabalho de tentar entender a
I6gica. Afin"i,i;;ai; -as o que fLrr ro ..rr,.-po fazer aptova.Simplesmente marque a resposta 'A compilagio
"o
falha'e passe para a questao seguinte.

.{ge.sqg Pirblico Uma declaragio de classe com publ i c dd alo-das as classes, de todos os pacotes, acesso.d
^p^lavr^-chave
p_-ni;qersoJava QU) tdm acesso a uma classe priblica. No entanto, ndo
-.l"sS.e pfbliC?. Em outras palavras, lg/a.s as classesdo
se esquega, de que, gg.ruLa-ela.s;g,pgbLq1.qqe estlyer terrta.ndo usar estiver em um pacote diferente do da classe que este
screrrendq vocgggd.U_ree!ca!--6 1r-nper!al?-@s€p'$!9.
No exemplo da segio anterior, talvez ndo queiramos colocar a subclasse no mesmo pacote que a superclasse. Para fazet o
c6digo funciona4precisamos adtcionar apalavra-chave pu-b1 ic na frente da declaragdo da superclasse @everage), da
seguinte forma:
n: nlz:na narf .

public cfass eeverage { }

Isso modifica a classe Beverage para que ela se torne visivel a todas as classes em todos os Pacotes. Essa classe agora pode set
instanciada a partir de todas as outras classes, e qualquer classe est6 agora livre para subclassific6la (estender a partir dela) - a
ndo ser que a classe esteja marcada tamb6m com o modificador f inal .J5. falarcn:.os sobre isso.

Outros Modificadores de Classes (Nio-referentes a Acesso)


Voc€podemodificarumadeclzraglodeclasseusandoaspalavras-chavefinal"ab.sEract,oustricF€.D.!sse;.
modiicadores exi*sfen-rm-adigio-a.qualqueffontrolede acesso existent€naslasse, entiovoc6 poderia, por eremplq declarar
U€Q(!.classecomopublic efina]*ao.mesrf,rotempo.Nlar:r.dqd.semprequevocepodemisturarmodificadoresndo-
{F.fgtgqtesaacesso.Voc€podeusarstrictfp emcombinagiocomfinal,porexemplo,masniodevenunca,iamais,
m tc rvmaclassecomof inal- eabstract aomesmotempo.Voc6ver6porquenasduaspr6ximassegSes.
strictfp funciona, entio nos concentfafemos apenas em modificar uma classe como
Voc6 nio precisard saber como
final- ouabstract.Paraoexame,voc6s6precisasaberquestrictfp 6umapalavra-chavegguepodeserusadapara
.nodifijarumaclasseouunm6tgdo*.m4snuocamavan|vel.Marcarumaclassecomostrictfp significaquequa-lquet
c6digo de m6todo na classe se conformar6 is regras do pa&io IEEET54pzrzpontos flutuantes. Sem esse modificador, os
JAVA 5 9
pontos flutuantes usados nos m6todos poderio comportar de forma variante conforme aplataforna.Se ndo declarat a
se
classecomostrictfp,aindaassimvoc6poder6obterumcomportamentostrictfp param6todosespecificos,
declarando o m6todo como strictfp. Se voc6 nio conhece o pa&io IEEE 754,agotanio6 o momento pam aprend6-lo.
Voc€ tem assuntos mais importantes para se preocupar.

ClassesFinaisQuandousadanadeclaragilodeumaclasse,ap.flV3;3;9bave-final significaqueaclasseemquestdonao
gg[gper subcla,ssificada' Em outras palavtas, ne*gblqggclr-g1a.ss-eppd-ejas.rar,s aslenJef
@erdar de) uma clasie f ina1, e
9gdWe1l9111aivade faz€-lolhe dard um erlo de compilag{q
Entio por que voc€ sequer m arcaiauma classe como f inal ? Afinal de contas, isso n6o viola to da a nogd.ode heranga
presente nas linguagens orientadas a obietos? !,oc€ s6-5!pv_g marc4r gp.qa.c,lasse como f ina] seprecisar de uma garantia
.
4lselu-ta dequ.g.ngghurlr dos m6todos dessa classe jamais vai ser substituido. Caso ieo c6digo seja profundamente
dependentedaimplementagiodecetosm6todos,usarfinal lhedar6asegur"ogad.qoe-ningu6mpoder;,modtficata
irslegrent?g5g .qem vo_qQ. s_4!e1.

V?.i n1i.U]ique rr.rtls-gb:-q9g-4?s bibliotecas fuodamentaisJava s6o f ina1.


!og*9,1emplo, a classe String"nio pode ser
subclassificada. Imagine a confusio que ocoreria se vocd nio pudesse garantir fo.mi co-t um objeto String funcionaria
em qualquer sistema que executasse a sua aplicagdo! Se os programadores tivessem"
a liberdade de estender a clisse String (e
assim colocar as suas novas instancias da subclasse String onde esperam-se instAncias de java.lang.Strin a civiltzagfuo ti $,
comoaconhecemosenttaiaemcolapso.$ssim,usefinal paraseguranga,masapenasqo".rdotivercertezadequeasua
classe f inal de fato j6 disse tudo o que precisa ser dito nos seus m6todos. Marcaiuma.larr".orno f
significa, na inal-
EI?a-94 que a su,a classe nunca ser6 aprimorada, ou mesmo modificada para uso mais especifico, por outro programador.

IJ-q1!-e1e{c!o de se ter.classe$nao--f;pa1 6 neste cgn6rio: imagine que voc6 encontrou um problema com um m6todo
em
9$a,alasseque.qs?i usando, mas nio tem o c6digo.fionte. A;;!g1, vo;6 nio pode.mo-difiear a ionte para melhorar o m6todg,
tr-3-sj9g9:s.t9,!der a-classe e substituir o m6todo em questio na sua nova rob.lur.., e simplesmenl llr". u subclasse em
tg-,{1s31og;r-s10es em gue a superclasse original for esperada. No entanto, se a classe for f inal,
entao nao h6 nada que voc6
pcissa fazer.

Vamos modificat o nosso exemplo Beverage colocando a palavra-chave f inal na declaragio:


nadLrd6
Fsv.leJv ^arf.
ve! e,

public final class Beveraqe {


nrrl-rl i n rrai A impor."n.rJ.noao
"-,* { }

Agora, se tentarmos compilar a subclasse Tea:

package exam. stuf f ,.

i mnnrl- .art Part , erage,.


class Tea extends Beverage { }
Recebetemos um erro como:

Can't final classes: cl_ass


subcl_ass
cert.Beverage class Tea e:itends Beveraqe{
1 error
Napr6tica,voc€quasenunczciars"wrnacJ.asse f inal.As classes f inal acabamcomumbeneficio fundamentalda
programagio OO - a extensibilidade. Assim, a n6o set que voc6 tenha uma s6ria preocupagio de seguranga, assuma
que
-'
algum dia algum outro programador precisar6 estender a sua classe. Se nio o fizir,o pt6*i-o p.op[amador
que for
obrigado a fazer a manutengio do seu c6digo ir6 lhe perseguir e <insira algo muito aisustadoiaqri>.

ClassesAbstract Umaclasseabg-trac-t lraqpgdeserinstanciadanunca.oseurinicoptop6s-ito,missionavida,raison


{'eqe i5lgoteodidetqllbglalsificada). @epare, no entanto, que vocd pode compilar e executaruma classe abstract,
desde que ni.o tente criar urnainst6nciq dela.) por que criar uma classeie voc€ nit pode criar objetos dela? porque
a classe
poderia ser simplesmente, bem, abstract. Por exemplo, imeging qu9 voqitgnh-a uma classe Car que tenha m6tpdo$
genericos comuns a todos os veiculos. Mas vocd n6o quer que]l-gq6- d. futo i.i. um objeto carge.r6ri.o,
abst.r.act.
t;ifro !d inici alzatia o seu estado? De que cor ele seria? Quantos assentos? Potancia do motor? bireg6o hidriulica ou nio?
ou, mais imPortante, de que forma ele se comportaria? Em outras palavras, como os m6todos seriam implementados?
O que voc6 precisa 6 que os progtamadores instanciem tipos reais de carros, como BMWBoxster e SubaruOutback.
Temos
apenas ,.sonha em
cefteza de que o dono de um Boxster lhe diria que o caffo dele 6. capaz de fazer coisas que o Subaru
fazer". Observe a seguinte classe abstract:

abstract class Car {


*_*-,e prlce;
nri rr:f a dnrrl.l
'l
0 Copftulo I : Decloroc6es e Controle de Acesso

privaLe String model,'


private String year;
public abstract voj-d goFast ( ) ;
public abstract void goupH]--Ll- (/;
public abstract void impressNei.ghbors O ;
/ / Co1 odrrc o resfo do c6digo importante e s6rio aqui
/ / vv+vYqv

O c6digo acima iti compilar sem problemas. Entretanto, se voce tentar instanciar um Car em outro corpo de c6digo,
receber6 eros de compilagio como o seguinte:

AnotherClass.java:7: class Car is an abstract


class. It can't be instantiated.
Car x = new CarO,'
1 error
Repare que os metodos matcados com abstract terminam componto-e-virgula, emvez de chaveg'
com uma declaragio de m6todo que te"rmine com ponto-e-virgula, emvezde chaves. Se o m6todo estiver
Pro.Clr_19-lyeptQes
.o-Uniliaiq9,-9 $io em uma interface -, entaq tanto o m6todo como a classe devem ser marcados como abstract.
Pode aparecer uma questao que lhe pergunte como consertar uma amostra de c6digo que inclui um m6todo que termina
com p;nto-e-virgula, mas sem um modificador abstract na classe ou m6todo. Nesse caso, voc€ poderia ou rn rcar o
m6todo e a classe como abstract, ou modificar o ponto- e-virgiapatao c6digo apropriado (um par de chaves, por
exemplo). Lembre-se, se transformar um m6todo de abstrac E parando-abstract, n5o se esquega de trocar o
ponto-e-virgula no final da d eclangdo do m6todo por um par de chaves!

Examinaremos os m6todos abstract com mais detalhes mais adiante neste obietivo, mas lembre-se sempre de que, sq
mesmo um s6 m6todo fqr abs,tract,.toda a classe dever6 ser declarada como abstract*Um -m6todo alQstracL
clntamirra !o4a_a.!q!ma: Vocd pode,:ro entaoto, coloc-ar m6todos nio-abstract em uma classe abs-F-.ract' Por
.*.-plo, rro.6 poderia ter m6todos com implementag6es que nio devem mudar de acordo com o tipo deCx,tais como
get|olorO ousetPriceO.Aocolocarm6todosnZo-abstract emumaclasseabsEract,vocediatodasas
subclasses concletas (e concreto significa apenas nio-abs!.5agt) implementagSes de m6todos herdadas. A boa noticia 6
que as subclasses concretas herdam funcionalidad.r, . preiiii- implementar apenas os m6todos que definem
comportamentos especificos da subclasse.

(A prop6sito, se voc6 achou que usamos a expressio raison d'etre fora de contexto, anteriotmente, nio nos mande e-mail'
de certificagio PM Progr madores')
Queremos ver uoc6 colocarumra expressio dessas em um livro
programar com tipos de classes abstract (incluhdo interfaces, que serio discutidas mais adiante neste capitulo) permite
q..e voc6 tire vantagem do polimorfismo, e lhe d6 o maior grau possivel de flexibilidade e extensibilidade. Voc6 aprender6
mais sobre polimorfismo no Capitulo 2.

Nig €pqssiv€l mar:catrtm^classe como abstract e f inaf ao mesmo tempo. Elas t6m significados quase opostos'
Uf"C -.laeSe-abgLract-'p:ecisa-ser subclassificada, enquanto que uma classe f inaf nlo deve ser subclassificada. Se voc€
efinal,usadosparaumadeclatzglodeclasseoum6todo,oc6digo
"it"..rrfombinagiodemodificadoresabstract
nio ir6 compi-lar.

Exercfcio 1 - 1

Criando uma Superclasse Abstract e uma Subclasse Concreta


Osegu.inteexerciciotestarioseuconhecimentodeclassespublic,default,finaf eabstract.Crieuma
suoerclasse chamada Fruit e urna subclasse concreta chamada Apple. A superclasse deve pertencer a um pacote
abstracg
chamado food e a subclasse pode pertencer ao pacote def ault (significando que ela ndo ser6 colocada em
um pacote
expLicitamente). Torne a superclasse pubf ice d€ i subclasse acesso def ault.
1. Crie a superclasse da segrrinte maneuzl.
n:nlraa fnnd.

nrrhtic
vuvr+v ehsl-recf class pruit{ /* insira qualquer c5digo que desejav */I
2. Ciea subclasse em um arquivo separado, da segrinte maneira:
import food.Fruit;
JAVAS II
class Apple extends Fruit{ ,/* insira qualquer c6digo que desejar */}
3. crie um diret6rio chamado food dentro do diret6rio configurado no seu class path.
4' Tente compilat os dois arquivos. Se quiser usar a classe Apple, certifique-se de colocar o arquivo Fruit.class no
subdiret6rio food.

Al .
Obietivo poro o CertificoE6o

Declarar Interfaces (objetivos l.l e 1.2 do Exame)


1'l Desenuolaer aidigo qae declare clases (incluindo clasus abttract e todas asformas de c/asses aninhadat), intefans e enum!, e inclua o uso
4rEiado de dukmgdet package e inport (incluindo impo,tapdet utriticas).
1'2' Desenaolaer aidigo qae declare uma nttrfott Desenuoluer aidigo que inplenente ou estenda uma ou mais interfaces. Desenuoluer c;digo
qae dec/are uma classe abstract. Desenuoluer cddigo que ettenda nri ,l^n abttract

Declarando uma interface


Quando voc6 criar uma inte rfzce, estat6' definindo um contrato com o que a classe pode fazer, sem mencionar nada sobre
como a classe o fad.Umalnterface 6 um conffato. Voc6 poderia escrevei uma interiace Bounceable,
por exemplo, que
estabeleceria: "Essa 6 uma interf"ceboon.eable.
Qualquertipo de classe que @plementar .rru irt.riu.. precisa concordar em
e;19r;y_q-r-9p6$go do_sm6todosbounce (
) e setBounceFactor ) ". (
Se uma interface Bounceable (Saltitante) for definida, qualquer classe que quiser ser ttatada
como algo sal.ntante podet6
simplesmente implementar essa interface e fornecer oi6digo de seosiois m6todos.

As interfaces podem ser implementadas por qualquet clasEe,


de,.quglguq 6rvore de heranEa. Isso permiur6 que voc€ use
gbi!9,uadadg-.tsltediferentes e-fortegaaelas.umacaracteristicaemiomum.Pore*emplJ,'voc€podequererquetantoa
classe Ball quanto Tire tenham o mesmo comportamento, mas elas n6o compartilham nenhom^relacionamento
de heranga;
Ball.e stende Toy, enquanto Tite s6 estende
iava.lang.Object. Por6m, ao frrer iom que Ball e Tire implementem Bounceable,
voce estara dizendo que as duas classes podem ser tratadas como "coisas saltitante-s", o qr.. .-Jr.r" 6 traduzido por..coisas
quevoc€podeusarparachamarosm6todosbounce( ) esetBounceFor( )".AFigura1_1 ilustrao
relacionamento entre interfaces e classes.

interface Bounceable O que vocd


declara

void bounce( );
void setBounceFactor(int. bf) t

interface Bounceable Oqueo


compilador
v6.
frub].tc abrtract void bounce ( ) ;
Dubtlc rJrttract void setBounceFactor(int bf),.

I
i

O que a classe
precisa fazer
Class Tire implements Bounceable
public void bounce( ) i... ] (todos os
public void setBounceractor(int bf)t )
mdtodos pre-
cisam ser
implementa-
dos e defini-
dos como
p{rblicos)
l-l A Re/ogdo Entre /nferfoces e C/osses
Figuro
Considete uma interface como uma classe 100%o abstract. Como uma classe abstract, a interface
define m6todos
abstract com a forma,
abstract void bounceo; // Termina com ponto-e-virgu1a, em vez de chaves
Mas, enquanto uma classe abstract pode definir tanto m6todos abstract quanto ndo-abstract,
r*najnferfacp
gggg.dt ter m€todos abstr-aqt. outro ponto em que as interfaces diferem das classes abstract 6 que elas
12 Copftulo 1 : DecloroE6es e Controle de Acesso

s6o declarados. As regras s5o


/ apresentam muito pouca flexibilidade em como os m6todos e vari6veis definidos na interface
restritas:

I Todososm6todosdeinterfacesioimpliciamentepublic eabstract.Emoutraspalavras'vocenaoprecisadigitar
realmente os modificadores publ ic ou abstract, na declaragio do m6todo, mas mesmo assim ele sempre ser6

PubIic eabstract.
,.' I Todasasvariaveisdefinidasemumainterfacedevemserpublic, static e f inal -emoutraspalavras,as
intetfaces s6 podem se declarar constantes e neo vari6veis de instAncia.
; I Osm6todosdeinterfacesn6opodemser static'
a Jaque os m6todos de interface sio abstract, nio podem ser marcados como f inal, native, strictfp ou

i synchronized. (Falaremos mais sobre esses modificadores a seguir)


I Uma interface pode estender uma ou mais interfaces diferentes.
I f Uma interface nio pode estender nada que nio seja outra interface.
1 I Uma interface nio pode implementar outra intetface ou classe.
f Uma interface deve ser declarada om apalavn-chave interf ace.
c
\
I r Os tipos de interface podem ser usados polimorficamente (consulte o Capitulo 2paramais detalhes)'
A linha a seguir 6 uma declaragio de interface v6lida:

public abstract interface RoIlable { }


Digitat o modificador abstract 6 considerado redundante; as interfaces serio implicitamente abstract caso
voce
.ligite ou n6o abstract. 56 6 preciso saber que essas duas declarag6es sio vilidas e funcionalmente id6nticas:

public abstract interface Rol1ab1e { }


public interface Ro1lable { }
g*+."di. 4S_ed"r pub 1 i c ser6 obrigat6rio se voc€ quiser que a interface tenha acesso priblico em Yez de padrig.

Examinamos z declaragdoda interface, mas agora nos aprofundaremos nos mdtodos de uma interface:

Public interface aounceable {


public abstract void bounce ( ) ;
cublic abstract void setBounceFactor(int bf) ;

i
por6m, digitar os modificadores public e abstract nos m6todos 6 redundante, i6 que todos os m6todos de
interface slo implicitamente publ ic e abst,ract. Dada essa regta, vocd pode ver que o c6digo a seguir 6 exatamente
equivalente a interface antenor:

public interface Bounceable {


void bounceO ; / / sem modificadores
void setBounceFactor (int bf) ; / / sem modificadores
]
Voc€precisalembrarquetodesosrn6todosdeinterfaces6opublic eabstract independentedoqueestivetoa
definigio daintetface.
procure m6todos de interface declarados com qualquercombinaglo que envolvapublic ou abstract, ou sem
modificadores. por exemplo, as cinco declarag6ls de m6todo a seguir, se declaradas dentro de uma interface, serio
vilidas e
id€nticas!

void bounce O ;
.,, public void bounce O ;
abstract void bounce O ;
: Fubf ic abstract void bounce O ,'

abstract public void bounce O ;


As declarag6es de m6todos de interface abaixo nio serio compiladas:

final voj-d bounceO; // f1-nal- e abstract jamais podem ser usados juntos' e

/ /abstract j6 est6 imPlicito


JAVA 5 13
i static void bounce ( ) t / / interfaces definem m6todos de instAncias
I

I private void bounce O ,. / / os m1todos de interface sio sempre public


{
I
I protected void bounce ( ) ; / / (iden)

Declarando constantes de interface


Voc6 pode inserir constantes em uma interface. Ao fazer isso, gq-r?8!I?g::.g.p-4a,s-ap clajises que implementarem a interface
tenham ace ! s !A qE "s.--!S?.cq_tls!.4ol9.

Ao colocar as constantes diretamente n ainterface,qualquer classe que impleme ntar aintefiace ter6 acesso
direto is
constantes, como se as tivesse herdado.

Yo4-ef9gi.tilg lembrar de- uma reg,ra fundamental para constantes de interfaces. Elas devem sempte se1
nrrhlin et=f i^ +inal.

Isso parece simples, certo? Afinal, as constantes de interfaces nio sio diferentes de quaisquer outras constantes acessiveis
publicamente, entio, obviamente elas precisam set declaradas como public, sLatic e f inal-. Mas, antes de pular o
restante desta discussio, pense nas implicag6es:.pelo.f3r!o dg_ a.s.constantes de interfaces serem definidas em uma
int-e-ttlqgrplas4ig.precig-arnsel.deg!4rqdascomopubflc,static oufinal.Flasdevemserpublic,
g!flq-*i.c g-f inal- ma's voc6 n6o ptecisa declarS-las explicitamente dessa maneiri. Assim como os m6todos de
interfacessiosemprepublic eabstract,independentementedevoc6indicarissoounionoc6digo.qualgref
v"*gttf"d€ggde."9!9'-9.1F'4 tnre{-faqe-deJe sskgsg*4ltaBe-tlle 6 uma constante publ i c . veja t. -'o.e .onr.grre perceber
-
o problema com o seguinte c6digo (assuma que sdo dois arquivos separados):

interface Foo {
int BAR = 42,.
void go O ;
)

class Zap implements Foo {

public void goO {


EAK = ZI'

l
Vocd nio pode alterar o valor de uma constante! I-lma vez que o valor tiver sido atribuido, nunca poder6 ser alterado.3!
qqP"iflg gtgr+-e.{?-ngptpgsaintedacq(onde-a constante for de't'ua&),
Rg!-tag-tofr-g1"... qlr. " .i1irr.., implementando
ggdglgaceg.la;!9 e us6-.!g, mas como um valor somente de leirura. Assim,l-atritdgao geR = 27 rdo complar6".

oB SERYAQoBS pene O EXAME

Procare defnigdes de intet'ace que utabe/egam constantes, pordm, sem usar exp/icitamente ot modifcadnres necessiriot. por
exenp/0, os
aidigos a seguir sio todos iddnticos:

public int x = 1; // varece nao-static e n50-fina1, mas n50 6,


ant x = 1; // parece defaul-t, ndo-final e ndo-static, mas ndo 6!
statii i-nt x = 1; // Neo mostra final ou public
final int x = 1; // Ndo mostra static ou public
6,,L] i^
1luuaru >L4Lru
^r-!l^ ant
l
x = 1; // Nao mostra final
yuuras
^,,Ltl^ larrdr
4t*^1 rrrt
r- x = 1,. / / Nao most.ra static
static final int x = 1 // Nd,o mostra public
public static final int x = 1; // o que voc6 recebe implicitamente
pualquer combinapio dos motlficadores necessriios (poriru in4licitos) d udlida, como tambdm o i o nlo artliqasio de modficadores! No
exame' espere encontrar perguntas as quais ndo podeni responder coretamenle, a ntenos qae saiba, por exempl0, qae
y.f a.u,,!!!,t!!,! dg-innface .f
final enanrapodenireceberumualordarlasseqaeaestiuerimp/emenlando(oadeqaa/qaeroarrarlasse).
14 Copitulo 1 : Declorogoes e Conirole de Acesso

Obietivo poro o CertificoEdo

Declarar Membros de Classes (Obietivos 1.3 e 1.4)


1 .i Desenuoluer tidigo qne dulare, inicialiTg e ase primitiuos, atrEt, enans e objetos coma uaridueis stat ic, de instdncias e locais' Aldn
disso, usaridentificadoru legaispara nomes de uaridueis.

l.4Desenuolueraidigoqaedeclaremdtotlosstatic enio-sLaLic e,seapropriado,ilsarnomesdemdtodosqaeobedtpanaospadrdes


tle nomeapdl JauaBi^. ZU, tlisso, d.esenuoluer aidigo que declare e use ama lista de argunentos de extensio uaiduel.

vimos o que significa usar um modificadot em um a declangdo de classe, e agora veremos o que significa modificar uma
J6
declatagdo de um m6todo ou uma vari6vel.

Os m6todos e as vari6veis de inst6ncias (nioJocais) sio conhecidos coletivamente como membros. Voc6 pode modificar
um membro que tenha tanto modificadores de acesso como modificadotes que nio se referem a acesso, e vocd tem mais
modificadorei para escolher (e combinar) do que quando est6 declarando uma classe.

Modificadores de Acesso
Pelo fato de os m€todos e vari6veis normalmente receberem controle de acesso exatamente da mesmas forma, abordaremos
ambos nesta segio.

Enquantoumaclasrcs6podeusardoisdosquatroniveisdecontoledeacesso(default oupublic),osmembros
podem usar todos os quatro:
r public
I protect
I default
I private
A proteg6o padrdo6 o que voc€ recebe quando nio digita um modificador de acesso na de clatagdo do membro. Os tipos de
controledeac.ssodefault. eprotect t6mcomportamentosquaseidenticos,excetopolumadiferengaqueser6
mencionada posteriormente.

E crucial que voc6 saiba tudo sobre o controle de acesso par o exzme. Haver6 uma boa quantidade de Perguntas pataas
qoais voc6 dever6 usar o seu conhecimento sobre controle de acesso. Algumas quest6es testam v6rios conceitos de
controle
de acesso ao mesmo tempo, enrio o desconhecimento de uma pequena parte que seja do assunto poder6lhe custar uma
questio inteira.

O que signific a em uma classe ter acesso a um membro de outra classe? Por agora, ignore quaisquer
o fatode o c6digo
diferengas entre m6todos e vari6veis. Se a classe A tiver acesso a um membro da classe B, isso significa que o membro da
classe B est6 visivel para a classe A. Quando uma classe nZo tem acesso a ouffo membro, o compilador vai brigar
com voc6
por tentar acessar algo que voc6 nio deveria nem saber que existe!

Voc6 precisa entender duas quest6es difetentes telativas ao acesso:

I Se o c6digo de um m6todo em um classe pode acessarDm membro de outra classe


I Se uma subclasse pode berdarwm membro da sua superclasse

O primeiro tipo de acesso ocorre quando um m6todo de uma classe tenta acessar um m6todo ou uma vari6vel de outra
.1"..., lrsr.rdo o operador ponto (.) para invocar um m6todo ou obter uma vari|veL Por exemplo:
class Zoo {
public String coolt"tethod ( ) i
return "Wow babv";

class Moo {
,'
nrrl.r'lin .___ rrqpZ-
rrnid *-_-\zoo(,) t
Zoo z = new ZooO;
/ / se a linha anterior compilar, Moo terS acesso
JAVA 5 15

// d classe zoo
/ / Mas'.. . ser6 que tem acesso a coolMethodO ?
System.out.println("A Zoo says, " + z.coolMethod() );
/ / A linha anterior funciona porque Moo pode acessar o
/ / mAraAn nrrl-r'] i a

l
O segundo tipo de acesso refere-se a quais membros de uma supetclasse (se 6 que existem) uma subclasse pode acessar
aftav€s da heranga. Nio
estamos querendo saber se a subclasse pode, digamos, invocar um m6todo para uma instincia da
supetclasse (o que seria aPenas um exemplo do primeiro tipo de acesso). Em vez disso, queremos saber se a subclasse pode
berdarum membro da sua superclasse. Lembre-se de que se uma subclasse herdaum membro, 6 exatamente como se a
subclasse tive sse declarado o membro ela mesma. Em outras palavras, se uma subclasse herdaummembro, efltao ela tem
esse membro.

class Zoo {
nrrhl i n (f ri na nnnl Morhnrl
uvvrrrLuarvs /\ /\ It

return "Wow baby";

l
class Moo extends Zoo {
public void useMyCoo1MethodO {
/ / Ser6, que uma instAncia de Moo herda coolMethod ( ) ?
System.out.println("Moo says, " + this.coolMethodO );
/ / A J-inha anterior funciona porque Moo pode acessar o
/ / m6todo public
// Ser6. que uma instAncia de Moo pode invocar coolMethodQ em

/ / wma instAncia de zoo?


Zoo z = new ZooO;
System.out.pri.ntln("Zoo says. rr + z.coolMethodO );
// coolMeuhodO 6 public. entao Moo pode invocd-Io em
/ / uma refer6ncia a zoo
)

A Figura 1,-2 faz a comparagdo entre uma classe herdando um membro de outra classe, e acessando um membro de outra
classe usando uma refer€ncia de uma inst6ncia dessa classe.

Muito do controle de acesso (ambos os tipos) se concentra em se as duas classes envolvidas estao no mesmo pacote ou em
Pacotes diferentes. N6o se esquega, no entanto, q,te se apnipria classe A nio puder ser acessada pela classe B, ent6o nenhum
membro da classe A poderi, ser acessado pela classe B.
Vocd precisa saber o efeito de diferentes combinag6es de acesso a classes e membros (por exemplo uma classe padrao com
uma vari6vel pubJ- ic). Para descobrir issq primeiramente observe o nivel de acesso da classe. Se a pr6pria classe nio for
visivel a outra, entio nenhum dos seus membros ser6 visivel, nem mesmo se forem declarados publ ie. Depois de
confirmar que a classe est6 visivel, 6 uma boa id6ia observar os niveis de acesso nos membros individuais.

Membros Public
Quando um m€todo - ou vatiivel-membro - 6 declarado publ i c, isso significa que todas as outras classes,
independentemente do pacote ao qual pertengam, podem acessar o membro em questao (assumindo-se que a pr6pria classe
esteia visivel).
16 Copftulo 1 : Declorog6es e Conlrole de Acesso

goFast (
dostuff (
goFast (
)

Convertible

doThings( ){
Sportscar sc = new Sportscar( )t
sc.goFas!( );
)

Driver
doDriverSEuff ( ){
Sportscar car = new Sportscar( )t
car.goFast( );
Convertible con = new Convertible ( ) ;
con.goFast( ),
)

Figuro l-2 Comporogdo de herongo x operodor ponto pqro ocesso o membros.

Tr€s formas de acessar um m6todo:

(D)Invocando um m6todo declarado na mesma classe


(R) Invocando um m6todo usando uma referdncia da classe

(I) Invocando um m6todo herdado


Observe o seguinte arquivo-fonte:
package book;
import cert.*; // tmporta todas as classe do pacote certo
class Goo {
public static void main (String IJ args) {
Sludge o = new SludgeO;
o.testIt O ;
)

Agora observe o segundo arquivo:


narkanp acrl.

public class Sludge {


public void testrtO { System.out.println("s1udge"),' }
1
)

Como vocd pode ver, Goo e Sludge estao em pacotes diferentes. Entretanto, Goo pode invocar o metodo em Sludge sem
problemas, porque t^nto a classe Sludge quanto o seu metodo test.It ( ) est6o marcados como public.

Pan uma subclasse, se um membro da sua superclasse for declatado pub 1 i c, a subclasse herda esse membto,
independentemente de se ambas as classes estarem no mesmo pacote ou nio:
JAVA 5 17
n:^Lrd6
^arf.

public class Roo {


public String doRooThings O {
/ / imagine o c6digo divertido que entra aqui
rafrrrn \fr1n/.

A classe Roo declara o membto doRooThings ( ) como publ i c. Assim, se criarmos uma subclasse de Roo, qualquer
c6digo presente nessa subclasse Roo poderi chzmar o seu pr6prio m6todo doRooThings ( ) herdado.
package notcert; / / NEo 6 o pacote em que Roo se encontra
import cert . Roo;
class CIoo extends Roo {
public void testcloo ( ) {
System. out . println (doRooThings ( ) ) ;
l
]
Repare no c6digo anteriot que o m6todo doRooThings ( ) 6 invocado sem a necessidade de prefixi-lo com uma
referdncia. Lembre-se de que se voc€ vir um mdtodo invocado (ou uma vad6.vel acessada) sem o operador ponto (.), isso
sigrrifica que o m6todo ou a vari6vel pertence i classe onde voc6 l'ru esse c6digo. Tamb6m significa que o m6todo ou a
vai6velest6 sendo implicitamente acessado(a) usando-se arefer€ncia this. Assim, no c6digo anteior,acharnadaa
doRooThings ( ) na classe Cloo poderia tet sido escrita como thi s . doRooThings ( ) . A refer6ncia thi s sempre
se refere ao objeto sendo executado atualmente - em outras palavras, ao objeto que esteja rodando o c6digo quando voc6
v6 a refer€ncia thi s. Pelo fzto de a rcfetdncia thi s ser impiicita, voc6 n6o precisa prefixar o seu c6digo de acesso a ela, mas
se o fizer nio havet6 nenhum problema. Alguns progtamadores o incluem p ar^ torn t o c6digo mais f6ci1 de l er p^ta,
programadores iniciantes ou desconhecedores deJava.

Al6m de poder invocar o m6todo doRooThings O para si mesmo, o c6digo de alguma outta classe pode chamar
doRooThings ( ) para uma instincia de Cloo, da seguinte forma:
class roon {
public static void main(StringtJ argrs) {

Cloo c = new Cloo0;


System. out.println (c. doRooThings ( ) ) ; // Sem problema; o m6todo
// 6 public

Membros Private
Membros marcados como private ndo podem ser acessados por c6digo em nenhuma ouffa classe que nio aquela na qual
o membro private foi declarado. Vamos fazer uma pequena modificagio na classe Roo apresentada em um exemplo
antedot.
package cert;
public class Roo {
private String doRooThings ( ) {
/ / Imagine o c6digo divertido que entra aqui , mas apenas
/ / a c]-asse Roo sabe disso
ratlrrn rrfrlnrr.

O m6todo doRooThings ( ) agora 6 private, entao nenhuma outra classe pode us6-lo. Se tentarmos invocar o
m6todo a partir de qualquer outra classe, teremos problemas:
1 I Copitulo 1 : DecloroE6es e Controle de Acesso

package notcert;
i mn^rf
+rrryv! e ^6rf D^^.

cl-ass useAr{oo t
public void testlt o tt

Roo r - new RooO; // Ate aqui, tudo bem; a classe Roo 6 prlblica
qvcfam
^,,f
nrintln (r.doRooThingsO ) i // Erro de compilaqdol
I)
.I

Se tentatmos compilarUseARoo, receberemos um erro de compilagio parecido com este:


cannot find symbol
symbol : method doRooThings ( )
E como se o m6todo doRooThings ( ) nio existisse, e, no que diz respeito a qualquer c6digo fora da classe Roo, isso 6
verdade. Um membro private 6 invisivel para qualquet c6digo fora da pr6pria classe do membro.
E se uma subclasse tentasseherdar um membro private da sua supetclasse? Quando um membro 6 declarado
private, uma subclasse nio pode herdar dele. Pata o exame, voc6 precisa entender que uma subclasse nio pode ver, usar
e nem sequer pensar nos membros private da sua superclasse. Voc6 pode, no entanto, declarar um m€todo
cortespondenie na subclasse. Mas, nio importa asuaapai€.nci^,t Ao se irqta de um mdtodo substitutolE
simplesmente um m6todo que por acaso tem o mesmo nome que o m6todo private (de cuia existdncia voc6 nio deve
sequer saber) da superclasse. As regtas de substituigio ndo se aplicam, de forma que voc6 pode fazer esse m6todo "rec6m-
declarado-que-por-um-mero-acaso-6-o-mesmo" declarar novas exceg6es, ou modificar o tipo de retorno, ou qualquer otrtra
coisa que voc6 queira fazer com ele.
nanlrana rarf .

public class Roo {


private String doRooThings ( ) {
// Imagine o c6digo divertj-do que entra aqui, mas nenhuma
/ / orttra classe saber6 disso
return "fun" -

.l
O m6todo doRooThings ( ) agora est6 fora do alcance de todas as subclasses, at6 mesmo aquelas que esteiam no
mesmo pacote que a superclasse:

package cerL; / / Cloo e Roo estao no mesmo pacote


class Cloo extends Roo { / / fuao bem aj-nda, a superclasse Roo 6 prlblica
public void testClooO {
System. out.prj-ntl-n (doRooThings O ) ; / / Erro de compilaqdo !

l
Se tentarmos compilar a subclasse Cloo, o compilador tet6prazer em apresentar um erro parecido com este:

?javac Cloo.java
Cloo. java:4 : Undefined method: doRooThings o
System. out. println (doRooThings ( ) ) ;
1 error

AO TRABALHO

Enboralhe s/a penaitido marcar uaiit'eis de instdnciat coma publ ic, napnitica qaase sempre d melhor nanter todas as uaridueis como
private ou protect. Se as uaidueit precisarem vr modficadat, defnidas oa /idas, os programadores deuem usar nitodos de ausso
public, para que ctidigos em quaisquer outras classes tenhan de pedirpara obter on defnir uma uariduel (passando atrauds de *m rudtodo),
em ueqde acerd-/a diretamente. Os ndtodos de acesso conpatiueis con JauaBeans t€m aforna get<noneDaPropriedade) ou, para booleanos,
f
is<noneDaPropriedade> e set<nomeDaPropriedade>, efornecem um lugar onde uocd pode uerifcar e oa ua/idar antes de retomar ou
JAVA 5 19

modficar um ualar.

Sem usaprotepdo, a uari,iuel weight ('pesa') de an objeto Cat, por exempl0, poderia ur defnida nmo tlm nilmem negatiuo caso o cddigo
in@npiado tenba acesso direto i uaiduel publ ic, coml em somecat . weight = -20. Mas un mdtodo dz acesto, setweight
(int wt), podeia uerifcar se o nilmem d @ropiado. (Ok, tudo isso d especulagdo, mat estamos partindo do prina?io de qae un peso negatiuo
poderia ser in@ropriado para am gato. Ou ndo.) O Capitalo 2 divutinl esta prutu(Ao de dadot (enc@ulanento) com mais detalhes.

E possivel um m6todo private ser substituido por uma subclasse? Essa 6 uma pergunta interessanre, mas a resposta,
tecnicamente, 6 nio. Uma vez qve a subclasse, como vimos, nio pode herdar um m6todo private, ela, portanto, nao
pode substituir o m6todo - a substituigio depende da heranga. Abordaremos as implicag6es disso com mais detalhes mais
adiante nesta segio, bem como no Capitulo 2,mas,por agora basta lembrar-se de que um m6todo marcado como pri -
vate nao pode ser substituido. A Figura 1-3 ilustra os efeitos dos modificadores publi-c e private em classes de
um mesmo ou de diferentes Dacores.

O efeito do controle de acesso privado

SportsCar

goFast ( ) {...}
dosEuff ( ) {
goFast ( ),
]

Convertible

Subclasse

Driver
doErrivy'sruff( ){
Spo9(sCar car = new Sportscar( );
c9r'.gd(ast( );
co\eZliUfe con = nehr convert.ible( );
l'
r'ffit"tt
Figuro l-3 Efeifos do ocesso plblico e privodo

Trds formas de acessar um m6todo:

@)Invocando um m6todo declarado na mesma classe


(R) Invocando um m6todo usando uma referdncia da classe

(I) Invocando um m6todo herdado

Membros Protect e Default


Osniveisdeconuoledeacessoprotect edefault sioquaseid€nricos,mascomumadiferengafundamental.Um
membro de f aul t s6 pode ser acessado se a classe que o estiver acessando pertencer ao mesmo pacote, enquanto que um
membro protect pode ser acessado (atrav6s da heranga) por uma subclasse rnesmo se e subclasse estiuer em urn
pacote diferente.
Observe as duas classes seguintes:
nanl::ao
--- *--*JaEfon,.
narf i f i z

public class OtherClass {


20 Copftulo 1 : DecloroE6es e Controle de Acesso

woiri festTr () {L // O
/ /v faro dc nio haver modificador
LsLv

/ / indica acesso padrao


System. out . println ( "Othercl-ass" );

)
Em um outro arquivo de c6digo-fonte voce tem o seguinte:
package somethingElse ;
imnarf
+LLrFv! e
aarf i f i nrf i nr ntharr-l rae.

class AccessClass {
static public void main(Stringtl args) {
Othercl-ass o = new OtherClassO;
o. testIt O ;

j'
Como pode ver, o mdtodo testlt
( ) do ptimeiro arquivo tem acessopddr1o (ot seja, de niveldopacote). Repare tambem
que a classe OtherClass se encontra em um pacote diferente de AccessClass. Serl que AccessClass poder6 usar o m6todo
t
t e s t f O ? Vai causar um erro de compilagdo? Ser6 que o Daniel vai se cas ar colr, aFrancesca? Nio perca os pr6ximos
capitulos.
No method matching testlt O found in class
certification. Othercfass. o. testlt ( ) ,'
Pelosresultadosacima,voc€podeverqueAccessClassniopodeusarom6todotestlt O deOtherClassporque
test.It O temacessopadtio,eAccessClassnioest6nomesmopacotequeOtherClass.Assim,Accessclassn6opodev6-
la, o compilador reclama, e n6s nao temos nem id6ia de quem sejam Daniel e Ftancesca.

Os comportamentos def ault e protect diferem apenas quando falamos sobre subclasses. Se a palavra-chave
protected fotusadaparadefinirummembro,qualquersubclassedaclasseque fazadeclangdopodeacess6-lo atrauisda
heranga. N6o faz diferenga se a superclasse e a subclasse estao em pacotes diferentes, o membro da superclasse protect
ainda estard visivel para a subclasse (embora visivel apenas de uma formabastante especiftca, como veremos mais adiante).
Isso contrasta com o comportamento paddo,que nio permite que uma subclasse acesse um membro da superclasse, a nio
ser que a subclasse esteia no mesmo pacote que a superclasse.

Enquanto que o acesso padrio nio estende nenhum considetagdo especial is subclasses (ou voc6 est6 no pacote ou nio
esti), o modificador protected respeita a relagao parent-chjld, at6 mesmo quando a classe child se desloca (e iunta-se d
um novo pacote). Assim, quando pensar em acessopadrdo,pense em restrig6es depacote. Sem exceg6es. Mas, quando Pensar
em protect, pense em?acnte + kids.IJma classe com um membro protect esti marcando esse membro como tendo
acesso de nivel do pacote pata todas as classes, mas com uma excegio especial para subclasses fora do pacote.

Mas o que significa uma subclasse de fora do pacote ter acesso a um membro (parent) da supetclasse? Significa que a subclasse
herda o membro. Nio significa, no entanto, que a subclasse de fora do pacote possa acessar o membro usando uma refer6ncia a
umainstinciadasuperclasse.Emoutfaspalavfas,protecL =henn7a,Protect niosignificaqueasubclassepossatratar
o membro protect da superclasse como se ele fosse publ ic. Assim, se a subclasse de fota do pacote obtiver uma
refer6ncia i superclasse (cdando, por exemplq uma instAncia da superclasse em algum lugar no c6digo da subclasse), a subclasse
nio pode usar o opetador ponto na refet€ncia i superclasse para acessar o membro protec. Para uma subclasse de fora do
pacote, um membro protect poderia da mesma forma ser def aul-t (ou mesmo privado), quando a subclasse est6
usandoumarefer€nciaisuperclasse.Asubclasses6podeveromembroprotect atrav6sdaheranga.
Est6 confuso? N6s tamb6m. Agriente firme e tudo ficar6 claro com a s6rie de exemplos segrintes. (E ndo se Preocupe, na
verdade, nio estamos confusos. Estamos apenas tentando fazt-lo se sentir melhot caso voc6 esteia confuso. Sabe, tipo nio
tem problema se voc€ estiver achando que nada faz sentido, e ndo 4 culpa sua. Ou serd que 6? <insira isada mal€vola aqui>)

Detalhes de protect
Vamos dar uma olhada em uma vari6vel de instincia protect 0embre-se de que uma vari6vel de instdncia 6 um
membro) de uma superclasse.
package certif ication ;
public class Parent {
protected int x = 9; // acesso protect
I

O c6digo acima declara a vari6vel x como protected. Isso acersiael a todas as outfas classes dentm do Pacote
^totn
certification, bem como herdduelpor gttaisquer subclasses defora do pzcote. Agora vamos criar uma subclasse em um pacote
JAVA 5 21

diferente, e tentar usar a vari6vel x (que a subclasse herda):


package other; / / Pacote diferente
imnnri- carfi fiaal-inn Drranf.

class Child extends Parent {


public void tesrlr ( ) {
System. out . printl-n ( "x i_s \ + x) ; Sem problema; Child
herda x

O c6digo acima compila sem problemas. Repare, no entanto, que a classe Child estd acessando a vari6vel protect atrav6s
dahetanga. Lembre-se, sempre que falarmos de uma subclasse ter acesso a um membro de uma superclasse, podetiamos
estar falando de a subclasse herdar o membro, e nio simplesmente acess6-lo atrav6s de uma referdncia a uma ins tdtcia da
supetclasse (que 6 a forma como qualquer ouua nio-subclasse o acessaria). Repare no que acontece se a subclasse Child (fora
do pacote da superclasse) tentar acessar uma variivel protect usando uma referencia i classe Parent.

package other,.
import certif ication. Parent ;
class Child extends Parent {
.i^..^ir !^^FTl- () {
^,,L1
yulf fu vvfu LsDLru \/ L

System. out . printl-n ( "x is " + x) i


// Sem prdblema; Child
/ / herda x
Parent P = new Parento; // Podemos acessar x usando
// a refer6ncia a p?
System. out.println ( "X in parent is " + p.x); // Erro de compilaqSol

l
O compilador alegtemente nos mostra qual 6 o problema:
9'i:rr=n -du . nl- ho- /alai
vurrLr/ I .l
Lrlf fu. i --'-
Jqva
other/Child.java:9: x has protected access in certification.Parent
Svsl-em otrt nrinf ln($X in naranf
yqlgllur9-y.^l' iq rt r n v\.

;;:.*belecemos que um membro p ro t e c t tem, essencialmente, acesso de nivel do pacote ou padrio a todas as classes,
^,u
exceto vimos que as subclasses de fota do pacote podem herdar um membro prot.ect. Finalmente, j6vimos
as subclasses.J6
que as subclasses de forado pacotenao Podem usarumafefer6nciadi superclasse paraacessarum membropratecl. Pera
uma subclnsse deforq do pacotq o membro protect stf pode ser acessado otraaes da heranqa.
Ainda h6 mais uma questZo que nao consideramos... Q"ul 6 a apar€ncia de um membro protect para outras classes que
tentem usar a subclasse de fora do pacote para obter o membro protect da superclasse que foi herdado pela subclasse?
Por exemplo, usando as nossas classes Parent/Child anteriores, o que acontece se uma outra classe - digamos, Neighbor -
do mesmo pacote que Child (subclasse) tiver uma refer€ncia a uma instincia de Child e queira acessar a vari6vel-membrox?
Em outras palavns, como esse membro protect se comporta depois que a subclasse o herdou? Ele mant6m o seu
status de protect, de forma tal que as classes no pacote de Child possam v6Jo?

Nio! Depois que a subclasse de fora do pacote herda o membro protect, ele (conforme herdado pela subclasse) torna-se
private para qualquer c6digo de fotada subclasse, com a excegio das subclasses dessa subclasse. Assim, se a classe
Neighbor instanciat um obieto Child, entdo mesmo se Neighbot estiver no mesmo pacote que Child, Neighbor nlo teri
acesso i vari6vel x herdada (mas protect) por Child. Resumo da hist6ria: quando uma subclasse de fora do pacote herda
um membto protect, esse membro torna-se essencialmente private dentro da subclasse, de forma tal que apenas a
subclasseeassuassubclassespodemacess6lo.AFigural-4ilustraoefeitodoacessoprotect sobreclassesesubclasses
no mesmo ou em diferentes pacotes.
Carambal Com isso terminamos protected, o modificador mais incompreendido emJava. Novamente, ele s5 6 usado
em casos muito especiais, mas pode ter certezade que aparecer6 no exame. Agora que j6 abordamos o modificadorpro-
tected, passaremos para o acesso padrio, uma molezacomparado a protect.ed.
22 Cqpitulo 1 : Declorog6es e Controle de Acesso

Detalhes de Default
Vamos comegar com o comportamento padrd.o de um membro de uma superclasse. Modificaremos o membro x de Parent
panrorn6-lo def ault.
package certif ication;
public class Parent {
int x = 9; / / Aus€ncia de modificadores de acesso
/ / indica acesso padrSo (de pacote)
)

Repare que nio colocamos um modificador de acesso na ftentedavai|vel x. Lembre-se de que, se voc€ nio di.grtar um
modificador de acesso antes da decla ragdo de uma classe ou um membro, o conrole de acesso 6 o padtdo, o que significa de
nivel do pacote. Agora tentaremos acessar o membro padrdo da classe Child que vimos anteriormente.

Se goFast$ for padr6o Se goFast$ for protegido

Pacote A Pacote A

goFast( )t ]

Convertible convergible

l--D'i'"'_l
T^^t,
I er," g t.

Pacote B
Convertible f c;;ctb;l
[H-el*l
f *1"".
Chave:
E-tr-ll
dofhings ( ){
r------------1
Sportscar sc = new Sportscar( ), I dot'tore( )( f
sc.goFast( ); I sorast( );I
l It
L-.r-F:'=*[
I.

Onde goFast 6 lnvocando goFast$ usando-se uma Refer- Invocando


Declarado na 6ncia A classe na qual goFastQ foi goFast$ usando.
mesma classe. declarada. se uma Refer6ncia
d classe na qual
goFast$ foi
declarada.

Figuro l-4 Efeitos do ocesso protect

Quando compilarmos o arquivo Child, recebetemos um effo parecido com este:


: Undefj-ned variable : x
Chi1d. j ava:4
System.out.println("Variable x is " + x) t
1 error
O compilador nos d6 o mesmo erro de quando um membro 6 declarado como private. A subclasse Child (em um
pacote diferente do da superclasse Parent) ndo 6 capaz de ver nem usar o membro padrio x da superclasse! Agora, e quanto
ao acesso padrio para duas classes do mesmo pacote?
package certif ication ;

public cl-ass Parent{


JAVA 5 23
int x = 9; // acesso padrao
)

E, na segunda classe, voc6 tem o segrinte:

package certif ication ;


class Child extends parent{
static public void main(StringlJ args) {
Child sc = new Chi_IdO;
sc. testIt O ,.

i
)

public void testrr O {


System.out.println('.Variable x is " + x) ; // Sem problemas
)

O c6digo-fonte acima compila sem problemas, e a classe Child roda e exibe o valor e x. Basta se lembrar de que os membros
padrio ficam visiveis par:-as subclasses apenas se elas estiverem no mesmo pacote que a superclasse.

Variiveis Locais e Modificadores de Acesso


Os modificadores de acesso podem ser aplicados a variiveis locais? NAO!
Nio existe nenhum caso em que um modificador de acesso possa ser aplicado aumavailvel local, entio, cuidado com
c6digo como o seguinte:
class Foo {
void doSruff O {
private int x = 7;
this.doMore(x);

]
Pode ter certeza de que qualquer vari6vel local declarada com um modificador de acesso fieo vai compilar. Na verdade. s6
existe um modificador que pode ser aplicado avari6veis locais f inal_.
-
Isso termina a nossa discussio sobre modificadores de acesso de membros. A Tabela 1.-2 mostratodas as combinag6es de
acesso e visibilidade; 6 uma boa id6ia passar algum tempo estudando-a. Em seguida, vamos passar para os outros
modificadores (nio-referentes a acesso) que voc€ pode apltcar a declarag6es de membros.

Tqbelo I -2 Determinondo o Acesso o Membros de Closses

Visibilidade Pubtc Protect Default Private

A partir da mesma classe Sim Sim Sim Sim


A partir de qualquer classe do mesmo pacote Sim Sim Sim Nio
A partir de uma subclasse do mesmo pacote Sim Sim Sim N6o
A partir de uma subclasse de fora do mesmo pacote Sim Sim, atrauis Nio Nio
da heranga

A partir de qualquer classe que nio seja Sim Nio N6o Nio
uma subclasse e esteia fora do pacote

Modificadores Nio-Referentes a Acesso


J6 discutimos o acesso a membros, o qual diz respeito ao c6digo de uma classe pode invocar rxn m6todo (ou acessar uma
variivel de instdncia) aparar de outra classe. Isso ainda nio inclui uma s€rie de outros modificadores que vocd pode usar em
declarag6es de membtos. Dois deles j6 lhe sio fami-liares f
- inale abstract -,porque n6s os aplicamos a
24 Coollulo I : Decloroc6es e Conirole de Acesso

declaraE6es de classes anteriormente neste capitulo. Mas ainda temos de dar uma ripida olhada em trans ient, syn-
chroni zed, nat ive, strictf p, e depois uma longa olhada no grande modificadot - stat ic.

Veremos primeiro os modificadores aplcados a m6todos, seguidos pelos modificadores aplicados a vari6veis de instAncias'
Fecharembs esta segao com uma olhad" .- .orno stat ic funciona quando aplicado a vari6veis e m6todos.

M6todos Final
A palavra-chave f inal impede que um m6todo possa ser substituido em uma subclasse, e frequentemente 6 usada para
forg"r os recursos API de om m6toio. Por exemplo, a classe Thtead tem um mdtodo chamado i sAl- ive ) que verifica se
(

om^ determin adathread atndz est6 airva. Se voc6 estender a classe Thread, no entanto, realmente nio h6 como vocd sozinho
implementar corretamente esse m6todo (ele usa c6digo nativo, s6 para citar uma das taz6es), entao os elaboradores o
to-"rrr., f inal-. Assim como nio 6 possivel subclassificar a classe String (porque precisamos confiar no comPortamento
Essa
de um objeto String), vocd nio poder6 substituir a matorizdos m6todos nas bibliotecas de classes fundamentais.
restrigio quanto a soUstitoigao propicia boa seguranga, mas voc6 deve us6-la com muito cuidado. Impedir que uma
atravds
subclasse iubstitua um metodo invatida muitos dos beneficios da orientagao a obietos, incluindo a estensibilidade
do polimorfismo. Uma declaragio de m6todo f inal tipica se pareceria com isto:
class SuperClass{
public fj-na1 void showSamPle O {
System. out . println ( "One thing . " ) ;

E v6lido esrender SuperClass, umavez qwe a classe ndo esti marcada como f inal-, mas nio podemos substituit o mdtodo
f inaf showsample ( ) , como o seguinte c6digo est|tentando f^zetl
class SubClass extends SuperClassi
public void showSampleO { // Tentando substituir om6todo
/ / f:-na:-- da suPerclasse
System. out . println ( "Another thing . " ) ;

Se tentar compilar o c6digo acima, voc6 receberi uma mensagem como esta:
?javac FinalTest.java
FinalTest.java:5: The method void showsampleO decfared in class
subclass cannot override the final method of the same signature
declared in cl-ass SuPerClass.
Final methods cannot be overridden.
public void showSample O { }
1 error

Argumentos Final
Os argumentos de m6todos sio as declarag6es de varidveis que aparecem entre par€nteses na declatagio de um m6todo. Uma
declaragdo de m6todo tipica, com multiplos afgumentos, se Parece com o seguinte:

public Record getRecord(int fileNumber, int recordNumber) { }

Argumentos de m6todos sio essencialmente o mesmo que variiweis locais. No exemplo_anterior,. as vari6veis
f ileNumber recordNuniber seguem todas as regras aplicadas avari6veis locais. Isso significa
e que elas tamb6m
podem ter o modificador f inal-:
public Record getRecord(int fileNumber, final int recNumber) { }
Nesteexemplo,avartfivelrecordNumber 6declaradacomofinal,oquesignificaobviamentequeelanlopoder6ser
modificada ientro do m6todo. Neste caso, "modificar" significa atribuir um novo valor d vari6vel. Em outras palavras, um
argumento f inal deve manter o mesmo valor que o pardmetro tinha quando foi passado para o m6todo.

M6todos Abstract
Um m6todo abstract um m6todo que foi declarado (como abstract) mas ndo implenentado. Em outras palavras, o
6
m6todo nio cont6m nenhum c6digo funcional. E, se vocd se lembrar da segio "Classes abstract", uma declaraqio de
m6todo abstract neo tem nem sequer chaves onde um c6digo de implementag6o pudesse ser colocado, terminando,
JAVA 5 25
emvez disso, com ponto-e-virgula. Em outras palavras, eIa ndo tem uru corpo de ndtodo. Voc6 marca um m6todo como
abstract quandoquerforgarassubclassesaforneceraimplementagloemquestao.Porexemplo,seescreverumaclasse
abstract Car com um m6todo goupHi 11 ( ) , voc6 poderia desejar forgai todos os subtipos de Car adefinir o seu
pr6pdo comportamento de goupHill ( ) , especifico dquele tipo determinado de carro.
public abstract void showSample O ;
Repare que o m6todo abstract termina com ponto-e-virgula emvezde chaves. E, inv,i,lido ter um rinico
m6todo
abstract. que seja em uma classe que n6o seia declarada explicitamente como abstractl Observe a seguinte
classeinvilida:
publi-c class I1lega1C1ass{
public abstract void dolt O ;

A classe anterior produzird o seguinte erro se voc€ a tentar compiJar:


f11ega1Class. java: 1 : class Il1ega1C1ass must. be declared
abstract.
It does not define void doftO from cl_ass I11ega1C1ass.
public cLass I11ega1Class{
1 error
voc6 pode, no entanto, ter uma classe abstract sem nenhum m6todo abstract. O seguinte exemplo ir6
compilar sem problemas:
publi-c abstract cl_ass LegalClass {
void goodMethodO {
/ / insira um monte de c6digos reais de implementagdo aqui
)
1
J

No exemplo anterior, goodMet.hod ( ) nio 6 abstract. Tr€s dicas diferentes lhe dizem que nio se trata cle um
m6todo abstract:
I O m6todo nio est6 marcado como abstract.
I A declaragio do m6todo inclui chaves, em vez de terminar com ponto-e-virgula. Em outras palavras, o m6todo tem um
corpo de m6todo.
I O m6todo inclui c6digo de implementagio.

Qualquer classe que estenda uma classe abstract deve implementar todos os m6todos abstract da superclasse. a
nio ser que a subclasse tambdn seia abst.ract. A tegra 6 a seguinte:
Aprimeirasubclasseconcretadeumaclasseabatraet deveimplernentattoda.sosm6todosabst,ract da
supetclasse.

Concretosignificaapenasnio-abstract,entao,sevoc€tiverumaclasseabstract estendendooutraclasseab-
stract, a subclasse abst.ract nio precisa fornecerimplementag6es para os m6todos abstract herdados. Mais
cedo ou mais tatde, no entanto, algu6m vai ctiat uma subclaise nio-abstract (em outras palavras, uma classe
que pode
serinstanciada), e essa subclasse teri de implementar todos os m6todos abstract de cima para baixo na 6rvore de-
heranga. O seguinte exemplo demonstra umaLrvorede heranga com duas classes abstract e uma concreta:
public abstract class Vehicle {
private String type;
public absrract void goUpHitl O ; / / M6tod.o abst.ract
public String gerType O { / / M6rodo neo-absrract
return t)4)et

l
public abstract class Car extends Vehicle {
public abstract void goUpHill O ; / / X:-naa abstract
nrrhl
yqvrf i a
v rrni
vvrq r{ dan--TLi
uvvqr rrrrrrgD
-^^ /\ \/ I
t
/ / C6digo especial para o carro entra aqui
26 Copitulo I : Declorocoes e Controle deAcesso
I
)

l
l
public class Mj-ni extends Car i
public void goUpHilI ( ) t
/ / c6digo especifico para o Mini subir ladeiras
i
]
Entio, quantos m€todos tem a classe Mini? Tr6s. Ela herda os m6todosgetType O e doCarrhings O , porque eles
sio pfblicos e concretos (nio-abstract). Mas, pelo fato de goupHill ( ) ser abst.ract na superclasse Vehicle, e
nunca ser implementado na classe Car (permanecendo abstract, portanto), isso significa que a classe Mini - como a
primeiraclasseconcretaabaixodeVehicle-precisaimplementatom6todogoupHill O.Emoutraspalavras,aclasse
Mini nio pode deixar a implementagio do m6todo abstract pa:.aapr6xjrr'a classe abaixo dela na 6rvote dehetanga,
mas a classe Car pode, porque Car, como Vehicle,6 abstract. A Figura 1-5 ilustra os efeitos do modificador ab-
stract sobre subclasses conctetas e abstratas.

absttact Car

startEngine( )
abstract gaFor'ward( )
abstract reverse( )
stop( )
abstract turn(int whichWay)

absEracE SW
startEngine( ) // opcional enable4wd( )
rd( | // requerido goForward( )
reverse( ) // requerido reverse ( )
turn ( int rdhichway) //requerido abst.ract gooffRoad( )

/
//
I
rttrn{\
vsLLL nin imnlamenEado
.lJrtyrvttt.

Os m6todos abstract devem set implementados por uma


subclassenio-abstract. Se a subclasse for abstrata, ela n6o 6
obrigada a implementar os m6todos abstract, mas tem a
pemisseo de implementat qualquer um ou todos os m6todos
abstract da superclasse. A classe AcmeRover 6 nio- enable4wd( \ // oPclonaL
goOffRoad( ) // requerido
abs t rac t, entao ela precisa implementar o mdtodo ab - turn (int, whichWay) //requerido
stract declarado na sua superclasse, SUV e precisa
implementar tamb6m turn ( ) , que nio foi implementado por
SL]V

Figuro t-5 Os efeilos do modificodor obsfrocl sobre subclosses concrefos e obsfrolos


Ptocure por classes concretas que nio fornegam implementag6es pata m6todos abstracL da superclasse. O seguinte
c6digo nio vai compilar:
public abstract class A {
abstract void foo ( ) ;
)

classBextendsA{
void foo(int r) { }

i
A classe B nio vai compilar porque ela ndo implementa o m6todo abstract herdado f oo O . Embora o m6todo
f oo int I ) da classe B parega ser uma
( implementagio do m6todo abstract da superclasse, na verdade €
simplesmente um m6todo sobrecarregado (um m6todo que usa o mesmo identificador, mas diferentes argumentos)' enteo
ele nio atende ao requisito de implementagdo do m6todo absLract da superclasse. Veremos as diferengas enre
substituigio e sobrecarga com mais detalhes no Capitulo 2.
Um m6todo nio pode nunca, jamais, ser marcado como abstract e f inal ao mesmo tempo, nem como ab-
stracL e private ao mesmo tempo. Pense um pouco - os m6todos abstract precisam ser implementados (o
JAVA 5 27
que na pr6tica significa serem substituidos por uma subclasse), enquanto que m6todos f e inal private
ndo podem
jamais ser substituidos por uma subclasse. Ou, dizendo de outra forma, uma designagio
abstract
significa que a
superclasse nlo sabe nada sobre como as subclasses devem se comportar no m6todo Lm questio,
enquanro que uma
designagio f ina l- significa que a superclasse sabe tudo sob.r como todas as subclasses
lpor -"1, afastadas qr.re estejam na
6rvore de heranga) devem se comPortarno m6todo em quest6o. Os modificadores ef abst;act inal- sio
praticamente opostos. Pelo fato de os m6todos private nio poderem nem mesmo ser vistos pof uma
subclasse
(_quanto mais herdados), eles tamb6m nio podem ser substituidoi, entio eles tamb6m
nao podem ser marcados como
abstract.
Finalmente,voc6precisasaberqueomodificadorabstract niopodenuncasercombinadocomomodificador
stat ic. Abordaremos os m6todos stat ic mais adiante .r.rt. obl.ti-ro,
mas, por zgora,bastalembrar que o seguinte
seria inv6lido:

abstract static void doStuff ( ) ;

E lhe daria um effo que a esta altura i6 deverdlhe parecet familiar:

MyClass.java:2: i1lega1 combi-nation of modifiers: abstract and


<f i
^l- ^
abstract static void doStuff O;

M6todos Synchronized
A palavra-chave s)mchroni zed indica que um mdtodo s6 pode ser acessado por um thread de cada vez. N6s
discutiremos isso i exaustio no Capin lo 9, mas, por agora, tud; o que nos intereisa 6 saber que o modificador synchro_
nized s6podeseraplicadoamdtodos-ndoavari6viis,nemclasses,apenasam6todos.Umadeclarag6osynchronized
tipica se parece com a seguinte:
public synchronized Record retrieveUserlnfo(int id) { }
Voc6 precisa saber tambdm que o modificador synchroni zed. pode ser acompanhado por qualquer um dos quatro
niveis de controle de acesso (o que significa que ele pode ser usado juntamente com qualqueiu-" d", t C, palavras-chave
modificadoras de acesso).

M6todos Nativos
O modificador native indica que o m6todo est6 seodo implementado conforme aplataformz,freqtientemente e C.
Voc6 n6o precisa saber como usar m6todos nativos pano etim.,basta saber qu. tr-ii.re € um modificador (e, ponantq
uma palavra-chave reservada) e-que nat j-ve s6 pode ser aplicado a mdtodos ndo a classes, nem avai6veo,
- "p..rui
a
m6todos. Repare que o corPo de um m6todo nativo deve ser ponto-e-virgula
O (como m6todos abstraci), indicando
que a implementagao foi omitida.

M6todos Strictfp
Vimos anteriormente o uso de strictfp como modificadot de classe, mas, mesmo que voc6 nio declare uma classe
como str j-ct f p, ainda assim voc€ poderi declarar um m6todo individual como strictf p. Lembre-se de que
strictfp forgaospontosflutuantes(equaisqueroperagoescompontoflutuante)aaderirem aopadriolEil,ET54.
Com strictf p,6 possivel prever como os seus pontos flufuantes se comportarao,independentemente daplatafotma
subjacente na qual aJ\M esti rodando. O inconveniente disso 6 que, se aplitaformasubjacente for capazde srrportar 11ma
maior precisio, um mdtodo strictfp n6o poderd se beneficiar dessa capacidade.
Voc6 s6 deseiati estudar o IEEE 754 se precisa r de algo para aiud6Jo a cak no sono. Para o exame, no entanto, voc6
nio
ptecisasabernadasobrestrictfp al6mdasuautilidade,dofatodequepodemodificarumad,eclangdodeclasseoude
m6todo, e que uma vad6vel nunca pode ser declarada como strictfp.

M6todos com Listas de Argumentos Vari6veis (var-args)


Desde a versio 5.0,Java lhe permite criar m6todos c pzzes de usar um nfmero variivel de argumentos. Dependendo
de
onde voc€ pesquisar, poderd ver essa caPacidade ser chamada de "listas de argumentos de extJnsio v ariivel';,,,argumentos
vari6veis", "vat-args","vatatgs" ou o nosso favorito (saido do departamento de obscuridad e),"patdmetrocom nfmero
vari6vel de argumentos". Todos eles sio a mesma coisa, e usaremos o termo "vat-ztgs" daqui em diante.

Apenas para informagio, gostariamos de esclarecer como iremos usar os termos "argumento" e "parAmetro" ao longo
deste
Livro.

I argumentos Aquilo que voc6 especifica entre pardnteses quando est6 inuocantlowm m6todo:
dostuff("a", 2l; // estamos invocando dostuff, entdo a & 2 sao argumenros
I patdmettos Aquilo na assinatura dom6todo indica o que o m6todo deve receber quando forinvocado:
rraid daQt-rrff ,r /Qf-]-^
roirro9 s,
^ l-nt
l-r a)
-\ \f jI // estamos esperando dois
28 Copftulo 1 : Declorog6es e Conlrole de Acesso

// pardmexros: String e int


Falaremos mais sobre o uso de mftodos var-args nos pr6ximos capinrlos, por agora vamos revisar as regras de
declangtro
pamvar-args:

I Tipo var-atg Quando declara um pardmeftovar-arg, vocd deve especificar o tipo do(s) argumento(s) que esse
p"ia-.t.o do seu m6todo pode recebet. @ode ser um tipo primitivo ou um tipo de obieto.)
I Sintaxe b4sica Para declarar um mdtodo usando um parAmetro vat-arg, voc€ escreve depois do tipo um sinal de
retic€ncias (...), um espagq e depois o nome do array que ir6armazenar os parimetros recebidos.

I Outfos pardmetros E v6lido tef outfos parametros em um m6todo que use um vaf-afg.
I Lirnites dos var-args O var-arg deve ser o riltimo parametro na assinatura do metodo, e voc€ s6 pode ter um var-arg
por m6todo.
Vejamos algumas declarag6es com var-argvdlidas e invilidas:

Vdlidas:
void doStuff (int... x) { } espera de 0 a muitos ints
como parAmetros
void doStuff2 (char c, int x) t ) / / es9era Primeiramente um char,
// e depois de o a muitos ints
void doStuff3 (Animal-... animal) { } tt de 0 a muitos Animals
Invdlidas:
void doStuff4(int x...) { } / / sin1caxe incorreta
void doStuffs(int . x, char... y) { } //mais deumvar-arg
void doStuff6 (String. . . s, byte b) { i / / var-arg tem de vir por rlltimo

Declarag6es de Construtores
EmJava, os obietos sio construidos. Sempre que voc€ cria um novo obieto, pelo menos um construtor 6 invocado. Toda
classe tem um construtor, e, se voc6 nio criar um explicitamente, o compilador vai criar um para voc€. Existem
toneladas de
regtas relativas aos construtores, e iremos deixar a discussio detalhada para o Capinrlo 2.Por agota,vamos nos concentrar
flas regras b6sicas de declaragio. Eis um exemplo simples:

class r.oo t
protected FooO { } / / este 6 o construtor de Foo

protected void Foo O { } este 6 um m6todo com um P6ssimo nome,

^^-6herr,
yvr
rrilida

)
A primeira coisa a se reparar 6 que os construtores se parecem um bocado com m6todos. Uma diferenga fundamental 6 que
11rrl .orrrtr.rtor n6o poie nonca, i"mais, ter um tipo de retorno.., Nunca! As declarag6es de construtores podem ter, no
entanto, todos os modificadores de acesso normais, e podem usar argumentos (incluindo var-args), da mesma forma como
os m6todos. A outra REGRA IMPORTANTE a se entender sobre os constmtores 6 que eles devem ter o mesmo nome
que a classe no qual sio declarados. Os construtores nio podem ser matcados como s t at i c (afinal eles sio associados
com instanciaminto de objetos), nio podem ser marcados como f inaL nem abstract (porque ndo podem ser
substituidos), Eis algumas declarag6es de construtores v6lidos e invalidos:

cJ-ass Eooz I

/ / consLrutores vSlidos

Foo2O { }
private Foo2 (byte b){}
Foo2 (int x) { i
Fnal/inf v inl-
v) t)
JAVA 5 29
/ / constTutores invSLidos

void Foo2 O { } / / 6 um m6t.odo, ndo um consrrur.or


FooO { \ / / n5o 6 nem m6todo nem conscruuor
Foo2 (short s) ,. / / se parece com um m6todo abscracc
static Foo2(float f) { } // ndo pode ser static
final Foo2 (long x) { } / / ndo pode ser fj_naI
abstract Foo2 (char c) { I t t ndo pode ser abstract
Foo2(int.. x, int t) { } tt sintaxe var-arg lncorreEa

Declarag6es de Variiveis
Existem dois tipos de vari6veis emJava:
I Primitivos Um primitivo pode ser de oito tipos diferentes: char, boolean, byte , short , int ,
long, double ou f l-oat. IJmavez declarado, o seu tipo primitivo nio pode nunca ser modificado, embota na
maioria dos casos o seu valor possa se modificar.
I Vari6veis de refet€ncia As vari6veis de referdncia sio usadas para se referir (ou acessar) um objeto. Uma variavel de
referdncia 6 declarada como sendo de um tipo especifico, e esse tipo nio pode nunca ser modificado. Uma vari6vel
de
refer€ncia pode ser usada para referit-se a qualquer objeto do tipo declarado ou de tm subtipo do ipodeclarado (um
,
tipo compativel). Falaremos muito mais sobre o uso de uma vari6vel de referCncia para referir-se a tlm subtipo no
Capitulo 2, onde discutiremos o polimorfismo.

Declarando Primitivos e Interralos de Primitivos


Vari6veis primitivas podem set declaradas como vari6veis de classe (stat ic), varidveis de instincias, parimetros de
m6todos ou vari6veis locais. Voc6 pode declarar um ou mais primitivos, do mesmo tipo primitivo, em uma mesma linha.
No Capitulo 3, discutiremos as diversas maneiras pelas quais eles podem ser inicializadosrmas, por agora, apresenraremos
apenas alguns exemplos de declaragSes de vari6veis primitivas:

byte b,'
boof ean myBooleanprimit ive ;

l nf v
/ / decl-ara tr6s primi_tivos j_nt
Em vers6es anteriores do exame, voc€ precisava saber como calcular intervalos para todos os primitivos ava. Para o exame
J
atual, voc€ pode pular alguns detalhes, mas ainda 6 impotante entender que, para os tipos intiiros, a seqtidncia 6 (do
menot
para o maior) byte, short, int e long, e que doubles sio maiores do que floats.

Voc€ tamb6m precisar6 saber que os tipos num6ricos (tanto inteiros quaflto de ponto flutuante) sio todos assinalados, e
como isso afeta os seus intervalos. Pdmeiramente, vamos revisar os conceitos.

Todos os seis tipos num6ricos emJava sio feitos de um certo nrimero de bltes de 8 bits, e s2to assinalados,significando que
podem ser negativos ou positivos. O bit mais i esquerda (o digito mais significativo) 6 usado para representar o sinal, em
que 1 significa negativo e 0 sigmfica positivo, como mostrado na Figura 1-6. O resto dos bits ..p..r..rturn o valor. usando a
notaqao de base 2.

bitde sinal: 0 - positivo 1 = negativo

ryi I 00100r.1 bits de valores:

/ t__=\ byte: 7 bits representam 27 ou 128 valores


bit de sinal bit valores diferentes: de 0 a 127 ou de -128 a -1
fe
\ short: 1 5 bits podem representar 21
s
ou 327 68
short I 111110100000011 valores: de 0 at6 327 67 ou de -327 68 a -1,

Figuro 1-6 O bit de sinol de um byte


30 Copftulo 1 : Declorog6es e Conlrole de Acesso

A Tabela 1-3 mostra os tipos pdmitivos com os seus tamanhos e intervalos. A Figura 1-6 mostra que com um byte, Por
exemplo, h6256 nimeros possiveis (ou 2). Metade deles sio negativos, e metade - 1 sio positivos. A faixa positiva tem
um valor a menos da que a negativo porque o niimero zero 6 armazenado como um ntimero bin6rio positivo. IJsamos a
t) voc€
f6rmula -2&it" -r) pa112- calcular o intervalo negativo, e usamos -l&its - - 1 pata o intervalo positivo. Novamente, se

souber as duas primeiras colunas desta tabela, estar4 em boaforrnzpzra o exame.

Tobelo l-3 Intervolos de Primitivos Num6ricos

Tipo Bits Bytes Intervalo Minimo Intervalo Miximo

b)'t' 21 -1
)15 a15 1
short t6

1nt 5Z
.r3r )3r 1

163 a63_L I
long oz+ L

float JZ n/d n/d


double oz+ n/d n/d

O intervalo para nimeros de ponto flutuante 6 complicado de determinar, mas felizmente voc6 nZo precisa sab6-los para o
exame (embora 6 esperado que voc6 saiba que um double 64 bits, e um float armazena32).
^rmazen^
Para tipos booleanos nlohdum intervalo; um booleano s6 pode ser true ou false. Se algu6m lhe perguntar a
profundidade de bits de um tipo booleano, olhe bem nos olhos da pessoa e diga "depen de da mdqutna vktual" . F,la
ficar6 impressionada.

O tipo char (um caracter) cont6m um s6 caracter Unicode de 16 bits. Embora o coniunto ASCII estendido conhecido como
ISO Latin-1 precise de apenas 8 bits Q56 carzcteres diferentes), 6 necess6rio um intervalo maior pata rePresent^t car^ctetes
encontrados em linguas diferentes do ingl6s. Os caracteres Unicode, na verdade, sdo representados por ndmeros inteiros de
16 bits nio-assinalados, o que significa 216 tipos possiveis, que vio de 0 a 65535 Q\ -1. No Capitulo 3, voc6 aprender6 que,
pelo fato de um char ser na verdade um tipo de nrimero inteiro, ele pode ser atribuido a qualquer tipo de nfmero grande o
suficiente p^tz 65535 (o que significa qualquer coisa maior do que um tipo short. Embora tanto chars quanto
^rm^zenar
shorts sejam tipos de 16 bits, lembre-se de que um short usa l bitpara rePresentar o sinal, de modo que menos nfmeros
positivos sio aceit6veis em um short).

Declarando Vari6veis de Refer6ncia


Vari6veis de refet€ncia podem ser declaradas como variiveis s t at i c, vari6veis de instincias, parAmetros de m6todos ou
vari6veis locais. Voc6 pode declarar uma ou mais vari6veis de referCncia, do mesmo tipo, em uma mesma linha. No Capitulo
3, discutiremos as virias maneiras pelas quais elas podem setirnciahzadas, mas por agot^^presefltaremos apenas alguns
exemplos de declarag6es de vari6veis de refer€ncia:

Object o;
Dog myNewDogRe f erenceVariable ;

String sL, s2, s3; / / declara tr6s vari6veis Strinq

Variiveis de lnstincias
As varidveis de instdncias sio definidas dentro da classe, mas fora de qualquer m6todo, e s6 stro inrcia\zadas quando a classe
6 instanciada. As vari6veis de instincias sio os campos que pertencem a cada obf eto fnico. Por exemplo, o seguinte c6digo
define campos (vari6veis de instAncias) par^name (nome), tide (tftulo) err:'ar'aget (gerente) para obf etos employee
(funcion4rio):
n l : cc E'mnl nrrao {

// d.efine campos (vari5veis de instAncias) para instdncias de employee


private String name;
private String titl-e,
private String manageri
/ / ouLros c6digos aqui, incluindo os metodos de acesso para campos privados
JAVA 5 3I
A classe Employee antetior diz que cada instAncia de employee saber6 qual 6 o seu pr6prio nome, titulo e gerente. Em
ouras palavras, cada instAncia pode ter os seus valores irnicos para esses ff6s campos. Se voc6 vir os termos "campo",
"vari6vel de instdncia", "propriedade" ou "atributo", eles significam praticamente a mesma coisa. (I.{a verdade, existem
disting6es sutis, mas ocasionalmente importantes enfte os termos, contudo, elas nio sio usadas no exame.)

Parao exame,voc6 ptecisa saber que as varidveis de inst6ncias


I Podem usarqualquer um dos quatro niueis de acerso (o que significa que eles podem ser marcados com qualquer um dos
tr€s nodficadoret de acesso)

I Podem sermarcadas como f inal


I Podem sermatcadzscomo transient
I Nio podem sermarcadas como absLract.
I N6opodem sermarcadas como sinchroni-zed
I Nio podem sermatcadas como strictfp
I Niopodem sermarcadas como native
I Nio podem set marcadas como stat. ic, porque isso as transformatia emvati|veis de classe.

J6 abordamos os efeitos de se aplicar controle de acesso a vari6veis de instincias (funciona da mesma maneira que para
m6todos membros). Um pouco adiante neste capin:lo, veremos o que significa aplicar o modificador f inal oo t.ran-
sient zumavari|ve.Tdeinstincia.Primeiro,daremosumar6pidaolhadanadiferengaentrevari6veisdeinstAnciase
variiveis locais. A FiguraT-7 compara amaneirapelaqual os modificadores podem set aplicados a m6todos em contraste
com varidveis.

Vari6veis locais Varidveis (nioJocais) M€todos

final finaL tinaL


nrrhf i ^
yuvf+e nrrl.r'l'i
ysvrre a

protected hr^|-a-l-aA
Fr vevv ues

private nrirr.f-a

st.at. ict D LdLIU

transient
volatile abstract
synchronized
c|-ri al-fn

native

iguro l-7 ComporoEdo de modificodores pqro vori6veis x m6fodos

Variiveis Locais (Automatic/Stack/Method)


Varidveis locais sio aquelas declaradas dentro de um m€todo. Isso significa qu e avai|velnd.o 6 apenas inrciahzzda dentro do
m6todo, mas tamb6m declarada dentto dele. Assim como a vari6vel local iticjaasua vida denffo do m6todo, ela tamb6m 6
destruida quando o m6todo finaLzz. As vari6veis locais frcam sempre na pilha, e nio no heap (Falaremos mais sobre a pilha
e o heap no Capinrlo 3). Embora o valor da vanivel possa ser pass ado para, digamos, outro m6todo que enrao
valor em uma vari6Lvel de instincia, a vari6vel propriamente dita s6 vive dentro do escopo do m6todo. ^r^^"in o
Apenas nlo se esquega de que enquanto a variivel local est6 na pilha, se a vati6vel for uma referdncia a obietq o objeto
propriamente dito ainda ser6 criado no heap. Nio existe um objeto de pilha, apenas umavari6vel de pilha. Voc6
frlqiientemente ouvird programadores usarem a expressio "objeto local", o que eles realmente querem dizer 6 "variivel de
refer6ncia declarada localmente". Assim, se ouvir um programador usar essa expressio, vocd sabir6 que ele 6 simplesmente
preguigoso demais parausar o termo tdcnico mais preciso. Voc6 pode dizer a ele que n6s afirmamos is so a nio ser que ele
-
saiba onde nos moramos.

As declarag6es de varidveis locais nio podem usar a maioria dos modificadores que podem ser aplicados a vari6veis de
instincias, tais como public (ou os outros modificadores de acesso), transient, vo1ati1e, abstract ou
static, mas, como vimos anteriormente, as vari6veis locais podem ser marcadas como f ina1. E, como voc€ aprender6
no- Capitulo 3 (mas aqui vai um adianto), antes que uma vari6vel local possa ser usada,ela precisa ser inicialiTada.o- ,r-
valor. Por exemplo:
32 Copitulo I : Decloroc6es e Controle de Acesso

class Testserver {
public void loglnO {
int count = 10;
l)
l
l
Na maioria dos casos, voc€ vai iticiahzat umavariivel local na mesma linha em que a declarar, embora voc6 possa ainda ter
de rcintciall2|-la depois, no m6todo. A chave 6 se lembrar de que uma vari6vel local precisa s er iniciabzada antes de voc6
tentar us6-1a. O compiladot rejeitar6 qualquer c6digo que tente usar uma vari6vel local que ndo tenha recebido um valor,
porque - ao conffario das vari6veis de instAncias - as vadiveis locais n6o recebem valores-padrio.

Uma varidvel local nio pode ser referenciada em nenhum c6digo fora do m6todo no qual foi declztzdz. No exemplo de
c6digo anterior, seria impossivel referir-se dvari|vel count em qualquer outro lugar da classe exceto dentro do escopo do
m€todo logln ( ) . Novamente, nio queremos dizer com isso que o valor de count n6o possa ser passado pan fon do
m6todo para comegar uma nova vida. Mas a vari6vel que armazena esse valor, count, nio pode ser acessada depois de o
m6todo frnaltzar, como o seguinte c6digo inv6lido demonstra:
class Testserver {
public void logInO {
int. count = 10;
)
nrrl.r"l in rrnid dnenmafhina/int i \
'...-', t
count = i; // Ndo vai compilarl Nao 6 possivel acessar count
// de fora do m6todo logino
I)

)
,4
E possivel declarar uma.vari6vel local com o mesmo nome que uma vari6vel de instincia. Isso 6 conhecido como
sonbreamento, como o seguinte c6digo demonstra:

class Testserver {
int count = 9; / / Declara uma vari6vel de instAncia chamada count
public void logInO {
int count = 10; // Declara uma vari6vel 1oca1 chamada count
System.out.println("1ocal variable count is " + count),'
I
)

public void count O {


System.out.println("instance variable count is " + count);
)

public static void main(Stringtl args) {

new Testserver O . loglnO ;


new TestServer O .count (),.

i
i
O c6digo acimaproduz a seguinte saida:
loca1 variable count is 10

instance variable count is 9

Mas por que razdovoc6.iiaquerer fazer isso?


Normalmente, voc6 n6o vai. Mas uma das raz6es mais comuns € pan dzr a um parAmetro o mesmo nome que a vai6vel de
instAncia i qual o parimetro ser6 atribuido. O seguinte c6digo (incotreto) est6 tentando definir o valor de uma vari6vel de
instAncia usando um parAmetro:

class Foo {
int size = 27;
JAVA 5 33
hrr'|.\'l i r'^.i raf qi to
vvfu A Deuer-s\frrL (inf <.i zo\
ofzs/ I
IJu!fre ^ I

size = size; // // ??? qual size 6 igual a qual size???


)

]
Entio vocd decidiu que - para melhor Iegibilidade - voc€ qu er dx ^o parrametro o mesmo nome que a vari6vel de instincia para
aqual o seuvalor se destina, mas como resolver a cotseo dos nomes? Use a palavrz-chavethis. Apalavn-chave this
sempre, sempre, semPre se refere ao ob,eto sendo executado atualmente. O seguinte c6digo mosta isso na pretica:

class Foo {
int size = 2'7 ;
public void setsize(int size) {
this. size = size ; / / L}ris. size significa a vari6vel de instAncia
/ / do objeto atual , slze. O valor de size
// d, direita 6 o parametro
l
l
l

Declarag6es de Arrays
EmJava, os arrays sio objetos qve m mriltiplas vari6veis do mesmo tipo, ou varilveis que sio todas subclasses do
^rmazen
mesmo tipo. Os attays podem arm^zeflar owprimitivos ou referdncias a obf etos, mas o pr6prio anay serS,sempre um
obieto no heap, mesmo se o array for declarado paraarmzrzerrar elementos primitivos. Em outras palavras, nio existe um
array primitivo, mas vocd pode criar um array de primidvos.

Para o exame, voc6 precisa saber ffes coisas:

I Como cizrwavai|vel de refer6ncia a um array (declarar)

I Como criar um objeto array (construir)


I Como preencher o array com elementos (inicializar)

Para este obietivo, voc6 s6 ptecisar6 saber como declarar um array; n6s abordaremos a construgio e airttciilrzagdode artays no
Capitulo 3.

AO TRABALHO

Os analt sdo efcientes, mat muitat uerys uoci det/ard usar am dos tipos Collecion fu j ava . ut i 7 (incluindo HashlvIap,
ArrayList e TreeSet). At classes Collection oferecen maneiras na*fuxzueis de acessar am objeto (para inurgdo, apaganentl,
/eitara por diante) e, ao contniio dos ara1s, podem se expandir ou contrair dinamicamente i medida que uoci adiciona ou remoae
e assim

elementos. Existe un tipo Collection para ltma amp/a gama de necessidadu. Vocd precisa de una classifcagdo nipida? De /4n grupt de objetot
sen dup/icatas? De uma maneira dn acessar um par de nome-ualor? O Capituk 7 os aborda com nais detalbes.

Os arrays sio declarados informando-se o tipo de elementos que o alray iri arrnazefl r (um objeto ou um primitivo),
seguido por colchetes em um dos lados do identificador.

Derlaranclo um Arral de Pinitiuot

int I J key; // Colchetes antes do nome (recomendado)


int key I J ; / / colchetes depois do nome (v61ido, mas menos legivel)
Declarando am Aray de Refer1ncias a Obietos

Thread [ ] threads; / / Pccnmond:dn

Thread threads [ ]; // val-i-do, mas menos leglvel

AO TRABALHO

Ao declarar ama referincia a anq,\ uoci deue sempre co/ocar o: colchetet do aralt imediatamente depois do tipo du/arado, em ueqde depois do
identfrcador (nome da uariduel). Dusaforma, qualqaer um qae leia o aidigo sabertlfaci/menh qaq por exenpl0, ke1 i uma referlncia a um
objXo de arrEt int, e ndo um pimitiuo int.
34 Copiiulo 1 : Declorog6es e Controle de Acesso

Podemos tamb6m declarar arrays multidimensionais, que, na verdade, s6o arrays de arrays. Isso pode ser feito da seguinte
maneira:

String[ J t ] [ ] occupantName;
String I J ManagerName [ ];
O primeiro exemplo 6 um array ridimensional (um array de arrays de anzys), e o segundo 6 bidimensional. Repare no
segundo exemplo, o quzltnz um par de colchetes antes do nome da vari6vel e um par depois. Isso 6 perfeitamente v6lido
para o compilador, provando mais uma vez que o fato de ser vdlido nio necessariamente indica que 6 bom.

OBSERVAQ6BS pene O EXAME

Nanca d adlido inclair o tamanho do arral na saa declaragdo. Sim, n6s sabertos que uocd podefaryr isso em algumat outras linguagens, que i
a raqdo pela qual uoci podeni uer uma questdo ou duas que ineluam aidigo parecido com o seguinte:

int [5] scores;


O cddigo acima ndo uai compilar. Itmbre-se, a JI./M ndo aloca etpapo ati que uoci defato in$ancie o objeto array Sd entdo d que o tamanbo

fa1 dtferenga.

No Capitulo 3, passaremos um bom tempo discutindo arrays, como os trnciahzar e usar, e como lidar com arrays
multidimensionais... Fique l-igado!

Variiveis Final
Declararumavari6velcom^palaw^-ch^vefinal impossibilitaareutilizagiodessavari6veldepoisdeelatersido
iniciahzada com um valor explicito (repare que dizemos explicito, e nio padrio). Para primitivos, isso significa que, uma vez
que avai|vel tecebeu um valor, esse valor n6o poder6 ser alterado. Por exemplo, se voc6 atribuit 70 d,vai|veI int x, entio x
vai permanecer como 10 para sempre. Isso 6 bem simples para primitivos, mas o que significa terwmavai|vel de referdncia
aobjeto f inal?Umavari6veldereferdnciamarcadacomo f inal- nSopode jamaisserrearibuidaparareferir-seaum
objeto diferente. Os dados dentro do objeto podem ser modificados, mas a varidvel de refer€ncia n6o pode set modificada.
Em outras palavras, uma referdncia f inal- ainda lhe permite modificar o estado do objeto ao qual se refere, mas voc6 nio
pode modificar avairdveldercfer€nciaparafaz€-laserefeir a um obieto difetente. Decore isto: nio existem objetos f inal,
apenas referdncias f inal. Explicaremos isso com mais detalhes no Capinrlo 3.

Agora jd estudamos como o modificador f inaL pode ser aplicado a classes, m6todos e vad6veis. A Figura 1-8 mostra as
principais caracteristicas e diferengas das virias aplicag6es de final.

classe classe final Foo a clasrc f j-nal- ndo

mdtodo cfasse Baz o nrltodo f inal nio


finrl rrnirl
vvru an/
Jv \
\/

classe Bat estende Ba

rinaffid so ( )

variivel classe Roo a uariduelf inal nio


fi"al i"t sir. = pode receber um valor
42; novo, depois de ter sido
criado o m6todo inicial (a
auibuigio inicial de um
,roi-ffi"rrgsize (

Figuro 1-8 Efeito de finol sobre vori6veis, m6fodos e closses


JAVA 5 35
Vari6veis Transient
Se marcar uma vari6vel de instdncia como transient, voc6 estar6 dizendo dJ\M para ignorar ess avaiilvelquando voce
tentat seria\zar o objeto que a contem. A serializagio 6 um dos recursos mais legais deJava; ela lhe permite salvar (o que As
vezes se chama de "flatten') um objeto escrevendo o seu estado (em outras palavras, o valor das suas vari6veis de
instincias) em um tipo especial de stream de E/S. Com a serializagio vocd pode salvar um objeto em um arquivo, ou at6
enviilo affav6s de uma conexio para ser "re-inflado" (deseridtzado) do outro lado, em outraJ\M. A serializagio foi
adicionada ao exame na vetsioJava 5, e falaremos dela com mais detalhes no Capitulo 6.

Vari6veis Volatile
Omodificadorvolatile diziJVMqueumthreadqueacesseavari6veldevesemprereconci-liarasuac6piaprivate
da vari6vel com a c6pia master ptesente na mem6ia. Como 6 que 6? Nio se preocupe com isso. Para o exame,tudo o que
voc6precisasabersobrevolatile 6que,assimcomotransient,essemodificadors6podeseraplicadoavari6veis
de instAncias. Nio se engane, a id6ia de multiplos threads acessando uma vari6vel de instAncia € assustadora, e 6 muito
importante que todo progtamadorJava a entenda. Mas, como ver6 no Capinrlo 9, voc6 provavelmente usar6 a
sincronizagio, em vez do modificador vol-at i l-e ,p^rz.torrr r seus dados i prova de threads.
O modift.cad.orvolaLile ("vol6til') tambdm pode ser apl:icado a gerentes de proJetos )
Vari6veis e M6todos Static
Omodificadorstatic 6usadoparacizrvai|veisem6todosqueirioexistirindependentementedequaisquerinstdncias
criadasparaaclasse.Emouftaspalavras,osmembrosstatic existemantesmesmodevoc6criarumanovainstinciade
uma classe, ehaver| apenas uma c6pia do membro stat ic, independentemente do nrimero de instdncias dessa classe.
Em outras palavras, todas as instAncias de uma dada classe compartilham o mesmo valor para qualquervait6vel stat ic.
Falaremos de membros static com mais detalhes no pr6ximo capitulo.
O que voc6 pode marcar como static:
I M6todos
I Vari6veis

I Uma classe aninhada dentro de outra classe, mas n6o dentro de um m6todo (falaremos mais sobre isso no Capitulo 8).
I Blocos de inicializagdo

O que voc€ nlo pode marcar como s t at i c:


I Construtores (nio faz senado;os constfutores somente s6o usados para criarinstAncias)
I Classes (a nio ser que esteiam aninhadas)

I Interfaces

I Classes internas locais de m6todos (veremos isso no Capitrrlo 8)

I M6todos de classes internas e vari6veis de instincias


I Vari6veis locais

Declarando Enums
A partit da versio 5.0,Java lhe permite restringir uma vari6vel para ter um de apenas uns poucos valores prd-definidos em outras
-
palawas, um valor de uma lista enumerada. ( Os itens da lista enumerada sio chamados, sulpreendentemente, de enums.)

O uso de enums pode ajudar a reduzir os bugs no seu c6digo. Por exemplo, na sua aplicagio de automagio de
lanchonetes, voc6 poderia desejar reduzir os tamanhos de caf6s possiveis a BIG ("gande"), HUGE ("enorme') e OVER-
WHELMING ('absurdo'). Se voc6 deixar a possibilidade que um pedido de tamanho LARGE ("grande') seja feito, isso
poderia causar um erro. Entram em agdo os enums. Com a simples declatagio a seguir, vocd poder6 garantir que o
compilador o impedir6 de atribuir qualquer coisa a um Coffeesize que nio seja BTG, HUGE ou OVERWHELMING:

enum CoffeeSize { erc, HUGE, oVERwHELMING };


Dai em diante, a rinica maneira de se obter um Co f f e e s i z e ser6 com um a declaragdo parecida com esta:
CoffeeSi-ze cs = CoffeeSize,BIG;
Nio 6 obrigatdrio que as constantes enums estejam escritas totalmente em mairisculas, mas, tomando emprestado da
convengio de c6digos da Sun que detetmina que as constantes tenham os seus nomes em mairisculas,6 uma boa id6ia
faz€Jo aqui.
36 Copftulo I : Decloroc6es e Controle de Acesso

Os componentes b6sicos de um enum sio as suas constantes (ou seja, BIG, HUGE e OVERWHELMING), emboravoc€
v6 ver logo adtante que pode haver muito mais em um enum. Os enums podem ser declarados como as suas pr6prias
classes separadas, ou como membros de classes, mas nlo podem ser declarados dentro de um m6todo!

Declarando um enum fora de uma classe:


enum CoffeeSize { erc, HUGE, oVERWHELMTNG I / / n5o pode ser
/ / private nem protect

class Coffee {

CoffeeSize size;
l
J

public class CoffeeTestl {


public static void main(Stringtl args) {
Coffee drink = new Coffee ( ) ;
dri-nk. size = Cof feeSize.BIG; // enum fora da cl-asse

]
O c6digo acima pode fazer parte de um s6 arquivo. (Lembre-se, o arquivo deve set nomeado como CoffeeTestl.iava,
porque esse 6 o nome da classe pfblica do arquivo.) A principal coisa a se lembrar 6 que o enum pode ser declarado somente
comomodificadorpublic ouodefault,assimcomoumaclassenio-interna.Eisumexemplodedeclaragiode
errum dentro de uma classe:

c-Lass uorreez { ^l

enum coffeesize {erc, uuce, oVERWHELMTNG }

CoffeeSize size;
I)

public class CoffeeTest2 {


public static void main(Stringtl args) {
Coffee2 drink = new Coffee2 O ;
drink. size = Coffee2 . CoffeeSize . BIG; ,z/ incluindo classes
/ / nome requerido
)
l
J

As principais coisas a se lembrar desses exemplos sio que: 1) enums podem ser declarados como as suas pr6prias classes,
ou podem ser incluidos em outra classe; e 2) que a sintaxe para se acessar os membros de um enum depende de onde o
enum foideclarado.
O seguinte exemplo NAO 6 v6lido:
public class CoffeeTestl i
public static void main(Stringtl argts) {
enum coffeesize { erc, HUGE, oVERWHELMTNG } // ERRADo! Nao se
/ / pode declarar enums
// em m6todos
Coffee drink = new Coffee O ;
drink. size = CoffeeSize.BIG;
)
I)
Panfazer as coisas ficarem mais confusas pzravoc€,os elaboradores da linguagem Java frzeram opcional a colocagdo de
JAVA 5 37
ponto-e-virgula no final da declatagdo do enum:
public cl-ass CoffeeTestl- i

enum coffeesize { erc, HUGE, OVERWHELMTNG I; / / .- o ponto-e-virgula


| / e
< ^^^:
// ^-^-
opcrona_L aqu]-

public statj.c void main(StringtJ args) {


Coffee drink = new Coffee O ;
drink. si_ze = CoffeeSize.BIG;
)

P"lT,o que 6criado quando voc6 cria um enum? O mais importante a se lembrar 6 que enums nlo sio Strings nem
ints! CadaumdostiposenumeradosdeCoffeeSize 6naverdadeumainstinciadeCoffeeSize.Emou-tras
palavras, BIG 6 do tipo Cof f eeSize. Pense em um enum como um tipo de classe, que 6 parecido (mas nio
exatamente) com isto:

,// exemplo conceitual- de como voc6


/ / pode entender os enums

class CoffeeSize {
public static final CoffeeSize BTG =
new Cof f eeSize (..BIG,' , 0) ;
public static flnal CoffeeSize HUGE =
new CoffeeSize ('.HUGE,,, I) ;
public static final CoffeeSize OVERWHELMTNG =

new CoffeeSize (.'OVERWHELMfNG,,, 2 ) ;


public CoffeeSize(String enumName, int index) {
// mais coisas aqui
I
)

public static void main(Stringtl args) {


System. out . println (CoffeeSize . BIG) ;
]
)
Repare como cada um dos valotes enumerados, BIG, HUGE e OVERWHELMING, 6 uma instAncia do tipo
Cof f eeSize. EIes sio representados como static e f inal-, o que no mundo Tava corresponde a uma constante.
Repare tamb6m que o valor de cada enum conhece o seu indice o.. poiigao... Em o.rtias palavras, a ordem na qual os
enumssdodeclaradosfazdiferengz.Voc€podepensarnosenums deCoffeeSj-ze iomofazendopatedieumarray
do tipo Cof f eeSi ze, e, como ver6 em um capitulo postedor, voc6 pode iterar atrav6s dos valor de um enum
invocando o m€todo val-ues ( ) em qualquer tipo de enum.
Q.,Tio se preocupe com isso neste capitulo.)

Declarando Construtores, M6todos e Variiveis em um enum


Pelo fato de um enum ser na verdade um tipo especial de classe, voc €. pode fazer mais do que apenas listar os valores das
constantes enumeradas. Voc€ pode adicionar consffutores, vari6veis de inst|ncias, m6todos e uma coisa bastante estranha
chzr:nada corpo de c/asse especfico da constante.Pan entender por que voc6 poderia precisar ter mais coisas no seu enum, pense
neste cen6rio: imagine que voc6 queira saber o tamanho exato, em ongas, que corresponde acadavmadaa aonrt"nta, f,.
CoffeeSize.Porexemplo,voc6querdeixarclaroqueBlG tem8ongas,HUGE teml0onqaseOVERWHELMING
tem inacredit6veis 16 ongas.

Voc6poderia criar algtm tipo de tabela de busca, usando alguma outra estrutura de dados, mas isso seria um design ruim e
dedificilmanutengio.Amaneiramaissimples 6ttataro.r."lo.e.dosseusenums (BIG,HUGE eOVERWHELMING)
como obietos que podem ter as suas pr6prias vari6veis de instincias. Ent5o, voc€ poder6 atribuir esses valores no momento
em que os enums forem inicializados, passando um valor ao construtor do enum. Isso precisa ser explicado com um
pouco mais de detalhes, mas, primeiramente observe o seguinte 6fdigo:
enum CoffeeSize {
38 Copitulo I : Declorqc5es e Conlrole de Acesso

B]G (8), HUGE (10), OVERV'THELM]NG(16) ;


/ / os argumentos ap6s o valor do enum sdo "passados"
/ / como valores para o construtor

CoffeeSize(int ounces) {
this.ounces = ounces; / / atrtbu]. o valor a
/
t | .._^ ----r:-re1
/ uttt4 vd!r4! de instancia
)
private int ounces; / / uma vari6vel de instdncia que o valor
de cada enum tem
publj-c int getounces Oi
ral- rrrn nrrndac.

i
)

cJ_ass colIee
a

t
CoffeeSize size; cada instAncia de Coffee tem um

enum CoffeeSize

public static void main(StringIJ args) {


Coffee drinkl = new Coffee O ;
drinkl . slze = CoffeeSize.BIG;

Coffee drink2 = new Coffee O ;


drink2 . size = CoffeeSize.OVERWHELMING;

System. out println (drinkl- . size . getounces


. ( )) ; exibe 8

System. out.println (drink2. size. getOunces ( )); exibe 16

]
Os principais pontos a se lembrar sobre os constflrtores de enums sio:
f NUNCA 6 possivel invocar um construtor de enum diretamente. Esse construtor 6 invocado automaticamente! com
os argumentos que vocd define ap6s o valor da constante. Por exemplo, BIG ( I ) invoca o construtor Cof f eeSize
que usa um int,
passando o literal 8 ao construtor. (I',los bastidores, 6 claro, voc6 pode imag1nar que BIG
int
tamb6m 6 passado ao construtor, mas nio precisamos saber - nem nos importarmos com - os detalhes.)
I Vocd pode definir mais de um argumento para o construtor, e pode sobrecarregat os construtores do enum, assim
como pode sobrecarregar um construtor normal de classes. Discutiremos os construtores com muito mais detalhes no
Capitulo 2.ParairuciaJtzar um Cof f eeType contendo ao mesmo tempo o nfmero de ongas e, digamos, um tipo de
lid, voc6 passaria dois argumentos ao construtor, ta fotma BIG ( I , "A" ) , o que significa que voc6 tem um
construtor em Cof f eeSize que usa tanto um int quanto uma string.
E, finalmente, voc6 pode definir algo realmente estranho em um enum, que se pafece com uma classe intema an6nima
(sobre a qual falaremos no Capinrlo 8). E o chamado corpo de classe especifico da constate, e voce pdoe us6Jo quando
precisar que determinada constante substitua um metodo definido no enum.

Imagine este cen6rio: voc6 quer que os enums tenham dois m6todos - um para ongas e um para c6digo de registro (uma
String). Agora imagine que a muorja dos tamanhos dos caf6s usa o mesmo c6digo, "8", mas o tamanho OVERWHELM-
ING usa o tipo "A'. Voc6 pode definir um m6todo getlidcode ( ) no enum Cof f eesize que retorne "8", mas
..rr. ."ro rro.6 precisa de uma forma de substinriJo para OVERWHELMING. Voc6 nio quer colocar um c6digo if / then
de dificil manutengio no m6todo getlidcode ( ) , entio a melhor saida poderia ser fazer com que a constante OVER-
WHELMING de alguma forma substitua o m6todo getlidCode O .
Isso parece esttanho, mas voc6 precisa entender as regras bisicas de declaragio:
JAVA 5 39
(-nffcaQ i za I

BIG(8),
HUGE (r_0) ,

OVERWHELMING ( 16 ) ttbloco de c6digo que defina


t,// ininie rrm

/ / o "corpo" para esta constante


public String getlidcode O { // substitua o m6todo
/ / definido em Coffeesize
return rrA";
)

); // .- o ponto-e-virgula 6 OBRIGAT6RIO quando h6 um corpo


CoffeeSize (int ounces) {
this.ounces = ounces;
)

private j-nt OUnCeS;

public int get.Ounces O {


reEurn ounces;
)
public String get.LidCode () { // este m6t.odo 6 subsriruido
/ pe!a consranre
/| / ^^1 OVERWHELMING
rafrrrh !rQrr.
/ / o va\or padrao que queremos retornar
/ / para as constantes CoffeeSize
)

Ap6s absorver o material d,este capitulo, voc€ dever6 estar familiarizado com algumas das nuances da linguagemJava. Voc6
poder6 talvez se sentir confuso sobre por que teve a id6ia de fazer este exame. Iiso 6 normal a esta altura. Caio esteia
ouvindo a si mesmo dizendo "onde eu estava com a cabega?",basta se deitar e descansar at6 que isso passe. N6s
gostariamos de poder dizer que fica mais f6cil, que este foi o capitulo mais dificil e que daqui em diante fica tudo menos
complicado...

Vamos rever brevemente o que vocd precisar6 saber para o exame.

Haverd muitas quest6es indiretamente relativas a palavras-chave, entao, certifique-se de que sabe identificar quais sio
palawas-chave reais e quais ndo sio.

Embora as convengoes de nomeagio como o uso de camelCase nao caiam diretamente no exatne, ainda assim voc6 ter6 de
entender os fundamentos da nomeagioJavaBeans, a qual usa camelCase.

Voc€ precisa entender as regras associadas com a criagio de identificadores v{-lidos, e as regras associadas com declarag6es de
c6digo-fonte, incluindo o uso de declarag6es package e import.
Agora voc6 tem um bom entendimento do controle de acesso no que se refere a classes, m6todo e vari6veis. Voc6 j6 viu
como os modificadores de acesso @ub1ic, protected e private) definem o controle de acesso de uma classe ou
um membro.
Voc€ aprendeu que as classe,s abstract podem conter tanto m6todos abstract quanto nio-abstract., mas que
se um s6 m6todo for marcado como abstract, entao a classe deve ser marcada como abstract.
Nio se esquega de
que uma subclasse concreta (nio-abstract) de uma classe abstract deve fornecerimplementagdes para t;dos
os
m6todos abstract da superclasse, mas que uma classe abstract nio precisa implerientar os m6todos ab-
stract da sua superclasse . Uma subclasse abstract pode "passar a boli" paraapiimeira subclasse concreta.
Examinamos a implementagio de interfaces. Lembre-se de que as interfaces podem estender uma outra interface (ou
mesmo multiplas interfaces), e que qualquer classe que implemente uma interface deve implementar todos os m€iodos de
todas as interfaces da drvore de heranga da interface que a classe est6 implementando.
40 Copftulo I : Decloroc6es e Controle de Acesso

Tamb6m vimos os outros modificadores, incluindo static, f inal-, abstract, synchronized e assim por
diante. Voc6 aprendeu como alguns modificadores nunca podem ser combinados em uma declangdo,pot exemplo,
misfurar abstract com f inal- ou pri-vate.
Tenha em mente que nio existem obietos f inal ernJzva. Uma variivel de refer6ncia marcada como f inal- nunca
poder6 ser modificada, mas o objeto a que se refere pode ser modificado.

Voc6 viu que f inal aplicado a m6todos significa que uma subclasse nio os poder6 substituir, e, quando aplicado a uma
classe, a classe final nio poder6 ser subclassificada.

Lembre-se que, a partir d oJava 5,os m6todos podem ser declarados com um parimetro var- arg (que pode usar de zeto
a muiros argumentos do tipo declarado), mas que voc€ s6 pode ter um var - arg por m6todo, e ele deve ser o ultimo
parAmetro do m6todo.
Certifique-se de estar famt\arizado com os tamanhos relativos dos primitivos num6ricos. Lembre-se de que, enquanto os
valores de vad6veis nio- f i na l- podem ser modificados, o tipo de uma vari6vel de refer6ncia nio pode.

Voc€ aptendeu tamb6m que arrays s5o obietos que contdm muitas variiveis do mesmo tipo. Os arrays podem tamb6m
contef ouffos aftays.
Lembre-se do que aprendeu sobre varidveis e m6todos static, especialmente que os membros static sio usados
por-classe emvez de por-instincia. Nio se esquega de que um m6todo stat ic nio pode acessar diretamente uma
vairivel de instincia apartu da classe onde reside, porque ele nio tem uma referdncia explicita a nenhuma instencia
particular da classe.
Finalmente, abordamos rrn recurso novo doJava 5, enums. Um enum 6 uma forma muito mais segura e fleivel de se
implementar constantes do que era possivel em vers6es anteriores deJzva. Pelo fato de serem um tipo especial de classe, os
enums podem ser declaiados de forma bastante simples, ou podem ser bem complexos - incluindo atributos tais como
m6todos, varidveis, construtores e um tipo especial de classe interna chamada de corpo de classe especifico da constante.

Antes de fazet o teste de treinamento, passe algum tempo com o otimistamente chamado "Exercicio Ripido". Volte a
consultat esse teste freqrientemente, dL medida que for lendo este livro e especialmente quando estiver perto da prova e voc6
estiver tentando memorizar tanto quanto conseguir. Porque - e eis aqui o conselho que voc6 gostaia que sua mie tivesse
lhe dito antes de voc6 ir p^tz^ faculdade - nio importa o que voc6 sabe, o que importa 6 quando voc6 sabe.

Para o exame, saber o que voc6 ndo pode fazer com a linguagemJava 6 tio importante quanto saber o que voc6 pode fazer-.
Experimente as quest6;s de amostra! Elas sio bastante semelhantes i dificuldade e ) estrutura das quest6es do exame real, e
deverio lhe abrir bs olhos para o quio dificil o exame pode ser. Nao se pre ocupe se errar vdrias delas. Se voc6 perceber que -
tem dificuldade em um t6pico especifico, passe mais iempo revisando-o e estudando-o. Muitos programadores precisam de
duas ou tr6s leituras s6rias de um capitulo (ou um objetivo individual) antes de conseguirem respondet is quest6es com
confianca.

{ Exercicio Ripido
Lembre-se de que quando falamos de classes neste capihio, estamos nos referindo a classes n6o-internas, ou classes de nivel
mais alto. Dedicaremos todo o Capitulo 8 is classes internas.

ldentificadores (Objetivo | .3)


E Os identificadores podem comegar com uma letra, um underscore, ou um caracter monet6rio.
E Depois do primeiro car^cter,os identificadores podem incluir tamb6m digitos.
E Os identificadores podem ter qudquer extensio.
D Os mEtodosJavaBeans devem ser nomeados usando-se camelCase e, dependendo do prop6sito do m6todo, devem
comegar com set ("define'), get ("obt6m'), i s("6'), add("adiciona") ou remove.

Regras de declaragSo (Objetivo l.l)


E Um arquivo de c6digo-fonte s6 pode ter uma classe priblica.
E Se o arquivo de c6digo-fonte tiver uma classe priblica, seu nome terA que coincidir com o dessa classe.
D O arquivo s6 pode ter uma instrugio de pacote,por€m,v6izs de importaqdo.
E A instrugeo de pacote (se houver) deve ficar na primeira linha (fora os comentarios) do arquivo de c6digo-fonte.
E A instruq6o de importaqio (se houver) deve vir depois do pacote e antes da declaragio de classe.

O Se nao houver instrugio de pacote, as instrug5es de importagio terZo que ser as primeiras (fora os comentArios) do
arquivo de c6digo-fonte.
fl As instrug6es de pacote e de importagio slo aplicadas a todas as classes do arquivo.

E O arquivo pode ter mais de uma classe nio priblica.


JAVA 5 4I
E Os arquivos que nio tiverem classes pfblicas nio apresentario restrig6es de nomeagio.

Modificadores de acesso a classe (Objetivo l.l)


0 ga t€s modificadores de acesso: publ ic , protected e private.
E H6 quatro niveis de acesso: public, protected, def ault e private.
E As classes s6 podem ter acesso publ ic ou d.ef ault .

D A visibilidade das classes gira em torno de se o c6digo de uma classe pode:


E Criar uma instdncia de outra classe
E Estender (ou criar subclasses) outra classe
E Acessar m6todos e vari6veis de outra classe

Modificadores de classe (n6o referentes a acesso) (Objetivo 1.2)


E As classes tamb6m podem ser alteradas com f ina1, abstract ou strictfp.
E Uma classe nio pode ser f inal- e abstract.
E Uma classe f inal- n6o pode ter subclasses.
E Uma classe abstract nio pode serinstanciada.
E Uma classe com somente um m6todo abstract significa que a classe inteira deve ser abstract.
E Uma classe abstract pode ter m6todos abstracts ou ndo.
E Aprimeiraclasseconcretaaestenderumaclasseabstract ter6queimplementartodososm6todosabstracts.

lmplementagio de interfaces (Objetivo 1.2)


D Asinterfacessiocontratosquedefinemoqueaclassepod,er6.fazer,masndodtzemnadasobreamaneirapelaqualela
deverS,faz€-Io.

E As interfaces podem ser implementadas por qualquer classe, de qualquer drvore de heranga.

E A interface 6 como uma classe 100%o abstract, e ser6 implicitamente abstract caso voc6.ligite ou nio o
modificadot abs t rac t na declaragd.o.
E Uma interface s6 pode ter m6todos abstracts, nenhum m6todo concreto 6 permitido.
El Osm6todosdasinterfacessio,porpadrio,public eabstracts -adeclaragioexplicitadessesmodificadores6
opcional.
E Asinterfacespodemterconstantes,quesiosempreimplicitamentepublic, staticefinal.
E Asdeclarag6esdaconstantedeinterfacecompublic,static efinal sioopcionaisemqualquercombinagio.
E Uma classe de implementagio nio-abst.ract va)tdatefi.as propriedades a seguir:
E Fornecer6 implementag6es concretas dos m6todos da interface.
E Deve seguir todas as regras de sobrecarga v6lidas para os m6todos que implementa.
E Ndo deve declarar nenhuma excegio nova do m6todo de implementagio.
E Nio deve declarar nenhuma exceg6o que seja mais abrangente do que as declaradas no m6todo da interface.
E Pode declarar exceg6es de tempo de execugio em qualquer implementagio de mdtodo da interface, independente do
que coostar na declarag6o da interface.

E Deve manter a assinatura (sio permitidos retornos covariantes) e o tipo de retorno exatos dos m6todos que
implementa (mas nio precisa declarar as exceg6es da interface).
E Umaclassequeestiverimplementandoumainterfacepodeelapt6priaserabstract.
E Umaclassedeimplementagioabstract nloprecisaimplementarosm6todosdainterface(masaprimeirasubclasse
concreta pfecisa).

E A classe s6 pode estender uma classe (sem heranga multipla), por6m, pode implementar v6rias.
E As interfaces podem estender uma ou mais interfaces.
E As interfaces nio podem estender uma classe ou implementar uma classe ou interface.

E Quando ftzer o exame,vetifique se as declaragSes de interface e classe sio v6lidas antes de verificar outras
l6gcas do c6digo.
42 Copftulo I : Decloroc6es e Controle de Acesso

Modificadores de acesso a membros (Obietivos 1.3 e 1.4)


E Os m6todos e as vari6veis de inst6ncia (nio locais) sdo conhecidos como "membros".
fl Os membros podem usar todos os quatro niveis de acesso: public, protected, def aul-t, private.
E O acesso aos membros se d6 de duas formas:
D O c6digo de uma classe pode acessar um membto de outra classe
f,l Uma subclasse pode herdar um membro de sua superclasse.
E Se uma classe ndo puder ser acessada, seus membros tamb€m ndo poderio.
E A visibilidade da classe deve ser determinada antes da dos membros.
D Os membros pub 1 i c podem ser acessados por todas as outras classes, mesmo de pacotes diferentes.
D Se um membro da superclasse for publ i c, a subclasse o herdat6 - independente do pacote.
fl Os membros acessados sem o operador ponto (.) t6m que pertencer i mesma classe.
D tnis sempre referenciarS.o objeto que estiver sendo executado no momento.
fl tnis.aMethod( ) 6omesmoquesimplesmentechamaraMethod( ).
E Os membros private s6 podem ser acessados por um c6digo da mesma classe.
D Os membros private n6o ficam visiveis p^r^ as subclasses, portanto, nZo podem ser herdados.
E Os membros def ault e protect s6 diferem quando subclasses estio envolvidas.
B Os membros def ault s6 podem ser acessados por outras classes do mesmo pacote.
E Os membros protect podem ser acessados por outras classes do mesrno pacote, al6m de pot subclasses,
independente do pacote.

E protect = pacote + kids (kids significando subclasses).


E Por subclasses externas ao pacote, o membro protect s6 pode ser acessado affavEs da heranga: uma subclasse
externa ao pacote nio pode acessar um membro protect usando a refer6noa a uma instAncia da superclasse (em
outras palavras,ahetangzb o rinico mecanismo para uma subclasse externa ao pacote acessaf urn membro protect
de sua superclasse).

D Um membro protect herdado por uma subclasse de outo pacote nio pode ser acessado por nenhuma outra
classe do pacote da subclasse, exceto Pelas pr6prias subclasses dessa.

Vari6veis locais (Objetivo 1.3)


D As declarag6es de varidveis locais (de m6todo, autom6ticas, de pilha) nio podem ter modificadores de acesso.

E f inal 6 o,inico modificador disponivelpzrzvzi|veis locais.


E As vari6veis locais nio recebem r-alores padriq portanto, devem ser inicializadas antes do uso.

Outros modificadores - membros (Objetivo 1.3)


E Os m6todos f inal nio podem ser sobrecarregados em uma subclasse.
E Os m6todos absgract foram declarados, com runa assinarura, um tipo de retorno e uma cl6usula throws opcional,
mas nio foram implementados.
E Os m6todos abs t rac t terminam com urn ponto-e-virguIa, e ndo chaves.
E H6 tr6s maneiras de identificar um m6todo n6o abstract :

E O m6todo ndo 6 marcado como abstract.


E O m6todo possui chaves.
E O mdtodo possui um c6digo entre as chaves.

E Aprimeiraclassenio-abstrata(concreta)aestenderumaclasseabstract deveimplementartodososmdtodosab-
stract dessa.
D O modificador synchroni zed s6 6 aplicado a m6todos e a blocos de c6digo.
O Osmdtodos synchronized podemterqualquercontroledeacessoetamb6mseremmarcadoscomo f inal.
E Os mdtodos abstract devem ser implementados por rxna subclasse, porantq tem de ser herdados. Por essarzzdo:
E Os m6todos absuract ndo podem ser private.
E Os m6todos absLract nio oodem ser f inal.
JAVA 5 43
E O modificador nat ive s6 6 aplicado a m6todos.

D Omodificadot strictfp s6 6apJicado aclasses em6todos.

M6todos com Argumentos Vari6veis (var-args) (Objetivo 1.4)


E A partir de Java 5,os m6todos podem declarar um p ardmetro que aceita de zero avdriosargumentos, 6 o chamado
m6todo var-arg.
O Um parimetrov^r-zrgedeclarado com a sintaxe tipo... nome; por exemplo:
doStuff (int... x) { }
E Um m6todo var-arg s6 pode ter um parim etro var'zlrg.
E Em m6todos com parimetos normais e um var-arg, o var-arg deve vir por ultimo.

Declarag5es de Vari6veis (Objetivo 1.3)


fl As vari6veis de instincia podem:
E Ter qualquet tipo de contole de acesso
E Seremmarcadas como finaL ou transl-ent
D Asvari6veisdeinstAncianiopodemserdeclaradascomabstract, sychronized, nativeoustrictfp.
D E valido declatar uma v ari|vellocalcom o mesmo nome de uma vari6vel de instincia; isso 6 chamado de
"sombreamento".
E As variiveis f inal apresentam as seguintes propriedades:
E Nao podem ser reinicializadas, uma vez que tiverem um valor atribujdo.
E As vari6veis de refer6ncia f inal- ndo podem referenciar um objeto diferente se j6 tiverem um objeto atribuido a
elas,

E Asvaridveisderefer6nciafinal devemseriniciahzadasantesqueaexecugiodoconstrutorsejaconcluida.
E N6o existem obietos f inal-. Uma refer€ncia a obf eto marcadacomo f inal- n5o significa que o obieto propriamente
dito seja inaltet6vel.
E o modificadot t rans ient s6 pode set aplic ado a vaifiveis de instdncia.
D o modificador vol at i 1e s6 pode ser aplicado avzi|veisde instdncia.

Declarag6es de Arrays (Objetivo 1.3)


D Os arrays podem arm^zerrat tipos primitivos ou objetos, mas o attay propriamente dito 6 sempre um objeto.
O Quando voc€ declara um array, os colchetes podem ficar i esquerda ou i direita do nome davzridvel.
fl Nunca 6 vdlido inclut o tamanho do anay na declaragdo.
D Um zrfay de obietos pode armazenar qualquer objeto que passe no teste E-UM (ou instanceof) para o tipo declarado do
attay.Por exemplo, se Horse estender Admal,entd,o um objeto Horse pode ser colocado em um arav di Animal.

Vari6veis e m6todos static (Objetivo 1.4)


D Nio sio associados a nenhuma instincia especifica da classe.
E Nio6necessiriaaexistdnciadainstinciadeumaclassepataqueosmembrosstatic destasejamusados.
D 56 haveri um a c6pia da vaidvel ou classe s tat i c e todas as instdncias a compartilhario.
E Os m6todos static nio tdm acesso direto a membros nio-static

Enums (Objetivo 1.3)


E Um enum especifica uma lista de valores constantes que podem ser atribuidos a um determinado bpo.
D Um ertum ndo 6 uma String nem um int; o tipo constante de um enum 6 o tipo do pr6prio enum . por exemplo,
INVERNq PRIMAVER T, VERAO e OUTONO sio do tipo enum Estagio.
Q Um enum pode ser declarado fora ou dentro de uma classe, rnas ndoem um m6todo.
E Umenum declarzdoforadeuma classeadopodesermarcadocomstatic, f inal , absLract, pro-
tected ou private.
44 Copitulo I : Decloroc6es e Controle de Acesso

E Os enums podem conter construtores, m6todos, variiveis e corpos de classes constantes.


E As constantes enum podem enviar argumentos para o construtor enum, usando a sintaxe BIG(8), onde o l-iteral int
8 6 passado ao construtor enum.

E Os construtores enum podem ter argumentos e podem ser sobrecarregados.

E Os construtores enum nuncapodem ser chamados diretamente no c6digo.Eles sio sempre chamados
automaticamente quando um enum 6. irttcidtzado.
deum enum 6 opcionar Ambos sio v6ridos:
"
r':f *:j ilt il:i;l:*io
Teste Individual
As seguintes quest6es o ajudardo a ava\ar sua compreensio do material apresentado neste capinrlo. Leia todas as opg6es
cuidadosamente, porque poder6 haver mais de uma respostacorreta. Selecione todas as resPostas corretas para cada quest6o.
Mantenha o foco.

Caso tenha dificuldades com as perguntas no inicio, nio se desespere. Pense positivo. Repita boas afirmag6es para si mesmo
do tipo "Eu sou inteligente o suficiente para entender enum" e "Tudo bem, aquele canaitentende mais de enum do que
eu, mas aposto que ele nio consegue <insira algo em que voc6 defato seia bom) como eu."

l. Dado o seguinte c6digo


f. interface Base {
2. boolean m1 O ;
3. byte m2(short s);
4. )

Qual fragmento de c6digo ir6 compilar? (N4arque todas as corretas')


A. interface Base2 i-mplements Base { }
B. abstract cl-ass Class2 extends ease {
public boolean m1 O { return true,' } }
C. abstract cl-ass Cfass2 implements ease { }
D. abstract class Class2 j-mplements Base {
public boolean mlO { return (true) ; } }
E. cl-ass Class2 implements Base {
boolean mlO {return false; }
byte m2(short s) i return 42; ) )

2. Qual das seguintes opg6es declara uma classe abstract compil6vel? (Marque
todas
as €orretas.)
A. public abstract cl-ass Canine { public Bark speakO; }
B. public abstract cl-ass Canine { public eark speak O t i }
C. public class Canine { public abstract Bark speak ( ) ; }
D. public class Canine abstract { public abstract Bark speak O ; }

esti correta? (Marque todas as corretas.)


3. Qual das seguintes afirmativas
A. "X estende Y" 6 Correto Se, e Somente se, X for uma classe e Y for uma
interface.
B. ..X estende Y" 6 correto se, e somente se, X for uma interface e Y for uma
^t ^a^^
5 45 JAVA
C. "X estende Y" 6. correto se x e Y forem ambos classes ou ambos interfaces.
D. "X estende Y" 6. correto para todas as combinaq6es d.e X e y sendo cl-asses e/
ou interfaces.

4. Quais das seguintes sio declarag6es v6lidas? (Marque todas as corretas.)


A. int gx;
B. int 123;
C. int _1,23;
D. int #dim;
F i nl- *naraanl- .

F. int *divide;
G. int central_sales_region_Summer_200S_gross_sa1es ;

5. Quais nomes de m6todos obedecem ao padreo favaBeans? (Marque


todas as corretas)
A. addSize
B. getcust
C. deleteRep
D. isColorado
E. putDimensions

6. Dado o c6digo:
l-. cl-ass voop {
2. public static voi_d main(String tJ args) {
3. doStuff (1) ;
4, doStuff (7,2) ;
Fl
l

5. / / insira c6digo aqui

Qual destas opg6es, inseridas independentemente na l-inha 6, ir6 compilar? (N{arque todas as correras.)
A. static void doStuff(int... doArgs) { }
B. static void doStuff (int [ ] doArgs) { }
C. static void doStuff(inr doArgs...) { }
D. static void doStuff(int... doArgs, int y) t i
E. static void doStuff(int x, int... doArgs) { }
7. Quais das seguintes opg6es sao declarag6es v6lidas? (Marque todas as corretas.)
A. short x [ ];
B.shorttly;
C. short[5] x2;
D. short z2 [5] ;
E. short t I z I I t l;
F, short t I y2 = [s] ;
46 Copitulo 1 : DecloroE6es e Controle de Acesso

8. Dado o c6digo:
1. enum Animals i
2. DOG("woof"), CAT(*meow"), FISH("burble") ;

3. String sound;
4- Animals(String s) { sound = }
",

6. class TestEnum {
7. static Animals a;
8. public static void main(StringtJ args) {
9. System.out.println(a.DoG.sound + r\ * + a.FISH.sound) ;
r-0. )

11. )

Qual 6 o resultado?
A. woof burble
B. Multiplos erros de compilagio
C. A compilagio falha devido a um erro na linha 2

D. A compilagio falha devido a um erro na linha 3

E. A compilag6o falha devido a um ero naltnha 4

F. A compilagio falha devido a um erro na linha 9

9. Dado o c6digo:
r. enum A t A ]
2. class E2 {
3. enum B t iJ l
4. voidcO {
s. enumo{o}
b. l
7. j
Quais das aEtrmaivas sio verdadeiras? (I\{arque todas as corretas.)
A. O c6digo compila.
B. Se apenas a linha 1 for temovida, o c6digo compila.
C. Se apenas ahnha3 for removida, o c6digo compila.
D. Se apenas a linha 5 for removida, o c6digo compila.
E. Se as linhas 1 e 3 forem removidas, o c6digo compi,la.
F. Se as linhas 1,3 e 5 forem removidas, o c6digo compila.

Respostas do Teste Individual


1. C e D estio coffetas. C esti correta porque uma classe abstract nio precisa implementar nenhum dos m6todos
da sua interface.D esti correta porque o m6todo est6 implementado coretamente.
A est6 incoreta porque as interfaces nio implementam nada. B est6 incorreta porque as classes nio estendem interfaces.
E est6 incorreta porque os m6todos de interfaces sio implicitamente publ ic, entao os m6todos sendo
implementados precisam ser publ i c (Objetivo 1.1)
2. B est6 correta. As classes abstract nio precisam ter nenhum m6todo abstract.
A est6 incorreta porque os m6todos abstract devem ser marcados como tais. C est6 incoreta porque n5o 6
possivel ter um m6todo abstract sem que a classe seja abstract. D est6 incorreta Porque apalzvra-chave
abst.ract deve vir antes do nome da classe. (Obietivo 1.1)
JAVA 5 47
3. C estd correta.

A est6 incorreta porque as classes implementam interfaces, mas nio as estendem. B est6 incorreta porque as interfaces
s6 "herdam de" ouffas interfaces. D est6 incorreta com base nas regras anteriores. (Objetivo 1.2)

4. A, C eG slo identificadores v6lidos.


B est6 incorreta porque um identificador nio pode comegar com um digito. D, E e F estao incorretas porque os
identificadores devem comegar com $ ou uma letra. (Obietivo 1.3)
5. B e D usam os prefixos v6lidosget e is.
A, C e E estao incoffetas potque add, delete e put nio sio nomes de prefixosJavaBeans padr6es. (Obietivo 1.4)
6. Ae E usam sintaxe vat-atgv6Jrdz.
BeCusamsinaxevar-arginv6lida,eD6invilidoporqueovar-argdeveseroultimoargumentodom6todo(Obietivo1.4)
7. A B e E sdo declaragSes de arrays corretas; E 6 um array tridimensional.
C, D e F estao incoffetas, ndo 6 possivel incluir o tamanho do seu array em uma declaragdo a n7'o ser que voc€ tambdm
instancieoobjeto anay.E usaumasintaxedeinstanciamentoinv6lida. (Objetivo 1.3)
8. A estd correta; enums podem ter consffutores e vari6veis.
B, C, D, E e F estio incorretas; todas essas linhas usam sintaxe correta. (Objetivo 1.3)
9. D e F estio corretas. A linha 5 6 a rinica que nio vai compilar, porque os enums nio podem ser locais a um m6todo.

A B, C e E estio incoffetas com base na afirmaglo acima. (Obietivo 1.3)


48 Copitulo I : Decloroc6es e Controle de Acesso
OrientaEio a
objetos

Obierivos pqrq q
certificog6o
I Decloror Interfoces

I Decloror, Iniciolizor e Usor Membros


de Closses

I Usoro Sobrecorgo eo SobrescriE6o


I Desenvolver Consirulores

I Descrever o Encopsulomento, o
Acoplomenlo e o Coes6o

I Usoro Polimorfismo
I Relocionor Modificodores e HeronEo

I Usor Conslrutores de Superclosses e


Conlrutores Sobreco rregodos

I Usor ReloE6et 6-UU e TEM-UM

l/ Exercfcios r6pidos

P&R Teste individuol


50 Copitulo 2: Orientogdo o objetos

Ser um SCJP I .5 signi{ico que voc6 tem de estor completomenie imerso nos ospectos orientodos o obieios de Jovo. Voc6 preciso
sonhor com hierorquios de heronEo, o poder do polimo#ismo lem de fluir otrov6s dos suos veios, o coesoo e o ocoplomento
froco precisom se tornor t6o noturois poro voc6 quonto ondor, e o composiE6o preciso se lornor o seu feiioo com orroz. Esle
copftulo ird prepord-lo poro todos os obietivos e quest6es relocionodos d orientoE6o o obletos que voc6 enconlrord no exome.
Conhecemos muitos progromodores Jovo experientes que, no verdode, n6o s6o muito {luentes no utilizoq6o dos {erromentos de
orientoE6o o obietos fornecidos por Jovo, portonto, comeeoremos pelo inicio.

nl . r. ..1.
\.roleTtvo poro o centttcocoo
Beneficios do encapsulamento (Objetivo 5. I do exame)
5./ Dercnaoluer aldigo que implemente encapsulamento igido, acoplanento Jraco e alta coetdo em classes, e desreaer os benefcios.

Suponhamos que voc6 escrevesse o c6digo de uma classe e virios programadores de sua empresa escrevessem programas
que a usassem. Agora imaginemos que nio tivesse gostado da maneira como a classe se comportou, porque algumas de
suas variiveis de instAncia estavam sendo configuradas (por outros programadores em seus c6digos) com valores que voc6
nlo previu. O c6digo deles resultou em erros no seu c6digo (relaxe, isso 6 apenas uma hip6tese...). Bem, trata-se de um
programaJava, portanto, voc6 deve simplesmente langar uma versSo mais recente da classe, que eles poderio substituir em
seus programas sem alterar nada no c6digo que criaram.

Esse cenario ressalta duas daspromessas/beneficios da OO: flexibilidade e f6cil manutengXo. Mas os beneficios nlo surgem
automaticamente. VocA tem quefaryralgo.Precisa escrever suas classes e c6digos de man eka que di sapore i flexibilidade e
f6cil manutengio. Portanto, e reJava der suporte a OO? Ela nlo projetar6 szu c6digo para voc6. Por exemplo, imagine se
voc6 criasse sua classe com variiveis de instAncia publ ic e os programadores citados acima as configurassem diretamente,
como o c6digo aseguirdemonstra:
public class BadOO i
public int size;
public int weight;

i
public cl-ass ExploitBadoo {
public static void main (String [] args) {
BadOOb=newBadOOO;
b.size = -5; ll velido, mas ruim!!

]
Agora voc6 esti encrencado. Como modificar6 a classe de uma maneira que permita resolver os problemas que surgirem
quando algu6m alterar a vari6vel s i z e para um valor inadequado? Sua rinica opgio 6 voltar ao script, escrever o c6digo de
umm6tododeajusteparasize (umm6todosetsize(int a),porexemplo)e,emseguida,protegeressavari6vel
com, digamos, um modificador de acesso private. Por6m, logo que voc6 fizer essa alt eragdo em seu c6digo, innnonper,l o dos

outros!

A capacidade de fazrr alterag6es no c6digo de implementagio seminterromper o c6digo das outras pessoas que o estiverem
usando, 6 um beneficio essencid do encapsulamento. Voclpode ocultardetalltes da inplenmtapdoportnis de uma interface dc
prugranEioprtblic. Por interface, querernos dizer o conjunto de m6todos que seu c6digo tornar6 disponivel para outros
c6digos chamarem - em outras palavras, a API de sea cridigo. Com a ocultagio dos detalhes da implementaglo, vocA
poder6 trabalhar novamente o c6digo de seu m6todo (podendo tamb6m alterar a maneira como as vari6veis serXo
usadas por sua classe) sem forgar uma alteragio nos c6digos que chamarem o m6todo modificado.

Se voc6 quiser obter f6cil manutengio, flexibilidade e extensibilidade (e 6 claro que voc6 quer), seu projeto deve
incluir o encapsulamento. Como fazer isso?
I Mantenha suas variiveis de instAncia protegidas (com um modificador de acesso, geralmente privat.e).
I Crie m6todos de acesso public, e exija que o c6digo chamador use esses m6todos, emvez de acessar
diretamente a vari|vel de instAncia.

I Para os m6todos, use a conveng1o de nomeagioJavaBeans de seLcsomeProperty> e


get<someProperty>.
JAVA 5 5I
A Figura2-1 ilustra o conceito do encapsulamento, forgando os chamadores do c6digo a usar m6todos em vez de
poderem acessar as variiveis diretamente.
Chamamos os m6todos de acesso de capturadores e confgaradores. embora algumas pessoas prefiram os termos mais
pomposos acusadorcs e modifcadorcs. (Pessoalmente, nio gostamos dapalavra modfiear.) Independente da maneira como
voc6 os chamar, eles serio os m6todos que as outras pessoas terio que usar para icessar suas varilveis de instincia. Slo de
apar6ncia simples, e 6 provivel que voc6 ji os tenha usado:

B b = new BO;
int x = b.getSize0; Qretsize ()

b.setsize(34); setSize ()

St.rinq s = b.getName0; getName ()

b.setName( "Fred') ; setName ()

Color c = b.getcolorO; getcolor ()

b. set.Color (b1ue) ; set.Color ()

A Classe A nio 6 capaz de acessar os dados de vari6veis de


instAncias da Classe B sem ser atrav6s de m6todos
capturadores e configuradores. Os dados sio marcados como
privados; apenas os m6todos acessadores sio p0blicos.

Figuro 2-l A noturezo do encopsulqmenfo

public class Box {


// protege a variS.vel de inst.Ancia; somente uma instAncia
/ / a parEir de Box pode acessar .' d
private int size;
// Fornece capturadores e configuradores priblicos
public int getsizeO {
recurn st-ze;
]
public void setsize(int newSize) {

size = newSize;
)

i
Espereumminuto...quantodoc6digoanterior6ritil?Elenemmesmoexecutaalgumavalidagioouprocessamento!
Que
beneficio pode haver em ter m6todos capturadores e configuradores que neo adicionem uma funcionalidade extra? A
questeo 6 a seguinte, uocd pode mudar de idiia depoit e adicionar mais alguma codificagio a seus m6todos sem
interromper a API. Mesmo se achar que nao precisari realmente de validagio ou processamento dos dados, um
bom projeto de OO Preconiza o planejamento para o futuro. A fim de ficar seguro, exija um cddigo chamador que acere
nus mdtodos em ueqde pennitir o acesso direto is uaridueis de insthnria. Sempre. Assim, poder6 trabalhar de novo as
52 Copitulo 2: Orientog6o o obietos
implementag6es de seus m6todos posteriormente, sem correr o risco de ter que enfrentar a fiiria dos diversos
programadores que sabem onde voc6 mora.

oBSERVAQ6ES pene O EXAME


Cuidado con cridigos que parepm abordar o cumpnftamentl de um mtitodo, ponim, com o pmblena real sendo afalta de encapsulamento.
Examine o exerQ/o a seguiry e uela se clltsegtle detcobir o qae eshi acontecendo:

class Foo {
n,rl-r"l in ihf r6ft - 9.
public int right = 3;
public void setleft(int IeftNum) i
left = leftNum;
right = leftNum/3;
)

// muitos c6digos de teste complexos aqui


)

Agora considere essaperganta: O ua/or da direita serd umpre ilm terp do ua/or da esquerda? Sua reposta senl sim, ati que perceba que os
usudiot da classe Foo ndo precisam usar o mitodo setl,ef t ( ) ! Eles poden simplesnente ir direto ds uaridaeis de instincia e alteri-
/as com qualqur ualor int aleahirio.

Obietivo poro o Certificog6o

Heranga, E-Um, Tem-Um (Obietivo 5.5 do Exame)

5,5 Desenuolaer aidigo qae inplenente relagdes "d-um" ef ou "tem-um".

A heranga esti por toda pane emJava. E seguro dizer que 6 quase (quase?) impossivel escrever at6 mesmo pequenos
programas em java sem usar a heranga. Para explorar esse t6pico, iremos usar o operador instanceof , o qual
discutiremos com muito mais detalhes no Capitulo 4. Por agora, basta lembrar de que instanceof retorna tnre se a
vari6vel de referAncia testada for do tipo ao qual est6 sendo comparada. Este c6digo:

class Test {
public static void main (String [ ] args) {
TesL t1 = new Test ( );
Test t2 = new Test ( );
if ( !tl.equals (t2) )
System.out.println ( "they' re not equal" ) ;
if (t1 instanceof Object)
System.out.println ( "t1's an Object" ) ;
)

Produz esta saida:


they're not equal
t1's an Object
De onde saiu esse m6todo equals? A varilvel de referAncia t1 6 do tipo Test, e nio existe nenhum m6todo
equals na classe Test. Ou existe? O segundo teste if pergunta se E1 6 uma instAncia da classe Object, e pelo
fato de ela ser (falaremos mais sobre isso em breve), o teste i f tem sucesso.
JAVA 5 53

E ptt um minuto... como t1 pode ser uma instAncia do tipo Object, se acabamos de dizer que ela era do tipo
Test? Tenho cerreza de que voc6 esti muito na nossa frente aqui, mas o que ocorre 6 que toda classe em Java 6
uma subclasse de Object, (exceto, 6 claro, a pr6pria classe Object). Em outras palavras, toda classe que voc€ venha
a usar ou a escrever iri herdar da classe Object. Voc6 sempre ter6 um m6todo equals, um m6todo clone,
notify, wait e outros, disponiveis para usar. Sempre que criar uma classe, voc6 automaticamente herdari
todos os m6todos da classe Obiect.
Por qu6? Examinemos esse m6todo equals, por exemplo. Os criadores de Java presumiram corretamente que
seria bastante comum os programadores Java quererem comparar instAncias das iuas classes para verificar se sio
iguais. Se a classe Object nio tivesse um m6todo equals, voc6 teria de escrever o seu pr6prio; voc6 e todos os
outros pr,ogramadoresJava. Esse m6todo equals ji foi herdado bilh6es de vezes. (Para ser exaro, equals foi
sobrescrito bilh6es de vezes, mas falaremos mais sobre isso no devido tempo)

Para o exame, voc6 ter6 de saber que pode criar relag6es de heranga em Java utendendo uma classe. Tamb6m 6
imponante entender que as duas raz6es mais comuns para se usar a heranga sio:
I Para promover a reutilizagilo de c6digos
r Para usar o polimorfismo
Vamos comegar com a reutilizagio.Uma abordagem de projetos comum 6 criar uma verslo um ranto gen6rica de
uma classe, com a intengio de criar subclasses mais especializadas que herdem dela. Por exemplo:
class GameShape {
public void displayShape ( ) {
System. out.println ( "displ_aying shape,, ) ;
]
// maiq c6dia

class PlayerPiece extends cameshape {


public void movepiece ( ) i
System. out.println ('.moving game piece,, ) ,.

/ / ma:-s c6digo
)

public class Testshapes {


public static void main (String[1 args; {
PlayerPiece shape = new playerpiece ( );
shape. displayShape ( ) ;

shape . movePiece ( ) ;

]
)

Tem como saida:

displaying shape
moving game piece

Repare que a classe


-p.layllspiece herda o m6todo display ( ) gen6rico da classe menos especializada
GameShape, e tamb6m adiciona o seu-pr6prio_m6todo, movePiece ( ) . A reutilizagio de c6digo atrav6s da
heranga.significa que.os m6todos com funcionalidade gen6rica (como display ( ) - que podeiia- se aplicar a
)
uma s6rie de tipos diferentes de formas em um jogg nio precisam ser reimplementadoi. Isio significa que todas
_
as subclasses.especializadas.de GameShape garantidamenie terlo as capaciiades da superclass."*"ir gen6rica.
Voc6.n6o vai querer que seja.necessirio reescrever o c6digo display (j em cada .rtn dor seus componenres
especializados de um jogo online, por exemplo.
Mas disso voce ji sabia. Voc€ ji passou pela dor de enconrrar c6digo duplicado ao f.azer uma modificaqeo em um
lugar e ter de rastrear todos os outros pontos em que exista o mesmo c6digo (ou um muito semelhante).
54 Copitulo 2: OrienfoE6o o obietos

O segundo (e relacionado) uso da heranga 6 para permitir que as suas classes sejam acessadas polimorficamente -
uma capacidade fornecida tamb6m pelas interfaces, mas falaremos disso em um instante. Digamos que voc6 tenha
uma classe Gamelauncher que queira fazer tm loop atrav6s de diferentes tipos de objetos GameShape, e
chamar display ( ) em cada um deles. No momento em que est6 escrevendo essa classe, voc6 nio conhece todos
os tipos possiveis de subclasses de GameShape que ainda serlo escritos por outros programadores. E voc6 com
certeza nio quer ter de ref.azer seu c6digo apenas porque algu6m decidiu criar uma forma chamada Dice seis
meses depois.

A beleza do polimorfismo (significa "rnuitas formas") 6 que voc6 pode tratar qualquer subclase de GameShape
como se fosse uma GameShape. Em outras palavras, voc6 pode escrever c6digo na sua classe Gamelauncher
que diga, "nio me importa que tipo de objeto voc6"6, desde que herde de.(estenda) GameShape. E, no que me diz
respeito, se voc6 estender GameShape entio voc6 com toda certeza ter6 um m6todo display ( ) , entio eu sei
que posso cham6-1o."
Imagine que n6s tenhamos agora duas subclasses especializadas que estendam as classes mais gen6ricas
GameShape, PlayerPiece e TilePiece:

cl-ass GameShape {
public void displayShapeO {
System. out.print1n ( "displaying shape" ) ;
)
/ / mai s cridiag vvv4Y

1
J

class PlayerPiece extends GameShape {


public void movePieceO (
System.out.println ( "moving game piece" ) ;

)
// mais crldio6
vvs4Y

)
class TilePiece extends GameShape {
n"l.'l
yulfre in rzniA
vvfs na|-aAi:nanf
Yeu^sJqeslru\/
1\ I
L

System.out.println("getting adjacent tiles" ) ;

// nais c6dioo
\

Agora imagine que uma classe de teste tenha um m6todo com um tipo de argumentodeclarado GameShape; isso
rifrtifi." qn'..Ia pode usar qualquer tipo de GameShape. Em outras palavras, qualquer subclasse de GameShape pode
sei p"s"dr a trnm6todo co- ltrn atg,rmento do tipo GameShape. Este c6digo

public class TestShapes {


public static void main (String[] args) {
PlayerPiece player = new PlayerPieceO;
TilePiece tile = new tilePiece ( ) ;
doghapes (player) ;
doshaDes (tile) t
)
public static void do9hapes(Gan€shaDe shape)
shape . displayShape ( ) ;

i
Gera a saida:
displaying shape
displaying shape
JAVA 5 55
O ponto principal 6 que o m6todo doShapes ( ) 6 declarado com um argumento GameShape, mas pode receber
qualquer subtipo (neste exemplo, uma subclasse) de GameShape. O m6todo pode entio chamar qualquer m6todo de
GameShape, sem nenhuma preocupagXo sobre o real tipo de classe de tempo de execugXo do objeto passado ao m6todo.
Existem implicag6es, no entanro. O m6todo doShapes ( ) sabe apenas que os objetos sio um tipo de GameShape,
uma vez que o parimetro foi declarado assim. E usar uma variivel de referAncia declarada como do tipo GameShape -
independentemsffs r{f se a vari6vel 6 um parAmetro de m6todo, uma variivel local ou uma variivel de instAncia - significa
qu-e apenas os m6todos de GameShape podem ser chamados para ela. Os m6todos que voc6 chama p^t^i^
refer6ncia sio totalmente dependentes do tipo dularado da variivel para a qual a refer6ncia aponta, nio importando
o que seja o objeto. Isso significa que voc6 nio pode usar uma vari6vel GameShape para chamar, digamos, o
m6todo getAdjacent ( ), nem mesmo se o objeto passado for do tipo TilePiece. (Veremos isio
novamente quando falarmos sobre as interfaces.)

Relacionamentos E-UM e TEM-UM


No exame vocA teri que ser capaz de examinar o c6digo e determinar se ele demonstra um relacionamento E-UVI
ou TEM-UM. As regras sio simples, poftanto, essa deve ser uma das poucas 6reas em que, para responder is
perguntas corretamente, euxs€ nlo ser6 preciso raciocinio.

E-um
Na OO, o conceito E-UU 6 baseado na heranga de classes ou implementagio de inrerfaces. O termo E-UM 6r.rma
maneira de dizer, "esse item d un tipo desse outro'.?or exemplo, um Mustang 6 um tipo de cavalo, portanto, na
terminologia da OO poderiamos dlzer, "Musta"g f-UIvt Cavalo". Subaru E-UU Carro. Broccoli f-'l-IM Vegetal
(!io muito atraente, mas mesmo assim conta). O relacionamento E-UM 6 expresso emJava por meio das piavras-
chave extends (para heranga de classes) e implements (para implementagio de interface$:
public class Car {
/ / C6digo de Car aqui
]
public class Subaru extends Car {
/ / Coisas importantes de Subaru aq"ui
/ / Nd,o se esqueqa que Subaru herda membros acessjveis de Car,
/ / o qte pode incluir tanto m6todos quanto vari6vers
]
Ocarro(Car)6umtipodeveiculoffehiclQ,pofianto,aArvoredeveterinicio apartirdaclasseVehiclecomoveremosabaixo:
public class Vehicle { ... }
public class Car extends Vehicle { ... }
public cl-ass Subaru extends Car { ... }
Na terminologia da OO, vod pode dizer o seguinte:
Vehicle 6 a zuperclasse de Car.
Car 6 a subclasse de Vehicle.
Car 6 a superclasse de Subaru.

Subaru 6 a subclasse de Vehicle.

CarherdadeVehicle
Subaruherdade Car
Subaru herda de Vehicle.

Subaru 6 derivado de Car.

Car 6 derivado de Vehicle.

Subaru 6 derivado de Vehicle.


Subaru 6 um subtipo de Car.
Subaru 6 um subtipo de Vehicle.
Voltando ao nosso relacionamento E-uM, as declaraE6es a seguir sio verdadeiras:
56 Copitulo 2: Orientogdo o obietos

"Car (Carro) estende Vehicle (Veiculo)" significa 'Carro E-(JM Veicuk".


"Subaru estende Carro' significa " Sabarv E-(JM Caro".
E tamb6m podemos dizer:
"Subaru E-UU Veiculo" porque a classe seri considerada "um tipo do" item que estiver acima dela em sua irvore
de heranga. Se a expressio (Foo instanceof ear) 6 true, enteo a classe Foo E-UM Bar, mesmo se Foo nio
estender diretamenie Bar, mas, emvez disso, estender alguma outra classe que seja uma subclasse de gar. A
Figura 2-2 ilustra a 6wore de heranga de Vehicle, Car e Subaru. A seta se rnove da subclasse para a superclasse. Em
outras palavras, a seta de urna classe aponta em direglo a classe de onde foi estendida.

Figuro 2-2 Arvore de herongo de Vehicle, Cor e Suboru

TEM-UM
Os relacionamentos TEM-UM sXo baseados na utilizagio , em vez de na heranga. Em outras palavras, classe A
TEM-UM B ocorreri se o aldrgo da classe A apresentar una referdncia a uma in$dncia da classe B. Por exemplo, voc6 pode
dizer o seguinte,
Um Cavalo ftIorse) f-UnA Animal. Um Cavalo TEM-UMA R6dea (Flalter).
E o c6digo teria o formato a seguir:
public class animal { }
public class Horse extends Animal- {
nri rraf e Hel ter mVHalter;
)

No c6digo anterior, Horse tem uma variivel de instAncia do tipo Halter, Poftanto' voc6_pode dizer que
a classe
"Horse ffU-UVt Halter". Em outras palavras, Horse aprercnta uma refeftncia a Halter. O c6digo de Horse.pode usar a
refer6ncia a Halter para chamar m6todlos dessa classe e .tsat seu comportamento sem ter um c6di_go (-og{..9
relacionado a ela ni pr6pria classe Horse. A Figura 2-3 ilustra o relacionamento TEM-IIM entre Horse e Halter.
Os relacionamenros TEM-UM permitirio que vocA projete classes que sigam as boas Priticas da OO sem que
sejam necess6rias classes monoliticas que eiecutem milhares de coisas diferentes. As classes (e, Portanto, os objetos
instanciados a paftir delas) devem ser especialistas. Como diz o nosso amigo.Andrew, 'as classes especializadas
de fato podem r a redvzir bugs". Qiuanto mais especializada. a classe, mais prov6vel que possa ser reutilizada
"jnd, Se voc6 inserir todos o. c6digoJrelacionados a Halter diretamente na classe Horse,
.* o.rt.o, aplicativos.
terminar6 diplicando o c6digo na classe Cow, Unplid.Intern e em qualquer outra classe que Possa precisar do
comportamento de Ftal ter. Mantendo o c6digo de Hal ter em uma classe especializada e separada, voc6 teri a
chance de reutilizila em v6rios aplicativos.

Horce
Halter halt Halter
tie(Rope r) """ tt"(""p" r)

A classe Horse tem um Halter, porque Horse declara


uma variivel de instincia do tipo Halter. Quando o
c6digo chama tie( ) em uma instincia de Horse, o
Horse em quest5o chama tie( ) na varidvel de inst6ncia
Halter do obleto Horse.

Figuro 2-3 Relocionomenfo TEM-UM entre Horse e Holter


JAVA 5 57

Os usu6rios da classe Horse (isto 6, um c6digo que chamar m6todos em uma instAncia de Horse), achardo que
essa classe tem o comportamento de Halter. A classe Horse pode ter um m6todo tie (LeadRope rope) ,
por exemplo. Esses usu6rios nunca saberio que quando chamarem o m6todo tie ( ) , o objeto Horse delegari
essa tarefa para sua classe Halter chamando myHalter . tie ( rope ) . O cen6rio que acabou de ser descrito
ter6 um formato semelhante ao seguinte:
public class Horse extends animal {
private Halter myHalter;
public void tie(LeadRope rope) {
myHalter.tie(rope) ; / / DeIega o comport.amento de tie para
// n nhiafn l{alfar

)
public class Halter {
public void tie(LeadRope aRope) {
/ / Faz o trabalho propriamente dito de tie aqui

Na OO, nio queremos que os chamadores se preocupem com que classe ou objeto ser6 o que realmente executari
a taref.a. Para que se d6 dessa forma, a classe Horse ocultar6 de seus usu6rios detalhes da implementaQio. Os
usu6rios de Horse solicitario a esse objeto que execute tarefas (nesse caso, a si mesmo) .
^marrar para o chamador
Horse o far| ou, como nesse exemplo, solicitarA a outrem parafaz6-lo. No entanto, ".lasse
sempre
pareceri qli;e 0 pniprio objeto Horse feqtado. Os usu6rios de Horse nio precisario nem mesmo saber que ha algo
chamado classe Halter.

Na sala de aula
Projeto orientado a obietos
Os relacionamentos f-Ulrt e TEM-UM sio apenas a ponta do iceberg quando se rrara de projeto orientado a
objetos.. Muito.s livros e.teses de graduaEio t6m sido dedicados a esse t6pico. A, razilo pari a Anfase no projeto
apropnado 6 simples: dinheiro. O custo de distribuigio de um aplicativo tem sido estimado como 10 vezis mais
caro para programas mal projetados. Tendo visto os resultados de projetos fracos, posso assegurar que essa
esrrmauva nio 6 irreal.
At6 os melhores projetistas que usam o modelo orientado a objetos cometem er.os. E dificil visualizar os
relacionamentos entre centenas, ou at6 milhares, de classes. Quando os erros sio descobertos durante a fase de
implementagXo_(criagio do c6digo) de um projeto, a quantidade de c6digo a ser reescrita is vezes pode fazer com
que as equipes de programagio tenham que comegar tudo novamente.
A indristria de software tem evoluido para auxiliar o projetista. As linguagens visuais de modelagem de objetos,
como a Unified Modeling Language (UML), permitem que os projetistas criem e alterem facilrnente classes sem
ter que escrever o c6digo primeiro, porque os componentes orientados a objetos sio representados graficamente.
Isso permite que o projetista crie um mapa com os relacionamentos de classe ajudando-b a reconhecer erros antes
que a codificaglo comece. Outra inovagio recente no projeto orientado a objetos est6 relacionada aos padr6es de
projeto. Os projetistas perceberam que muitos projetoi orientados a objetos sio aplicados de maneiraionsisrente
de um projeto para outro, e que seria ritil aplicar os mesmos projetos porque isso reduziria a possibilidade de
introdugio de novos erros. Assim, os projetistas usu6rios do modelo orieniado a objetos comig"ram a
companilhar esses projetos entre si. Atualmente, hi muitos catilogos desses padr6es de projetos tanto na Internet
quanto em livros.
Embora para passar no_exame de certificaglo em Java voc6 nio precise compreender o projeto orientado a objetos
com esse nivel de detalhes, essas informag6es auxiliares o ajudario a entender melhor porqn. os criadores do teste
optaram por incluir o encapsulamento e os relacionamentos d um e tem a?n no exame.
I Jonathan Meeks, Programador Certificado em Java pela Sun
58 Copftulo 2: OrientoEdo o obietos

Obletivo poro o CertificoE6o

Polimorfismo (Objetivo 5.2 do Exame)


5.2 Dado am cendrio, desenuoluer aldigo qae demonsile o uso dopolimorfsno. Alin disso, deterrtinar quando a conuersdo senl necerdria e

reconhecer quando os erros sdo de nnpikgdo e quando sdo de i


tenpo de exuugdo n0 que re refere conuersdo de referdncias de objxo:.

kmbre-se de que qualquer objetoJava que possa passar em mais de um teste E-UM pode ser considerado polim6rfico.
Fora os objetos do tipo Object, todotos objetosJava sio polim6rficos, no sentido de que eles passam no teste E-IIM feito
em relaSo ao seu proprio tipo e em relagio ) classe Object.

Lembrese de que a rinica maneira de acessar um objeto 6 atrav6s de uma vari6vel de refer6ncia, e h6 algumas coisas
imponantes a memorizar sobre as refer6ncias:
I Uma vari6vel de refer6ncia s6 pode ser de um tipo e, uma vez declarado, esse tipo nunca pode ser modificado (embora o
objeto que referencie posa se modificar).
r Uma referOncia 6 uma variivel, de forma que pode ser reatribuida para outros objetos (a nio ser que a refer6ncia seja
declaradacomo f inal).
r O tipo de uma variivel de refer6ncia determina os m6todos que podem ser chamados no objeto o qual a vari6vel est6
referenciando.

r Uma vari6vel de refer6ncia pode apontar para qualquer objeto do mesmo tipo que a refer6ncia declarada, ou - isto 6
muito importante - pode se referir a qualquer subtipo do tipo declarado!
I Uma variivel de referAncia pode ser declara& como um tipo de classe ou um tipo de interface. Se a vari6vel for declarada
como um tipo de interface,ila pode referenciar qualquer objeto de qualqu er classe que impbmente a interface.
Anteriormente, n6s criamos uma classe GameShape que foi estendida por duas outras classes, PlayerPiece e
Tilepiece. Agora, imagine quevoc6 deseje animar algumas das formas no quadro do jogo. Masnem todasasformas
podem ser animadas, entio, o que voc6 faz com a heranga da classe?
Poderiamos criar uma classe com um m6todo animate ( ) , e fazer somente algumas das subclasses de GameShape
herdar dela? Se pudermos, entlo poderiamos fazer PlayerPiece, por exemplo,estender tanto a classe GameShape
quanro a classe Animatable, enqu-anto que TilePiece estenderia apenas GameShape. Mas nio, isso nio funciona!
Javatem supofte a apenas uma heranga! Isso signi{ica que uma classe s6 pode ter uma superclasse imediata. Em outras
palavras, se PlayerPiece for uma classe, nlo 6 possivel dizer algo como:

class PlayerPiece extends GameShape, Arrimatable t // Niot


// mais c6dica
]
IJma classe nio pode estendermais do que uma classe. Isso significa um parent por classe. lJma classe pode ter mriltiplos
ancestrais,no.itttatrto,,r-avezqueiclasseBpoderiaestenderaclasseA,aclasseCpoderiaestenderaclas_seBeassimpor
diante. Entio, qualquer classe poderia ter mriltiplas classes acima de si na 6rvore de heranga, mas isso nio 6 o mesmo que
dizer que uma classe estende diretamente duas classes.

AOTRABALHO
Algurzas ltngaagens (cono C++) permitem qae ana classe e$enda nais do que uma classe. Essa capacidade d conhecida como "heranga

ntiltipla". A raTdo criadoru de Jaua decidiram ndo permitir a beranga nilltipla d qae ela pode acabar bagungando o c,idigo.
pela qual os
Basicaaente, o prob/ena i qae se uma clasv estender dttas oatras c/astes, e ambat as superc/asses tiuerem, digamoq um mitodo
f f
doStuf ( ) , qaal uersdo de doStuf ( ) a subclasse herdaria? Essa quut1o poderia leaar a un ceniio conhecido como o 'Dianante
da Morte", por causa daforrna do diagmna dt clasm qae pode ser criado en pmjetot com heranga nilltipk. O dianante iformado qaando
tantoaclasseBquantrac/asseCestendemA,etantoBquantoCherdamummitododeA.Seac/asseDestendertantoBquantoC,e
tanto B quanto C tiaerem sobrescito o mitodo de A, a claste D tenl, na teoia, herdado duas imp/erttentagdes dtferentes do mesmo mitodo.
Duenhada cumo ilm dngmma de classes, aforma das qaatro c/ases se parece com um dmmante.

Assim, se isso nio funciona, o que mais voc6 poderiaf.azer?Poderia simplesmente colocar o c6digo de animate ( ) em
GameShape, e depois desabiliiar o m6todo im classes que nio possam ser animadas. Mas essa 6 uma decisio ruim para
um prorero por murras raz6es, incluindo a de que isso o torna mais propenso a erros, torna a classe GameShape menos
coesa (falaremos mais sobre a coesio em instantes), e significa que a API de GameShape "anuncia" que todas as formas
podem ser animadas, mas isso nlo 6 verdadeiro porque apenas algumas das subclasses de GameShape poderio rodar
com sucesso o m6todo animate ( ) .
Entdo o que mais voc6 poderia fazer? VocA j6 sabe a resposta - criar uma interface, Animatable, e fazer com que
apenas ai subclasses di cameshape q.rc possam sei animadas implementem essa interface. Eis o seu c6digo:
JAVA 5 59

public interface Animatable {


public void animate ( ) ;
)

E eis a classe PlayerPiece modificada para implementar a interface:


class PlayerPiece extends Gameshape implements Animatable
publi-c void movePiece ( ) {
System.ouL.println( "moving game piece" ) ;
)
public void animateo {
qlrcf 6m
rJeuerLrr nrrl. nrifif
vqu.y!rarufll l-
\
jfr-F.l*-
/\r--AIlrlL@LfIrV, ,,\;
)
/t /| ^^:^
Lltal> ^aa:-^
Lvufvv

Agora n6s temos uma classe PlayerPiece que passa no teste E-LIM tanto para a classe GaneShape quanto para a
interface Animatable. Isso significa que um PlayerPiece pode ser tratado polimorficamente com uma das quatro
seguintes opg6es a qualquer momento, dependendo do tipo declarado da variivel de refer€ncia:

r Um obj ect (uma vez que qualquer objeto herda de Obj ect)
I Um GameShape (umavez que PlayerPiece estende GameShape)

I Um PlayerPiece (umavez que 6 isso que realmente 6)


I Um Animatabl e (uma vez que Pl ayerP i ece implementa Animat.abl e)
As seguintes sio todas declarag6es legais. Observe com cuidado:
PlayerPiece player = new PlayerPiece ( ) ;
uDJecE.
^Li ^^+ o prayer;
^ -= *1 --.,

Gameshape shape - player;


Animatable mover - player;
56existeumobjetoaqui-umainstAnciadotipoPlayerPiece -mashiquatrotiposdiferentesdevari6veisde
referdncia, todasreferindo,se a um objeto na *&n6.i". teste rapido: quais das variiveis'de refer6ncia acima podem chamar o
m6todo displ-ay ( ) ? Dica: apenas duas das quatro declarag6es podem serusadas para chamar o m6todo display ( ) .
Lembre-se de que as chamadas a m6todos permitidas pelo compilador sio baseadas unicamente no tipo declarado da
referAncia, independentemente do tipo do obj eto.Eitlo,observando os quatro tipos de refer6ncias novamente - obj ect,
GameShape, PlayerPiece e Animatable - quais desses quatro tipos conhecem o m6todo display ( ) ?
VocA adivinhou - e PlayerPiece, como 6 de conhecimento do compilador, t6m um m6todo
as classes GameShape
display (), tipos de refer6ncias pode ser usado para chamar display ( ) . Lembre-se de que,
entio qualquer um desses
para o compilador, um PlayerPiece E-UM GameShape, enteo o compilador diz'estou vendo que o tipo
declarado6 elayereiece e,umavezque PlayerPiece e$endeGameshape,issosignificaque etayerpiece
herdou o m6todo display ( ) . Ponanto, PlayerPiece pode ser usado para chamar o m6todo display ( ) ."

Quais m6todos podem ser chamados quando o objeto PlayerPiece e$6 sendo referido por meio de uma refer6ncia
declarada como do tipo animatable? Apenas o m6todo animate O . E claro que o interessante aqui 6 que qualquer
classe, de qualquer irvore de heranga, pode tamb6m implementar Animatatle; enteo isso significa qn., s.voc6
-
tiver um m6todo com um argumento declarado como do tipo Animatable, poder6 passar objetos
PlayerPiece, objetos spinninglogo e qualquer coisa que seja uma instAncia dl uma classe que
implemente Animatabl-e. E voc6 pode usar esse parAmetro (do tipo Animatable) para chamar o m6todo
animate ( ) ,.mtr nio o m6todo display ( ) (que pode nem existir) ou qualquer outro que nio seja conhecido
pelo compilador com base no tipo da refer6ncia. O compilador sempre sabe, nb entanto, que voc6 pode chamar os
m6todos da classe obj ect em^qualquer objeto, entXo 6 seguro chami-los independentemente da iefer6ncia -
classe ou interface - usada para apontar para o objeto

Deixamos de fora uma grande pane deste assunto: o fato de !lue, mesmo que o compilador s6 conhega o tipo de
refer6ncia declarado, a JVN[, em tempo de execugio, sabe o que o objeto iealmente 6. E isso significa que, mesmo
que o m6todo displJy ( ) de PlayerPiece seja chamadb usando-se uma variivel de referTncia Gimeshape,
a JVM chamari a verslo do m6todo display ( ) presente em PlayerPiece, caso PlayerPiece sobrescreva
esse m6todo! A Jyry o!se_rv1 o objeto real do outro lado da refer6ncia, "v6' que ele sobrescreveu o m6todo do tipo
da vari|vel de refer|ncia declarada, e chama o m6todo da classe verdadeira do objeto. Mas uma coisa a se ter eni
mente:
As chamadas de m6todos polim6rficos se aplicam somente a nitodos de in$6ncias. VocA sempre pode se referir a um
objeto com um tipo de va?iivel de refer6ncia mais geral (uma superclasse ou interface), -"r, .- tempo de
60 Copitulo 2: Orientogdo o obietos

execuglo, ONTCAS coisas que sio selecionadas dinamicamente com base no pr6prio objeto (em vez de no tipo
da referincia)"ssio os m6todos de instincias. Nio m6todos uttiticos. Nio uaridueis. Apenai m6todos de instAncias
sobrescritas slo chamados dinamicamente com base no tipo real do objeto.
IJma vez que essa definigio depende de um entendimento claro da sobrescrigio, e da distingio entre m6todos
estiticos e m6todos de instincias, falaremos sobre eles em seguida.

Obletivo poro o CertificoE6o

Sobrescrevendo/ Sobrecarregando (Obietivos 1.5 e 5.4 do


Exame)
/.5 Dado um exemplo de cddigo, detenninar se um mitodo estd sobrescreuendo ou sobrecarregando coretamente outro mitodo, e identifcar
ualoru de retorto udlidos (inclaindo retlrnlr couaiantes) para o mitodo ent questio.

5.4 Dado am cendio, desenuoluer cddigo qae declare ef ou chame mdtodos sobrescritos ou sobrecarregados, e devnuoluer cddigo que declare ef ou
chame conshatores de superc/asses, cznstfl.rtzre! sobrescritos oa sobrecatregados.

M6todos Sobrescritos
Sempre que vocd tiver uma classe que herde o m6todo de uma superclasse, poderi sobrescrever esse m6todo (a
menos que, como aprendeu anteriormente, ele tenha sido marcado com f inal). O beneficio chave da
sobrescrigio 6 o recurso de definir um comportamento que seja especifico de determinado tipo de subclasse. O
exemplo a seguir demonstra a subclasse Horse penencente i classe Animal sobrescrevendo a versio do m6todo
eat( )dessaclasse.
public cl-ass animal {
public void eat ( ) t
System. out.println ( "Generic animal Eating Generically" ) ;
)

]
class Horse extends Animal {
public void eat ( ) {
q\/qj-
rf Fm nrrf nrintln
ousrL'.vuL.P!
(.'Horse
\ frvrrE gqLrrlY i-^
eaf 1-'r.'
rrsJ r veev, c
^^f =-4 hOrSe tfeats");
errv

]
)

Para os m6todos abstract que voc6 herdar de uma superclasse, nio hi escolha. E preciso implementar o
m6todo na subclasse a menos que ela tambdm seja abstract. Os m6todos abstract devem ser inplementados ,
pela subclasse concreta, -as isio virtualmente 6 o mesmo que dizer que a subclasse concreta sobrescreae os m6todos
abst.ract da superclasse. Portanto, voc6 deve considerar os ndtodos abstract
como aqueles ot quair ser,iforpado a
sobrescreuer.

O criador da classe Animal pode ter decidido que para fins de polimorfismo, todos os subtipos de Animal
precisario de um m6todo eit ( ) definido de maneira .rp..ifi." e.exclusiva. Coq o polimorfismo, quando
algu6m tiver uma referAncia a Animal que aponte nio para uma instAncia de Animal, mas para a instAncia de uma
su-bclasse de Animal, o chamador deveria chamar eat ( ) na referAncia a Animal, mas o objeto real do tempo de
execuglo (digamos, uma instAncia de Horse) executari seu pr6prio m6todo eat ( ) especifico. Marcar o
m6todo eaJ( ) como abstract 6 a maneira de o programador de Animal informar a todos os
desenvolvedores de subclasses: "Nio tem sentido s.n novo subtipo usar um m6todo eat( ) gen6rico, portanto, voc6
teri que criar sua pr6pria implementagio do m6todo eat ( ) !". lJm exemplo (nlo-abstract) do uso do
polimorfismo 6 apresentado abaixo:
pubJ-j-c cl-ass TestAnimals {
public static void main (String [] args) t
Animal a = new Animal0;
Animal b = new lrorEe () t / / Refer6ncia Animal, rnas 6 tut objeto Horse
a.eat\\; // Executa a versdo Animaf de eato
b.eat (\; / / Executa a versSo Horse de eato
JAVA 5 6I

]
class animal {
public void eat ( ) t
System.out.println( "Generic Animal Eating Generically" ) ;

)
class Horse extends Animal {
public void eato {
System.out.println("Horse eating hay, oats, and horse treats"),'
i
public void buck0 { }
)

No c6digo anterior, a classe de teste usa uma refer6ncia a Animal para chamar o m6todo em um objeto Horse.
Lembre-se de que o compilador s6 permitir6 que os m6todos da classe Animal sejam chamados quando a
referAncia a um objeto Animal for usada. O c6digo a seguir nio seria vilido dado o c6digo anterior:
Animalc=newHorse0;
c.buck(l; / / rmpossivel chamar buckO;
| / A cl'aes'e Aninral nio possui asse m6todo
O compilador s6 verificari o tipo da referdncia e nio o da instdncia. O polimorfismo permitir6 que voc6 use a
refer6ncia a um supeftipo mais abstrato (incluindo uma interface) para acessar um de seus subtipos (inclusive
os implementadores da interface).
O m6todo novo ndopodertl ter um modficador de acesso mais restritiuo do que o m6todo que foi sobrescrito (por exemplo,
voc6 nio pode sobrescrever um m6todo marcado com public f.azendo com que ele se torne protected).
Pense bem: se a classe Animal apresentar um m6todo eat ( ) public e algu6m tiver uma referAncia a Animal
(em outras palavras, uma referencia declarada com o tipo Animal), essa pessoa presumiri ser seguro chamar
eat ( ) na refer€ncia a Animal independente da instAncia real para a qual a refer6ncia estiver apontando. Se
fosse permitido que uma subclasse se infiltrasse e alterasse o modificador de acesso no m6todo novo, enteo,
repentinamente no tempo de execuglo - quando a JVM chamar a verseo real do m6todo no objeto ftIorse) em vez
da versio do tipo da referincia (Animal) - o programa seria interrompido (sem mencionar o stress emocional sofrido
por quem foi traido pela subclasse embusteira). Alteremos o exemplo de polimorfismo que vimos anteriormente:
public class TestAnimals {
public static void main (String [] args) {
Animal a = newAnimalo;
Animal b = new Horse() i / | Refer6ncia Animal, nag 5 urn objeto Horse
a.eat); // Executa a versao Animal de eato
b.eatO; // Executa a versdo Horse de eato
]
]
cl-ass Animal {
public void eat ( ) {
System.out.println( "Generic Animal Eat.ing Generically" );
]
]
class Horse extends Animal {
priwate void eat ( ) {
System.out.printl-n( "Horse eating hay, oats,
+"and horse treats");
)

Se esse c6digo pudesse ser compilado (o que nio acontecer6) o descrito a seguir falharia no tempo de execugio:
62 Copitulo 2: Orientogdo o obietos

Animal b = new Horseo; // Referlncia Animal, mas 6 um objeto Horse,


/ / aL6 aqui. tudo bem
// Falha no tsnpo de execug3,ol

A vari6vel b 6 do tipo enimal, que possui um m6todo eat ( ) public. Contudo, lembre-se de que no tempo de
execugio,alinguagemJavausaachanadaaumnitodovirtaalparaselecionardinamicamenteaverseo realdom6todoqueser6
executado, com base na instAnciareal.IJmarefer6ncia aAnimal sempre poderiapontatparauma instincia de Horse, porque
Horse E-UM Animal. O que torna possivel a essa superclasse refererr.i", r.r*" iortAncia da subcl asse 6 a certery dc qui)
subcksse pode faqgr tuda que a superclasn pode
faqer. Se a insdncia de Horse sobrescrever os m6todos herdados de Animal
ou simplesmente herd6los, qualquer pessoa com uma refer6ncia de Animal ) instAncia de Horse poder6 chamar
todos os m6todos disponiveis em Animal. Por essa razio, o m6todo novo deve seguir o contraro da superclasse.

As regras para a sobrescrita de um m6todo sio as seguintes:

I A llsta de argumentot deae coincidir exatamente com a do m6todo sobrescrito. Se nXo coincidirem, voc6 poder6 acabar
com um m6todo sobrecarregado que nio queria usar.

I O tipo dz retomo deae ser o mesmo, ou um subtipo, do tipo de retorno declarado no m6todo sobrescrito original da
superclasse (Falaremos mais sobre isso daqui a algumas piginas, quando discutirmos os retornos covariantes).

I O nfuel de acesso n6o deue ser nais rutritiuo que o do m6todo sobrescrito.

I O niuel de acesso pode ser menos restitiao que o do m6todo sobrescrito.

I Os m6todos de instAncias somente podem ser sobrescritos se forem herdados pela subclasse. lJma subclasse
dentro. do mesmo pacote que a superclasse da instincia 6 capaz de sobrescrever qualquer m6todo de
superclasse que nio seja marcado com private ou f inal. Uma subclasse de um pacote diferente somente
pode sobrescrever os m6todos nio-f inal marcados com public ou protecteA (uma vez que os
m6todos protect.ed sio herdados pela subclasse).

I O m6todo sobrescritor PODE langar qualquer excegio (de tempo de execugio) nio-verificada,
independentemente de o m6todo sobrescrito declarar ou nio a excegio. (Mais sobre isso no Capitulo 5.)
I O m6todo novo ndo deae langar excegdes ueifcadas flnuas 0a mais abrangentes que as declaradas pelo m6todo sobrescrito.
Por exemplo, um m6todo que declare uma excegio FileNotFoundException nio poder6 ser sobrescrito
Por um m6todo que declare uma excegio SQlException, Except.ion ou qualquer outra excegio que nio
seja de tempo de execugio, a menos que ela seja uma subclasse de FileNotFoundException.

I O ndtodo noao podeni langar excegdes nais restritiuas oil nefilr abrangentes. 56 por que o m6todo sobrescrito "se arriscou',
nio quer dizer que a excegio da nova subclasse deva contemplar os mesmos riscos. Conclusio: O m6todo
novo nio precisa declarar nenhuma excegio que nunca langar6, independente do que o m6todo sobrescrito
tenha declarado.
I Voc6 n6o pode sobresmuer um mdtodo marcado com f :-na]-.
I Voc6 nio pode sobrescrever um m6todo marcado com static. Veremos um exemplo daqui a algumas
p6ginas, quando discutirmos os m6todos static com mais detalhes.

I Se u, mdtoda ndo puder rcr lterdado, uocd ndo poderi sobrewaiJo. Lembre-se de que a sobrescrigio implica que voc6 esti
reimplementando um m6todo herdado! Por exemplo, o c6digo a seguir nio 6 vllido, e mesmo se voc6 adicionasse um
m6todo eat ( ) a Horse, ele nio seria uma sobrescriqXo do m6todo eat ( ) de Animal:
public class TestAnimals {
public static void main (String [] args) i
Horse h = new Horse0;
h.eat l); / / Nio 6 w61ido, Dorque Horse nio herdou eat()
)

]
^1 -^^
L!d>D n-l--r
rurltrdf t

private void eat ( ) t


System. out.println ( "Generic Animal Eating Generically" ) ;
)

)
class Horse extends aninal { }
JAVA 5 63
chamando a versio da superclasse de um m6todo sobrescrito
Geralmente, voc6 iri se. beneficiar de algum c6digo da versio da superclasse para um m6todo, ainda assim,
sobrescrevendo-o para fornecer um comport"-.ito especifico adicional. Seri como dize., li"ecrrte a versio
da
superclasse o m6todo e' em seguida, volte aqui e tirmine com o c6digo adicional d. mirrh" subclasse para
p-a.ra.
-
1y 3€t$g"lf !:"* ressaltar qry
:,.t?o
6 preciso que a versio da superclassZ t.1"
suDclasse)' t tacrl tazer lsso no codrgo usando a palavra-chave super, como vemos a
.".."r.J"";;;;i;;dt;;'d"
seguir:
public class Animal {
public void ear O { }
ntthlin rznid nrint-Vnrrrcalf
rvstpsr! \/\ / t/

/ / C6digo ritil de exibiqdo aqui

]
class Horse ext.ends Animal {
nrrl-r'lic rrnid
wvfu nr.infv^rrra6lf
yrfrrurvq!osr! /\
\/
/I

/ Aproweita-se do c6digo de Animal, depoj-s adici-ona mais c6dioo


/
super.printYourself O,. // Chama a supercfasse
/ / c6digo (Animal)
/,/ Depois volta e realiza
// outros serviqos de exibiqio
// especificos de Horse aqui

Observagio: IJsar super para chamar um m6todo sobrescrito somenre se aplica a m6todos de instAncias. (Lembre-
se de que m6todos static nio podem ser sobrescritos.)

oBSERVAq6ES pane o EXAME


Se am mitodofor sobreterito, mar anr
ama refeftnciapolinilfica (do sapet'po)para apontarpara o objeto do subtipo com o m1todo
aocd
sobretcritor, o conpiladar arunini que
cbamando a uersdo do ndnio do srpen;po.-Se o aeoAo do supet;po dul)rar uma exnpdo
uocd eshi
uerifcada, mas o mdtoda do subn'po ndo of7.er, o conpilador ainda assim pensani qie uoc6 uni chamando
,nao qae declara ama"excegdo ni
(mais sobre isso no Capit*lo 5). V/anos un exemplo:

class Animal i
public void eat ( ) throws Exception {

/ / Ianea uma Exceqd.o

class Dog2 ext.ends Animal {


public void eatO { //sem Exceq6es }
public static void main(String [] args) t
Animala=newDog2O;
Dog2 d = new Dog2O;
d.eatO;// ok
a.eatO; ll erro de coogilagao -
I / Exceg6,o n6o relatada
)

i
Este aldigo ndo coapilanl deuido exce\zo dularada no mdtodo eat ( ) de Aninal. Isso ocom mesmo qtle, em tempo de exuugdo, 0 mit4do
)
eaL ( asado sela a uertdo de Dog a qual ndo dulara a excegdo.
64 Copitulo 2: OrientoE6o o obietos

Exemplos de sobrescritas de m6todo v6lidas e nao-vilidas


Examinemos a sobrescrita do m6todo eat ( ) de Animal:
public class Animal {
public void eat O { }
)

A Tabela 2-1 lista exemplos de sobrescrig6es nio-viLlidas Odo m6todo eat ( ) de Animal, dada a verslo anterior da
classe Animal.

Tobelo 2-1 Exemplos de sobrescriE6es ndo-vd/idos

C6digo de subscrigio invSlido Problema no c6digo

privatevoideat( ){l O modificador de acesso 6 mais restritivo

Declara uma excegio verificada nio declarada


public void eat ( ) throws lOException { }
pela versio da superclasse

IJrru sobrecarga vilida, e nio uma subscrigiq


public void eat ( string food) { }
poque a lista de a{gumentos foi aherada

Nio 6 uma subscriglo por causa do tipo de


publicStringeat( ){ } retorno, mas tamb6m nio 6 uma sobrecatga
porque nio h6 afteragio na lista de argumentos

M6todos sobrecarregados
VocA deve estar pergtrntando o que os m6todos sobrecarregados estio fazendo em um capido sobre OO, mas os
se
incluimos p.lt fa:to de uma das coisas com as quais os deienvolvedoresJava novatos mais se confundem serem
"q.ri
justamente as sutis diferengas entre m6todos sobrecamgados e sobrescitos.
Os m6todos sobrecarregados permitirio que voc6 reutilize o mesmo nome de m6todo em uma classe, mas com
;g";;; dif.rentes (e Spciori"l*..rr., .or.r um tipo de retorno diferente). A sobrecarga de um m6todo geralmente
,ifnifi." q.r..,o.6.rt"ri r"ndo um pouco mais condescendente com as Pessoas que chamarem seus m6todos, po^rque razr
..iaig" *]"*r ,^^tirf.^d{idar coirrtipos de argumentos diferentes eri vezdeiorgar o rhamadorafaznr convers6es antes de
chamar seu m6todo. As regras sio simples:

I Os m6todos sobrecarregados deuem alterar a lista de argumentos.


I Os m6todos sobrecarre gados poden alterar o tipo de retorno.
I Os m6todos sobrecarreg adospodem alterar o modificador de acesso.
I Os m6todos sobrecarregado pothm declarar exceg6es verificadas novas ou mais abrangentes.
s

t Um mttodo podeser sobrecarregado na mesma classe ou em uma subclasse. Em outras palavras, se a classe A
definirum m6todo doStuf f (int i), a subclasse B poderia definirum m6todo doStuf f (String s)
sem sobrescrever a versio da superclasse que usa um int. Assim, dois m6todos com o mesmo nome, mas em
diferentes classes, ainda podem'r.r corrsid.rados como sobrecarregados, caso a subclasse herde uma versio do
m6todo e depois decl^ri outr^versio sobrecarregada na sua definigio de classe.

Sobrecargas vilidas
Examinemos um m6todo que queremos sobrecarregar:
nrrhlic
Puvfrv
rrnid
vvrs chanaesizc(inf
vlrgrrYe size. String name, float pattern) { }.
Os m6todo a seguir sio sobrecargas u,itidas do m6todo changeSize ( ) :

public void changeSize(int size, String name) { }


n,,1.r1 .in ini
frrL urrqrtverr!= qize f I^al- naftern) I I
trruurI9 ^h:ndaqizotini- \rlru
public void changeSize(float pattern, String name)

throws rOException { }
JAVA 5 65
oBsERvAe6ns pene o ExAME
Tome caidado 41ando tiuer qae reconbecer se um mitodo d nbrecarregado em ueTde sobrucrito. Voc€ pode aer am mdtodo
qae parega uio/ar
uma regra da nbrucrigdo, mar qae na uerdade senl uma sobrecarga u,i/ida, como ueruos a seguir:

public class Foo {


nrrhl
vuvrrL i c rrni
vvru rl rlnqtrrf
u---e f / i nr rr
r, ctsri
evL-ng S) { }
public void moreThings(int x) { }
]
class Bar extends Foo {
nrrl.r'lin rznid r{nQl-rrff!! f\ frfu
inr y, float s) throws rOException { }
i
VocdpodefcartentadoaconsideraralOExcepLioncomooproblema,a0uerqueomdtodosobrevritodoStuff()ndodeclarou
um1 excegdo e ao saber que a excegdofoi uerifcadapelo compilador. Mas o mitodo doStuf f ( ) ndofoi defotma alguma substcrito! A
-
subclasse Bar o sobrepds, altemando a lista de argumentlr, portanto a excepdo lOExcept.i on i adequada.

Chamando m6todos sobrecarregados


Repare.que ha muito mais a ser dito sobre como o compilador sabe qual m6todo chamar, mas o restante ser6
abordado no^Capjtu1o.3, quando virmos o boxing e os var-args - ambos t6m impacto significativo sobre a
sobrecarga. (Voc6 ainda assim ter6 de prestar atengio na pafte apresentada aqui, no enianto.)

Quando.um m6todo for chamado, pode existir mais de um m6todo com o mesmo nome para o ripo de objeto em
que voc6 o estiver chamando. Por exemplo, a classe Horse pode ter-tres m6todos com o ;esmo nbme, por6-,
com listas de argumentos diferentes, o que significa que o m6todo foi sobrecarregado.
A decisio sobre qual dos m6todos coincidentes chamar ser6 baseada nos argumenros. Se voc6 chamar o m6todo
com um argumento String, a versAo sobrecarregada que usar uma String ser6 chamada. Se chamar um m6todo com
o mesmo nome' mas Passar Para ele um tipo f 1oat, a versio sobrecarregada que usar um tipo f loat ser6
executada. Se chamar um m6todo com o mesmo nome, mas passar para el=e um-objeto roo e nio houver uma
versio.sobrecarregada que use esse objeto, enteo, o compi]xdel aviJar6 que nio est6 conseguindo encontrar uma
coincid6ncia. A seguir temos exemplos de chamadas a m6todos sobrecarregados:
class Adder {
public int addThem(int x, int y) {
return x + v;
)

// Sobrecarrega o m6todo addThem para adi-cionar doubles em vez de ints


public double addThem(double x, double y) {
return x + y;
)

/ A partir de outra classe, chama o m6todo


/ addThemo
public c1ass TestAdder {
public stat.ic void main (String [] args) {
Adder a = new Adder0;

int c = 3;
int result. = a.addThem(b,c) ; ll euaL addTtren 6 chanado?
double doubleResult = a.addThem(22.5,89.36) ; // euaL addlltrern?

]
No c6digo TestAdder anterior, a primeira chamada a a. ad.dThem (b, c) passa dois tipos int para o
m6todo, portanto, a primeira versio de addThem ( ) - a versio sobrecarregada que usa doii argumen^tos de tipo
int -ser6chamada.Asegundachamadafeitaaa.addThem (22.5, 89.361 passadoistiposdouble-
para o m6todo,.portanto, a segunda verseo de addThem ( ) - a versio sobrecarregadl que usa dois argumentos
double - ser6 chamada.
66 Copitulo 2: Orientoqdo o obietos
Chamar m6todos sobrecarregados que usem refer6ncias a objetos_ em vez de tipos primitivos 6 um pouco mais
inr.r.rr"rri.. Oig"r"ot qrr. v&e tive'sse um m6todo sobre.a.i.g"do em qu9 -uma versio usasse um objeto Animal e
a outra;"b,;?;H;rr'. 1r"b"i"rt. Je Animal). Se voc6 p"tt"t"o- objeto Horse na chamada do m6todo, chamarh
a versio sobrecarregada que usa esse objeto. Ou pelo menos 6 o que Parece i primeira vista:

class animal { }
class Horse extends animal { }
class UseAnimals {
public void doStuff(Animal a) t
s\/qt-Fm orri- nrint-ln("Tn the Animal version");
uJ e uer( .

]
public void doStuff (Horse h) {
svsl-cm orrf nri nf l n ( "Tn fhe Horse version"
vJrevlrr! vse.y!4^re+ ) ;

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

UseAnimals ua = new UseAnimals ( ) ;


Animal animalObj = new animal ( ) ;

Horse horseobj = new HorseO;


ua.doStuff (animalObj ) ;
ua.doStuff (horseObj ) ;
)
)

A saida seri a que voc6 espera:

in the Ani-mal version


in the Horse version
Mas, e se voce usar uma referOncia de Animal a um objeto Horse?
Aninal aninalRefToHorse = new Horse();
ua. doStuf f ( animalRefToHorse ) ;

Qual das vers6es sobrecarregadas seri chamada? Voc€ pode estar querendo responder: "A ,9ge usa qm objeto
liorr., jL que 6 esse objeto que est6 sendo passado parJo m6todo no tempo de execugio". Mas nio 6 assim que
funciona. O c6digo anterior na verdade exibiria:
in the Animal version
Ainda que o objeto real no tempo de execugXo seja Sli*ll, a opgio por qual
um objeto llgrse e."q" m6todo
sobrecamgado chamar (em outras palavras, a assinatura do m6todo) nio 6 decidida dinamicamente no tempo de
execugi6. Apenas lembre-se de q.te o tipo da referdncia (e ndo o tipo d9 objeto) d(emiry 4!al ndto(o sobrecamgado.unl chamado!
Resumindo,^o m6todo sobresnito a chamar (em outras palavris, de qual classe da 6rvore de heranga)- 6 decidido.no
tempo de exuipao com base no tipo do objeto, mas qual versio sobreearegado do m6todo chamar 6 baseado no tipo da
referdnciapassado no rempo de tonp;kgi. Se voc6 chamar um m€todo passando a ele uma referdncia Animal a um
oblrto Horr., o compilador s6 saberi do Animal, portanto, ele escolhe a. verslo sobrecarregada do m6todo que
,rr" rr* Animal. Nio impona, em tempo de execugio, que na verdade seja um Horse sendo passado.

Polimorfismo em m6todos sobrecarregado e sobrescrito


Como o polimorfismo funciona com m6todos sobrecarregados? Pelo que acabamos de examinar,.nio parece que o
polimorfiimo seimponecom o fato de o m6todosersobrecarregado. Sevodpassarumarefer6nciaaAnimal, o m6todo
iobrecarregado q*^usatrrmobjao Animalser6chamado, mesmo que o objetorealmentepassadotenhasido Horse. Mesmo
queHorse"sejapassado parao m6todo como Animal, ele continuarisendouqobjao Hgrse apesarde o m6todo estar
apera"d" enit"d. Portanto, 6 verdade que o polimorfsmo nio dgtermina qual versio sobrecarregada seri chamada o
polimorfismo enrra em agdo qrr*do a decisio a tomar aborda qual veisio sobrescrita de um m6todo ser6 chamada.
'Por6-, )s vezes u- m6todo 6 sobr.."rregado e sobrescrita. Suponhamos que as classes Animal e Horse fossem
iguais is descritas abaixo:
public class animal {
public void eat ( ) {
System.out.println ( "Generic Animal Eating Generically" ),'
JAVA 5 67
)
public class Horse extends Animal {
public void eat0 {
System. out.println ( ..Horse eating hay .. ) ;
)

yslf
.ia rrniA
nrrh'l re vvfq a:|- tqt-rind c\ II
cqu \uL!frrY o/

System.out.println(..Horse eating \ + s);


)

Observe que a classe Horse tanto sobrep6s quanto sobrescreveu o m6todo eat ) . A Tabela 2-2 mostra que (
versao dos tr6s m6todos (
eat ) ser6 executada dependendo de como forem chamadas.

Iobelo 2-2 Chomodos o rn6fodos e sobrescrifos


C6digo de chamada de m6todo Resultado

Animala=newAnimal( ); a.eat( ); Generic Animal Eating Generically

Horseh=newHorse( ); h.eat( ) Horse eating hay

Hone eating hay O polimorfismo funciona - o tipo do objeto real fttrone), e


Animal ah = new Horse ( ) ; ah. eat ( ) nio o tipo da refedncia (Aninral), 6 usado para determinar que m6todo eat( )
he . eat ( "App1es " ) ; ser6 chamado.

Horse he = new Horse ( )


Hone eating Apples O m6todo eat(String s) sobrecarregado 6 chamado.

Animal a2 = newAnimal ( ) Erro do compilador! O compilador percebeu qtre a classe Animal nio possui
a2,eaX ("treats"); um m6todo eat( ) que use uma String.

Erro do compilador! O compilador conrinuou examinando somenre o tipo da


Animal ah2 = new Horse ( ) ; refer6nciae viu que Animal nio tem um m6todo ea( )qtre use uma srring. O
ah2 . eat ( " carrots " ) ; compilador nlo se preocupou com o fato de quetalvez o objeto real no tempo
de e:<ecugio seja um objeto Hone.

oBSERVAQ6ES pene O EXAME


Ndo se deixe enganar prr uril mitodo que s/a sobruamgado, e ndo robretcrito pnr uma subclatse. E perfeitanente udlido fa7,er o seg,tinte:

public class Foo {


void doStuff0 { }
]
class Bar extends Foo {
void doStuff (String s) { }

)
A elasseBar tem dois mdtodot doStuf f ( ): a uersdo sem argamentls qae herdou deFoo (e ndo sobresmuel e a nbrecamgada
doStuf f (String s) defnida na classe Bar. O aidigo con uma refer€ncia ao objeto Foo pode chamar somente a aersdo sem
argilnentLr' mN 0 que ten a refer€ncia a am objeto Bar pode chamar qua/.quer uma das uersdes sobrecamgadas.

A Tabela 2-3 resume a diferenga entre m6todos sobrecarregados e sobrescritos.

Iobelo 2-3 Diferengo enlre m6fodos sobrecoregodos e sobrescrifos.

M€todo sobrecarregado M6todo sobrescrito

lista de argumentos Deve ser alterada Nio deve ser alterada


tipo de retorno Pode ser alterado Nio deve ser alterado

Exceg6es Podem ser alteradas Podem ser reduzidas ou eliminadas.


68 Copftulo 2: Orientog6o o obietos
Nio devem ser langadas exceg6es
verificadas novas ou mais abrangentes

Acesso Pode ser aherado Nio deve se tornar mais restritivo (pode
ser menos restritivo)

O tipo do objeto (em otttras palavras, o


Chamadas O tipo da refer6ncia determina
qtre verslo sobrecarregada ti1o da inrfincia real na memtiia)
(baseada nostipos de ser6 selecionado. Isso ocorrer6 a todo
argumentos deilarados) seri instante.
sel-ecionada. O m6todo real a ser
chamado ain&ter6uma
chama&virnral no tempo de
excecu$o, a coincidAncia de
argumentos ji teri sido definida,
s6 faltando a classe real onde o
m6todo reside.

Sobrescrito Sobrecarregado

Tree Tree

showleaves () setFeatures (String name)

Oak Oak

showleaves () setFeatures (String name, int leafSize)


setFeaLures (int leafSize)

Figuro 2-4 Metodos sobrescrifos e sobrecorregodos em relocionomenfos de closses

O objetivo atual (5.4) aborda tanro a.sobre carga de m6todos quanto de construtores, por6m, a iltima ser6 abordada
na proxlma segao, na qual tamb6m discutirernos os outros t6picos-relacionados a construtores que aParecerio no
."".n.. A figuia 5-4 ilustra a maneira como m6todos sobrecarregados e sobrescritos sio tratados em
relacionamentos de classes.

Obietivo poro o Certificogdo

Conversio de Variiveis de Refer6ncia (Objetivo 5.2 do Exame)


5.2 Dado un centirio, d.esenuoluer aidigo que demonstre o uto do polimorfsno. Al6n disso, deterwinar quando a conuersdo senl necessdna e

saber dferenciar enor de conrpilagdo de erms de tempo de execapdo relacionados i conuersio de refer4ndas a objetos.

de objetos
J6 vimos que 6 possivel e comum usar tipos gen6ricos de variiveis de ref_9r6ncia pa?:.ap2+tar.para,tipos
mais especifi.oi. kto forma a base do poli*orfir-o. Por exemplo, esta linha de c6digo lhe deveri Parecer natural
a esta altura:
Animaf animal = new DogO;
Mas o que acontece quando voc6 deseja usar a variivel de refer€ncia do animal a fim de chamar um m6todo que -
apenas a classe oog possui? VocA sabe que esti se referindo a um Dog, e deseja fazer algo que 6 especifico.a Dog?
No c6digo seguinti, f.*or rr* array deanimals e, sempre que. acharmos um Dog no array, queremo^s fazer
algo espe"cific6 d. pog. Vamos coniordar por agora que todo o c6digo est6 correto, exceto pelo fato de nio
estarmos ceftos sobre a linha que chama o m6todo playDead.
class Animal {
void makeNoise ( ) {System.out.println( "generic noise") ; }

)
class Dogr extends Animal {
JAVA 5 69
void makeNoiseO {System.out.println(..bark,,) ; }
void playDead ( ) i System. out.println ( ', roll over,, ) ; )
]
class CastTest2 {
public static void main(String IJ args; {
Anima] tl a = inew Animal O , new DoSO , new Animal O );
for(Animal animal : a) {
animal.makeNoise ( ) ;
if (animal instanceof Dogr) {
animal .playDead(li // lentou realizar um coq)orta.m€nto de D,og?

Quando tentarmos compilar esse c6digo, o compilador dir6 algo como:


cannot. find slzmbol
O compilador est6 dizendo: 'Ei, a classe Animal nio tem um m6todo playDead () ". Vamos modificar o bloco
de c6digo if:
if (animal instanceof Dos) {
oog d. = (Dog) anirnal; // conwertendo a variSvel de refer6ncia
d.playDeadO;
]
O novo e melhorado bloco de c6digo cont6m uma conversio, que neste caso 6 is vezes chamada de conuersdo
redutora,porque estamos convertendo para baixo na Lrvore de heranga, de uma classe mais geral para uma mais
especifica. Agora, o compilador frcarS, feliz. Antes de tentarmos chamar playDead, n6s convertemos a variivel
do animal para o tipo Dog. O que estamos dizendo ao compilador 6 "sabemos que ela na verdade se refere a um
objeto Dog, entio nio tem problema em criar uma nova vaiiivel de refer6ncia Dog pata apontar para esse objeto".
Neste caso, nos safamos porque, antes de sequer tentarmos a conversio, fazemos um testtinstJnceof para
termos certeza.
E i-pon"ttt. saber que o compilador ser6 forgado a confrar em n6s quando fazemos uma conversio redutora,
mesmo quando fazemos besteira:
class Animal i )
class Dog extends Animal { }
al aac T\aaToct I

public static void main(Stri-ng [] args) t


Animal animal = new Animal ( ) ;
Dog d = (Dog) animal; // corpila, nas falha depois

Isso pode ser enlouquecedor! O c6digo compila! Mas quando tentamos executAlo, recebemos uma excegeo parecida
com esta:
j ava. 1ang. ClassCastException
Por que nio podemos confiar que o compilador vai nos a.judar aqui? Ser6 que ele nio consegue ver que animal 6
do tipo Animaf ? Tudo o que o compilador pode fazer 6. verificar se os dois tipos esrio na mesma iwore de
heranga, de forma que, dependendo se houve ou nio algum c6digo antes da conversio, 6 possivel que animal
seja do tipo Dog. O compilador precisa permitir coisas que possivelmente vio funcionar no mominro da
execugio. Entretanto, se o compilador souber com certeza que a conversi.o nio poder6 funcionar de jeito nenhum,
-
a compilagio faihar6',. O seguinte bloco de c6digo substiruto NAO compilari:

Animal animal = new Animal ( ) ;

Dogd= (Dogr) animal;


9tring s = (String) aninal; // animal NTNCA poderia E6r urra String
70 Copitulo 2: Orientoglo o obietos

Nesse caso, voc6 receberi um erro parecido com este:


inconvertible tlpes
Ao contr6rio da conversio redutora, a conversio generalizadora (convefter para cima na irvore. de heranga, de um
tipo mais especifico para um mais geral) funciona-implicitamente (ou seja, voc6 nio precisa incluir n_o seg c{digo)
porque q.rando faz ima conversio ge neralizadora, votA esti implicitamente restringindo o nimero de m6todos
que ilode chamar, ao contririo da conversio redutora, o que implica que, mais tarde, voc6 poder6 desejar chamar
um m6todo mais espec{fco. Por exemplo:
^t ^^^
Ll45> n-i*-1
rurrrllal r )
I J

class Dog extends Animal { }

class DogTest {
nrrlr]in c{-:fia void main(St.ring [] args) {
Dog d = new Dogo;
Anina1 a1 = d; / / converslo generalizadora ok sem nenhunr converEio e:rglicita
Ani.mal a2 s (Animal) dt ll cornwergio generalizadora ok co umr conversio otrllicit,a
)

Ambas as convers6es acima irio compilar e rodar sem exceg6es, porque um Dog n-UVt Animal, o que significa
que qualquer coisa que um Animal possa fazer, um Dog tamb6m poder6. Um Dog pode f.azer mais, 6 claro, mas-a
questao 6: qualquer um que tenha uma referAncia a Animal pode chamar, com seguranga, os m6todos de Animal
em uma instincia de Dog. Os m6rodos de Animal podem ter sido sobrescritos na classe Dog, mas tudo que nos
importa agora 6 que um Dog sempre pode tazer, no m(nimo, tudo o que um Animal puder. O compilador e a JVM
tamb6m sabem disso, entlo a conversio generalizadora implicita 6 sempre v6lida para atribuir um objeto de um
subtipo a uma referencia de uma das classes (ou interfaces) do seu supertipo. Se Dog implementar Pet, e Pet
definir beFriend.ly ( ) , entio um Dog pode se converter implicitament. .tn n.tiPrt, mas o 6nico m6todo de
Dog que voc6 poder6 chamar enteo ser6 beFriendly ( ) , que Dog foi forgado a implementar porque Dog
implementa a interface Pet.
Mais uma coisa... Se Dog implementa Pet, entXo se Beagle estender Dog, mas Beagle nio fuclarar que esti
implementando Pet, Beagle ainda ser6 um Pet! Beagle 6 um Pet simplesmente porque estende Dog, e Dog jlt
cuidou dos seus pr6prios comportamentos Pet, e os de todos os seus descendentes. A classe Beagle sempre pode
sobrescrever quaisquer m6todos que herdar de Dog, incluindo m6todos que Dog implementou para satisfazer o
contrato da sua interface.
E s6 mais uma outra coisa... se Beagle de fato declarar que est6 implementando Pet, apenas para que as pessoas
gue olharem a API. da classe Beagle possam ver facilmente que Beagle E-IIM Pet, sem ter de olhar nas superclasses
de Beagle; Beagle ainda assim nlo precisarl implementar o m6todo beFriendly ( ) caso a classe Dog (a
superclasse de Beagle) jS,tenha cuidado disso. Em outras palavras, se Beagle E-UM Dog, e Dog E-UM Pet, entio
Beagle E-IIM Pet, e ji atendeu is suas obrigag6es de Pet de implementar o m6todo beFrien-dly ( ) , uma vez que
ele [erda esse m6todo. O compilador 6 espirio o suficiente pira dizer, "Eu j6 sei que Beagle 6 UM Pet, mas nio
tem problema em tornar isso mais 6bvio".
Assim, nio se deixe enganar por um c6digo que mostre uma classe concreta que declare estar implementando
uma interface, mas que nio implemente os mitodos da interface. Antes de poder dizer se o c6digo 6 vilido ou nio,
vocA precisa saber o que as superclasses dessa classe concreta declararam. Se qualquer classe da sua irvore de
heranla jitiver forneiido implementag6es concretas (ou seja, nio-abstract) doi m6todos, e tiver declarado que
ela (a superclasse) est6 implementando a interface, enteo a subclasse nXo tem obrigagio nenhuma de
reimplementar (sobrescrever) esses m6todos.

oBSERVAQoES pene O EXAME


Os niadorcs do exame irdo lhe diryr que foran forgadot a eo/ocar toneladas de aldigos em pequeills espapos 'por causa do sistema do exane".
Embora isso t/a potencialmente uerdadeiro, eles TAMBEM gwtam de ser obvums. O aidigo ngainte:

Animala=newDogO;
Dogd= (Dog) a;
: rlnnnacrrrff
s.uvsvvvesr! /\
\ / ,

Pode rcr substituido por e$e, nuito nais jlcil de ler:

Ani-ma1 a = new DogO;


( (Dog) a) .doDogStuff () ;
Neste caso, o conpiladorprecisa de todos esses par€nteses, caso contniio pentari que eshi recebendo ama infuwgdo innmpleta.
JAVA 5 71

etivo poro o CertificoEdo

lmplementando uma Interface (Objetivo 1.2 do exame)


1.2 Desenuolaer cddigo qae declare uma interface...

Quando voc€ implementar uma interface, estari concordando em aderir ao conrraro definido nela. Isso significa
que estari concordando em fornecer implementas6es v6lidas de cada m6todo definido na inrerface e que
{ualquer
pessoa que.souber como sio os m6todos da interface (nio a maneira como sio implementados, *"r .&.to
irod6m
ser chamados e o que retornam) poderi cham6-los na instAncia de uma classe sua que a implementar.

Por exemplo, se voc6 criar uma-classe que implemente aintertace Runnable (de modo que seu c6digo possa ser
executado por um thread especifico), ter6 que fornecer o m6todo public void run ( I . Oo conlririo, o
coitado do thread_ poderia ser informado para executar o c6digo de seu objeto Runnable e - surpresa - iria
descobrirqueo objetoniopossui o m6todo run( ) !(Momentoemque, othreadseriainterrompidoeaJVM
encerrado em uma finalizagi"o espetacular, por6m, horrivel). Felizmenle, a linguagem Java impedlr6 que isse dano
ocorra pela execugio de uma verificagio do compilador em cada classe que tentaiimplementar uma interface. Se
a classe informar que esti implementando uma interface, 6 melhor que tinha uma implementagio de cada m6todo
da interface (com algumas exceg6es que examinaremos em breve).
Assumindo-se que temos uma interface Bounceable, com dois m6todos: bounce ( ) e setBouneeFactor () , a
seguinte classe ir6 compilar:

public class Ball inplenents Bounceable { // palavra-chave.imp]ements'


public void bounce O { }
public void setBounceFactor(int. bf) t ]
)

Cefto, sabemos o que voc6 esti pensando: "Essa deve ser a pior classe da hist6ria das classes de implementagio". No
entanto, ela ser6 compilada. E executada. O contrato di interface garante que uma classe tenha o m6todo (em
outras palavras, classes diferentes poderio chamar o m6todo, sujeito a conirole de acesso), mas nunca garantirS,
uma implementagio adequada - ou mesmo algum c6digo de implementaEio real no corpo do m6todo-O
compilador nunca lhe dir6, "Desculpe, mas voc6 nlo quer mesmo inserir nada entre essas chaves? ATENQAO: ji
que se trata de um m6todo, ele nio deveria executar algo?".
As classes de implementagio devem estar sujeitas as mesmas regras de implementagio do m6todo como uma
classe estendendo uma classe abstract. Para ser uma classe de implemintagio v6lida, uma classe de
implementagio nio abstract deve fazer o seguinte:
I Fornecer implementag6es concretas (nio abstract) de todos os m6todos da interface declarada.
r Seguir todas as regras de sobrecarga vilidas.
I Nio declarar exceg6es existentes em m6todos de implementagio que nio sejam as declaradas pelo m6todo da
interface, ou subclasses que nio sejam as declaradas por esse m6todo.
I Manter a assinatura e o mesmo tipo de retorno do m6todo da interface (por6m, nXo sendo preciso declarar as
exceg6es existentes na declaragio do m6todo da interface).

Mas.espere_, hi mais! Uma_classe de implementagio pode ser ela pr6pria abstract! Por exemplo, o c6digo a
seguir 6 v6lido para uma classe Ball que implemente a interface Bounceable:
abstract class Ball implements Bounceable { }
Notou algo faltando? Nio fornecemos os m6todos de implementagio. E isso esti certo. Se a classe de
implementagio for abstract, ela pode simplesmente passar atarefa para sua primeira subclasse concreta. Por
exemplo, se a classe BeachBall estender Ball e nio for abstract, entXo, reri que fornecer todos os m6todos de
Bounceable:
class eeachBall extends Ball {
/ / F;rnbora nao o digamos na declaragd.o de classe acima,
// BeachBall implement.a Bounceable, uma vez que a superclasse abstract de
/ / BeachBall (8a11) implementa Bounceable

public void bounceO t


/ / a6di an hnrrnna acnaaif
vePevflfvv i an rla Ra:nhpr1 rr I amri
uqur

]
72 Copftvlo 2: OrientoEdo o objetos
public void setBounceFactor(int bf) {
/ / c6digo bounce especifico de BeachBall aqui para definir um fator de bounce

/ / se a classe Ball Liver definido quaisquer m6todos abstract, eles terao de


/ / ser implementados aqui tamb6m.
)

Procure m6todos que informem implementar uma interface, mas nXo fornegam-as implementag6es de m6todo
correras. A menos'que a classe de implementagio seja abstract, elaterS, que fornecer implementag6es de
todos os m6todos definidos na interface.
VocA precisa conhecer mais duas.regras para que.possamos, entio, encerrar esse t6pico (ouIaz voc6 dormir
sempre, pois nunca nos confundimos com uma dessas op96es):
1.. Uma classe pode implementar mais de uma interface.
vilido informar, por exemplo, o. seguinte:
E perfeitamente
public class Ball implements Bounceable, Serializable, Runnable { ... }

VocA pode esrender somente uma classe, mas implementar muitas. Por6m, lembre-se de que a criaglo de sub-
classei define quem e o que 6 a classe, enquanto I implementagio define uma fungio que ela.poderi desempenhar
ou algo que poderi usar, apesar do quanto possa ser diferente de outra classe que estiver implementando a mesma
interface (por6m, apartir de uma 6wore de heranga diferente). Por exemplo, uma pessoa estenderia HumanBeing
(embora isso possa ser discutivel para alguns). Mas tamb6m poderia implementar programmer, snowboarder,
employee, parent ou personcrazyenoughtotakethisexam.
2. A pr6pria inter{ace pode estende r outra interf.ace, mas nunca implementar algo.
O c6digo abaixo 6 perfeitamente v6lido:
public interface Bounceable errtends rdoveable { }
O que isso significa? A primeira classe concreta (nio abstract) de implementagio de Bouceable deve
implementar todos os m6todos dessa interface, al6m de todos os m6todos de Moveable! A subinterface, como a
chimamos, simplesmente adicionari mais requisitos ao contrato da superinterface. VocA veri esse conceito
aplicado em muitas 6reas da linguagem Java, principalmente no J2EE, onde geralmente temos que construir
nossas pr6prias interfaces para estender uma das suas.

No entanto, agoarde, porque 6 agora que comega a ficar estranho. Uma interface pode estender mais de uma
interface! Pense bem por um momento. Voc6 sabe que quando se trata de classes, o que vemos abilxo nio 6 vlilido:
frublic cLass PrograrEner extends Eqrloyee, Geek { , || I,rrvlLj-Aol
Como mencionamos anteriormente, uma classe nio pode estender virias outras em Java. No entanto, uma
interface pode estender virias interfaces.
inlerf,ace BounceabLe extends Dloveable, spherical {
void bounce O ;
void setBounceFactor(int bf ) ;
)
interface Moveable {
void moveft O ;
)
interface Spherical {
void doSphericalThing( ) ;

Ball 6 necess6ria na implementagio de Bounceable, al6m de todos os m6todos das interfaces que Bounceable
estende (incluindo qualquer interface que essas interfaces estendam, e assim por diante, at6 que vocb alcance o
inicio da pilha - ou seria o fim da pilha?). Portanto, Ball teria que ter o seguinte formato:
class Ball implemenLs Bounceable {

public void bounceO { } // rmplementa os m6todos de Bounceable


public void setBounceFactor(int bf) { }
JAVA 5 73

publ-ic void movelt O { } // Implementa os m6todos de Moveable

public void doSphericalThingO { } // Implementa os m6todos de Spherical


]
Se a classe Ball n5o conseguir implementar nenhum dos m6todos de Bounceable, Moveable ou Spherical, o
compilador se move{6_para cima e para baixo incontrolavelmente, um pouco envergonhado, at6^que ela o faga.
Isto 6, a menos que Ball.seja marcada.como. abstract. Nesse caso, ela poderia opiar por implementar qualquer
um, todos ou nenhum dos m6todos de qualquer das interfaces, deixandoassim o restante das implem.ttt"g6.ip"r"
uma subclasse concreta de Ball, como descriio abaixo:
abstract class Ball implements Bounceable {
public void bounce0 | ... j / / Define o comportamento de bounce
public void setBounceFactor(int bf ) { ... }
// N6,o implemente o resto,. deixe para Lrma subclasse
)
class SoccerBal-l- extends Ball {
// a classe SoccerBal-l precisa i-mplementar os m6todos da interface gue Ball nao
implemenLou
public void moveTt ( ) { ... }
public void doSphericalThingO { ... }
/ / SoccerBall pode decidir sobrescrever os m6todos de Bounceable
// implementados por Ball
public void bounce ( ) { ... }
I

interface Bounceable
void bounce( ); abstract Ball implements Bounceabl-e
void setBounceFacEor(int bf) ;

/*ndo serSo implementados


em Ball quaisquer m6todos
de Bounceable */
^
I
void beSpherical( ){}

class Tire implements Bounceable class BeachBall exEends Ball


public woid bounce( ) { ) public void bounce( ){ }
public void setBounceFactor (int bf) { } public woid setBounceFactor (int bf) { )

/*beSpherical n5o 6 abstract entao


BeachBall ndo 6 solicitado para
implementar isso */

Devido oo foto de BeochBoll ser o primeiro closse concreio poro implemenlor Bounceoble, elo deve
fornecer implementog6es poro todos os m6todos de Bounceoble, excelo oqueles de{inidos no closse
obstroct Boll. Como boll n6o forneceu implementoE6es dos m6todos Bounceoble, BeochBoll foi referido
poro implemenlor lodos.

A Figuro 2-5 comporo o uso vdlido e o n6o volido de exlens6es e implementoq6es, tonto poro
closses quonlo poro inferfoces.

oBSERVAQ6ES pene O EXAME


Procure utiliqagdes ndo udlidas de exten$u e inplenentapdes. As linhas a seguir mostram exemplos de dulamgdu udlidas e ndo udlidat de
intet'aces e clastes:

class foo { } // oK
ala<< R:r imnlamanfc E'^^ f J // Ndo! Ndo 6 trtossiveL impTementar uma cLasse
74 Copftvlo 2: OrientoE6o o objetos

interface eaz { } // oK
interface Fi { i // oK
interface Fee implements Baz { } // Ndo! A interface ndo Pode
/ / impTementar uma interface
interface Zee implement.s Foo { } // Ndo! A interface ndo Pode
fasse
/ / im9sTementar uma c

int.erface Zoo extends Foo { } // Ndo! A interface ndo pode estender


/,/uma cf asse
interface Boo extends Fi { } // OK. A interface pode estender uma
// interface
class Toon extends Foo, Button { } // Ndo! A c-lasse ndo pode estender
/ /miTtiplas cl.asses
cl-ass Zoom implements Fi, Fee { } // OK. A cTasse pode implementar miTtipTas
/ /interfaces
interface Vroom extends fi, Fee { } // OK. A interface pode estender
/ /n67tip7as interf aces

MemoiTe isto e pmcare abusos cometidos petgilntar qae estiuerem n0 exame. IndEendente do que as perguntas parEam aualiar, o
nas
pmbhna real pode Antes de cair na arwadilha, digaruos, de acompanbar o fluxo de am thread
ser a declaragdo da classe ou interface.
mmplexo, ueifqae sepelo nenos o cddigo ser,l compilado. (Srlporessa dica,jd meruemls ettarem seu testamento!) (I'zoc6fcari
impressionado com o empenho dos elaboradtres do exame en desuid-lo do pmblena real). (Cono as pessnar cznsegt'/iam redigir alg antes dos
pa ftfl teret nre m i n ue n tadot ?).

Obietivo poro o Certificoc6o

Tipos de retorno v6lidos (Objetivo 1.5 do exame)


|.5 Dado am exemplo de nidigo, deterninar se *m ndtodo estd sobrescreuendo ou sobreean'egando comtamente oahv mitodo, e identifcar
ualoret de retorno adlidos (inc/aindo retomot couariantet) para o mdtodo,
Este objetivo abordari dois aspectos dos tipos de retorno: o que voc6 pode declararcomo um tipo de retorno e o que
pode realment e returnar como um valor. O que pode ou nio ser declarado 6 muito simples, mas tudo depender6 de
voc6 estar sobrescrevendo um m6todo herdado ou simplesmente declarando um novo m6todo (o que inclui os
m6todos sobrecarregados). Examinaremos rapidamente a diferenga entre as regras dos tipos de retorno para
m6todos sobrecarregados e sobrescritos, porque j6 abordamos isso neste capitulo. Entraremos um pouco em uma
6rea nova, no entanto, quando examinarmos os tipos de retorno polim6rficos e as regras para o que 6 ou nio
v 6lido re torn ar realmente.

Declarag6es de tipos de retorno


Esta seglo examinar6 o que voc6 pode declarar como um tipo de retorno, o que depender6 principalmente de
sobrescrever, sobrecarregar ou declarar um novo m6todo.

Tipos de retorno de m6todos sobrecarregados


Lembre-se de que a sobrecarga de m6todos nXo significa muito mais do que a reutilizagdo de nomes. O m6todo
sobrecarregado 6 completamente diferente de qualquer outro m6todo com o mesmo nome. Portanto, se um
m6todo for herdado, mas sobrecarregado em uma classe, voc6 nio estar6 sujeito is restrig6es da sobrescrigio, o que
significa que poderi declarar o tipo de retorno que quiser. O que voc6 niopodef.azer 6 alterar o tipo de retorno.
Para sobrecarregar um m6todo, lembre-se de que uoc€ precisa alterar a lista de atgamentos. O c6digo a seguir mostra um
m6todo sobrecarregado:
publj-c class Foo{
void go0 { }
)
public class Bar extends Foo {

String go(int x) {
return nu11;
JAVA 5 75
O_bserve que a versio da classe Bar para o m6todo usa um tipo de retorno diferente. Isso 6 perfeitamente
adequado' Contanto que voc6 tenhi alterado a lista de argumentos, esrari sobrecarregando'o m6todo, porranto, o
tipo de retorno nio precisar6 coincidir com o da versio da superclasse. O que voc6 n?o pode fazer 6 isto:
public class Foo{
void go0 { }
]
public class Bar ext,ends Foo {
String go0 { // Inv6lidol Ndo 6 possivel modificar apenas o tipo de rerorno
return null;

A Sobrescrigio e os Tipos de Retorno; e Retornos Covariantes


9y4o uma.subclasse quiser alterar a implementagio de um m6todo herdado (uma sobrescrigio), ter6 que
definir um m6todo qrre coincida exatanente com a verslo herdada. Ou, a partir do Java 5, voc6 tem a possi-bilidade
de modificar otipo de retorno no m6todo sobrescritor, desde que o novo tipo de i.totno seja um subiipo do tipo
de retorno declarado do m6todo sobrescrito (da superclasse).
Vejamos um retorno covariante em agXo:
public class Foo{
void so0 { }
)
public class Bar extends Foo {
String goO { // sobrescrlgdo v6.1i-da em ,Java 1.5
return nu11;
)
]
Com oJava 5, esse c6digo compilari sern problemas. Se voc6 tentasse compil6Jo usando um compilador 1.4 ou
com o flag source, desta forma:
javac -source 1.4 Beta.java
receberia um erro de compilagio parecido com este:
attempting t.o use incompatible return type
(Falaremos mais sobre os flags do compilador no Capitulo 10.)

Outras regras slo aplicadas i sobrecarga, inclusive as dos modificadores de acesso e exceg6es declaradas, mas elas
nio sio relevantes para a discussio sobre o tipo de retorno.

No exame, voc6 ter6 que saber que os m6todos sobrecarregzdos podem ter o tipo de retorno alterado, mas os m6todos
que estiverem sobrerreuendo outros sri poden fa$-/o dentro dot linitu dos retnftilr couariantes. 56 por ter conhecimento disso
voce conseguiri responder v6rias perguntas do exame.

Retornando um Yalor
VocA ter6 que lembrar de apenas seis regras para o retorno de um valor:
1. Voc6 pode retornar null em um m6todo que tenha como tipo de retorno a referAncia a um objeto.
public Button doStuff ( ) {
return nu11;
)
2. O array 6 um tipo de retorno perfeitamente v6lido.
public String tl goo {
return new St.ring[] {"Fred", "Barney", "Wi1ma"};

3. Em um m6todo com tipo de retorno primitivo, voc6 pode retornar qualquer valor ou variivel que possa ser
76 Copitulo 2: Orientoq6o o obletos

implicitamente conveftido para o tipo de retorno declarado.


public int foo ( ) {
char c = 'c';
return c; / / char 6 compativel com int
)

4. Em um m6todo com tipo de rerorno primitivo, voc6 pode retornar qualquer valor ou vari|vel que Possa ser
explicitamente convertido parao tipo de retomo declarado.
public int foo ( ) {
float f = 32.5f;
return (i-nt) f;
]
5. Y oc€ ndo deve retornar nada de um m6todo com tipo de retorno void.
public void bar ( ) {
return "this is it"; /,/ rnv6lido! !
]
6. Em um m6todo que tenha como tipo de retorno a refer6ncia a um objeto, voce pode retornar qualquer tipo de
objeto que possa ser implicitamente convenido paraotipo de retorno declarado.
public Animal- getAnimal ( ) {
return new Horse (\ ; / / Assuma que Horse estenda Animal
)

public Object. getObjectO {

int[] nums = {I,2,3};


reLurn nums; // Retorna um array int, que ainda 6 um objeto
]

public interface chewable { }

public class Gum implements Chewable { }

public class TestChewable {

/ / M6Lodo com um tipo de retorno da interface


Chewable getChewable {

return new Gum(); // Retorna o implementador da interface


]
)

oBSERVAQ6ES pRne O EXAME


Procure mdtodos qae dtclarem cono tipo de retomo una clasn abs trac t ou anta interface, e rzemoriry que qaa/quer objeto qae passar
no teste E-UM (erz outras pa/awar, qu/e tiaer como ruultadn lrae no teste com o operador ins t.anceo f ) podeni rcr retomado desse

mdtodo - por exemplo:


public abstract class Animal { }
public class Bear extends animal { }
public class Test {
public Animal go ( ) {
return new Bear (\ ; / / OK, Bear $a!-um/' Animal

]
]
Esse aldigo ini compilar, o ualor de retorno i um subtipo.
JAVA 5 77

Obietivo poro o certifico€6o

Construtores e instanciagio (Objetivos 1.6 e 5.4 do exame)


1.6 Dado um conjanto de claset e saperc/asses, desenuo/uer constmtzrer para uma oa mais das c/asses. Dada uma dukragdo de c/asse,
deterwinar se serri criado am clnrtutzrpadrdo e, em caso afrrtatiuo, determinar o comportamento dcsse construtor. Dada uma listagem dt
c/asse aninhada ou ndo, escreuer aidigo para instanciar a c/asse.

5.4 Dado um nndrio, desenuo/ueraidigo que declare efou chame nitodos sobrescritos ou sobrecanegados, e cddigo qae dec/are efou cbane
cznJtratlres de superc/assu, con$rutoret sobrescritot ou sobrecanegados.

Os objetos sio construidos. Voc| ndo pode criar am nouo o[eto sem chamar am clnstratzn Na verdade, nio pode criar um
novo objeto sem chamar nio s6 o constnrtor do tipo de classe real do objeto, como tamb6m o construtor de cada ana de
suas superclassetlConstrutores sio o c6digo que serl executado sgTple. q.Ye voc6 usar a palavra-chave new. OK, para
sermos um pouco mais precisos, pode haver tamb6m blocos de inicializagio que executem quando voc6 usar new,
mas iremos abordiJos (os blocos de inicializagio), e as suas contrapartes estiticas, no pr6ximo capitulo. Temos
muito que discutir aqui - examinaremos como os construtores sXo codificados, qaem os codifica e como funcionam
no tempo de execugXo. Portanto, pegue seu capacete e um martelo e executemos a construgio de alguns objetos.

Apectos bisicos do construtor


Toda classe, incluindo as classet abstract, precisa ter um constnrtor. Memorize isso. Mas s6 porque uma classe
precisa ter um constnrtor, nio significa qlre a prugramadorterthaque digit6-lo. lJm construtor tem o formato a
segurr:

class Foo {
roo0 ( | ll o constrirtor para a claEse foo
)

Notou o que est6 faltando? I'{do htl tipo de retomolLembre-se de que um construtor nio possui tipo de retorno, e seu
nome deve coincidir exatamente com o nome da classe. Normalmente, os construtores sio usados para inicializar
o estado de variiveis de instAncia. como descrito abaixo:
class Foo {
int size;
Qlri nd nama.

Fan
r vv I\ve!+rrY
efri nn nam6 i nf ci za\ {

this.name = name;
this.size = size;

No c6digo do exemplo anterior, a classe Foo n5o possui um construtor sem argumentos. Isso significa que o
c6digo a seguir ndo seri compilado,
Foo f = new Foo O ; / / Ndo vai compilar, nao h5 um construtor correspondente
mas a linha a seguir ser6 compilada,
Foo f = new Foo("Fred", 43); // problemas. os argumentos correspondem ao
Sem

//construtor de Foo.
Portanto, 6 muito comum (e desejivel) que uma classe tenha um construtor sem argumentos, independente de
quantos outros construtores sobrecarregados existam nela (sim, os construtores podem ser sobrecarregados). Voc6
nno conseguiri fazer com que isso funcione sempre em suas classes; ocasionalmenrc terh uma classe em que nio
far6 sentido criar uma instAncia sem fornecer informag6es para o constnrtor. IJm objeto j ava. awt.Color, por
exemplo, nio pode ser criado com uma chamada a um construtor sem argumentos, porque isso seria o mesmo que
dizer iJVM: "Crie um novo objeto Color para mim e nio vou me preocupar com a cor real que ele ter6,...Vocd
escolhe". Voc6 realmente quer que a JVM tome as decis6es est6dcas no seu lugar?

Cadeia de construtores
Sabemos que os construtores serXo chamados no tempo de execugio quando voc6 digitar new em algum tipo de
classe como vemos abaixo:

Horseh=newHorseo;
78 Copitulo 2: OrientoEdo o obietos

Mas o que ocorreri realmente quando voc6 digitar new Horse ( ) ? (Assuma que Horse estende Animal e que
Animal estende Object.)
1. O construtor de Horse ser6 chamado. Todo constnrtor chama o construtor da sua superclasse com uma
chamada (implicita) a super ( ) , a nlo ser que o construtor chame um construtor sobrecarregado da
mesma classe (falaremos mais sobre isso em instantes).
2. O construtor de Animal seri chamado (Animal 6 a superclasse de Horse).

3. O construtor de Object ser| chamado (Object 6 a superclasse final de todas as classes, portanto, a classe
Animal estenderi Object ainda que voc6 nio digite realmente "extends Object" em sua declaraEio. Estari
implicito). Nesse ponto estaremos no inicio da pilha.
4. As vari6veis de instAncia de Object receberio seus valores explicitos. Por explicitos, queremos dizer os
valores que slo atribuidos no momento em que as varilveis sio declaradas, como "int x = 27", onde
"27" 6 o valor explicito (e nio um vaTor padrio) davariSvel de instAncia.
5. A execuEio do construtor de Object ser6 concluida.
6. As variiveis de instAncia de Animal receberio seus valores explicitos (se houver).
7. A execuglo do construtor de Animal ser6 concluida.
8. As vari6veis de instAncia de Horse receberio seus valores explicitos (se houver).
9. A execugio do construtor de Horse seri concluida.
A Figura 2-6 mostra como os construtores funcionam na pilha de chamadas.

4. Object o
3. Animal O calls super ( )

2. Horse ( ) calls super ()

l. main ( ) calls new Horse ()

Figuro 2-6 Construtores no pi/ho de chomodos

Regras dos construtores


A lista j.g"lf re^sume as que voc6 teri que conhecer para faze.r o exame (e para compreender o restante
" .regras
cesta segao). v oce preasara se lembrar-se delas, portanto, estude-as mars de uma vez.
r Os construtores podem usar qualquer modificador de acesso, inclusive private (um construtor private
significaque somente o c6digo que estiner dentro da pr6pria classe poderi inJtanciar um objeto desse tipo, ionanto, se
a classe do construtor private tor permitir que uma instincia dela seja usada, deve fornecer uma varilvel ou m6todo
static que conceda acesso a uma iistAncia ciiada dentro da classe).
I O nome do construtor deve coincidir com o da classe.
I Os construtores nio devem ter um tipo de retorno.
r E valido (mas inritil) ter um m6todo com o mesmo nome da classe, por6m, isso nio o tornar6 um construtor. Se
houver um tipo de retorno, seri um m6todo em vez de um construtbr. Na verdade, voc6 poderia ter um m6todo e um
construtor com o mesmo nome - o nome da classe - dentro da mesma classe, e isso nlo 6 um problema paraJava.
Cuidado para nlo achar que um m6todo 6 um constnrtor e vice-versa - pro*i. ,.*pre um tipb de retorno.
r Se voc6 nlo inserir um construtor no c6digo de sua classe, um constnrtor padrio seri gerado automaticamente
pelo compilador.
I O construtor padrio ser| sempreum construtor sem argumentos.
I Se voc6 quiser um construtor sem argumentos e tiver inserido algum(n$ outro(s) no c6digo de sua classe, o
compilador nio fornecer6 esse constirtor (ou qualquer outro). Ein outras palavias, se uori"tiaerinseido am
clnthatlr clrt aryt/rlettlr, nZo teni tlm sem argumentli a nenlJ que o insira por conta pnipia!
Todo construtor deve ter como sua primeira instruEXo a chamada a um construtor sobrecarregado (this ( ))
ou ao constnrtor da superclasse (super ( )), mas lembre-se de que essa chamada pode ser inserida pelo
compilador.
Se voc6 inserir um construtor (emvez de ficar esperando pelo construtor padrio gerado pelo compilador) e ndo
digitarachamadaasuper( )ouathis( ),icon?iladirinseini,automaticamente,irztachanadarsuper(') sen
argt/mentos, como a primeira instrugdo do constrvtor.

T Uma chamada a super ( ) pode ser sem argumentos ou incluir os argumentos passados para o construtor da
zuperclasse.

IJm construtor sem argumentos nio ser6 necessariamente o constnrtor padrio (ou seja, o fornecido pelo
compilador), apesar de ele nunca ter argumentos. O coushzrtorpadrio i o que o nntpikdorfomecelEmborio
JAVA 5 79
construtor padrio nuncatenha argumentos, voc6 pode inserir seu pftipit construtor sem argumentos.
t podeni,fazer uma chamada ao m6todo de uma instAncia, ou acessar uma vari6vel de instAncia, at6 que
ndo
Y?:€
tenha executado o construtor da superclasse.
I Apenas vari6veis e m6todos static p9{eqr s9r acessados como pafte da chamada a super ( ) ou this (
) . (Exemplo: super (Animal . NAME )) 6 v6lido, porque NAME 6 declarada como uma variivel static.
I As classes abstract t6m construtores e eles sio chamado s serupre que uma subclasse concreta 6 instanciada.
r As interfaces ndo t6m construtores. Elas nio fazem pane da irvore de heranga de um objeto.
r A
$i1 maneira pela qual um constmtoS pode ser chamado 6 dentro de outro construtor. Em outras palavras,
voc€ nio pode escrever um c6digo que chame efetivamente um construtor como vemos abaixo:
class Horse {
Horse0{}//construtor
rroid dnQirr+Fl\ I

HorseO; // chamando o construt.or - inv6.lidot


]
]

ldentificando se um construtor padrio seri criado


O exemplo a seguir mostra uma classe Horse com dois construtores:
class Horse {
Horse O { }
Horse(String name) { }
)

O compilador inseriri um consrrutor padrio para a classe acima? Nio!


E para uma variagio da classe como a descrita abaixo?
class Horse {
Horse(String name) { }
)

Agora o compilador inseriri um construlor padrlo? Nio!


E para esta classe?

class Horse ( )

no ponto exato. O compilador gerarS,tmconstnrtor padrXo para a classe anterior, porque nio foi
{Bpr3,chegamos
celrnroo nennum construtor para ela.
Certo, e quanto a esta classe?

rlaqq IJ^rc6 f 1

void Horse( ) { }

i
Pode paruer que o compilador nlo crrari um construtor, porque ji existe um na classe Horse. Existe mesmo?
\-rDserve novamente a classe Horse anterior.

Oque hi de errado com o constnrtor Horse( )?.Ele nio 6 de forma alguma um consrrutor! E simplesmente um
m6todo que por acaso tem o mesmo nome da classe. Lembre-se de que o tipo de retorno 6 uma
fista certa de que
estamos olhando para um m6todo, e nio um constnrtor.

Como voce pode ter a certeza de que um construtor padrio seri criado?
Isso ocorreri quando aocd ndo criar nenhum construtor em sua classe.
Como voc6 poder6 reconhecer o construtor?
Da forma a seguir:
I O construtor padrXo te ri o mesmo modfirador dt acesso da classe,

I Ele ndo terd atgumentor.

I Ele incluir6 uma cbamada sem atgamenttt ao constrator da stperclatse (super ( ) ).


80 Copitulo 2: OrientoE6o o obietos

A Tabela 2-4 mostrao que o compilador gerari (ou nio) para sua classe.

Tobelo 24 Codigo do construto r gerodo pelo compilodor

C6digo do closse C6digo do construlor gerodo Pelo


(digitodo por voc6) com pilodor

class Foo {
roo( ) {
cfass Foo { } Eulrer ( );
)
)

class Foo {
cfass Foo { } Foo( ) {
FooO {} Euper( ),
] )
]

class Foo {
public roo() {
nrr].'linalaceFnn {l super( );
)
]

class Foo {
class Foo { } F^^/qfrinn q\ I
I,OO(Srrngs) tJ auper( );
) ]
)

class Foo { }
!oo(Scrfngsl tj Nenhum , o compilador nao precisa inserir
super ( ) ;
]
]

cfass Foo {
void Foo O {}
class Foo { ) roo() (
voidFooO {} super( );
] )
]
(void Foo O 6 um m6todo, nao um construtor.

O que acontecer6 se o construtor da superclasse tiver argumentos?


Os construtores podem ter argumentos da mesma forma que os m6todos, e se voce tentar chamar um m6todo que
use, digamos, um tipo int, mas nio passar nadaPara ele, o compilador reclamari:
cfass Bar {
class UseBar {
public static void main (String [] arqs) t
Barb=newBarO;
b.takelnt () t / / Tenta chamar wn n6todo takelnto sem argJumentos

O compilado r avrsarique voc6 nio pode chamar takeInt ( ) sem passar um tipo int. E 9laro. qg9-o- .
compil;dor aprecia urrenigma ocasional, portanto, a mensagem que exibir6 em algumas vers6es da JVM (pode
variar com a verseo) nio seri tio clara:
UseBar.java:7: takelnt(int) in Bar cannot be applied to o
b. takelnt O ;

Mas voc6 a entender6. A conclusio 6 que deve haver uma corresponden cia para o m6todo. Por correspondAncia,
queremos dizer que os tipos dos argumentos devem poder aceitar.os valores ou varilveis que voce estiver
passando e na oraem em que forempassados. O que nos conduz de volta aos constnrtores (e voc6 Pensou que
nunca chegariamos neles), que funcionam exatamente da mesma maneira.
JAVA 5 8I
Assim, se o construtor de sua superclasse (isto 6, o constnrtor de sua superclasse,/parent imediata) tiver
argumentos, voc6 teri que inserii a chamada a super ( ) , fornecendo os argumenros apropriados. Ponto crucial:
sesua suPerclasse ndo tiver um constnrtor sem argumentos, voc6 tenl qte ins#. rr* .orrt-ior em sua cl"rse (a
subclasse) Porque precisard de um local para inserir a clianado ao nnstrutor da s'upockss, cvm 0r atgamentus
@ropiadot.
O c6digo a seguir 6 um exemplo do problema:
^l ^^^
Lfq-r rulrrrrqa
^61*-l 1

Anima] (String name) t ]


)

cl-ass Horse extends Animal {


Horse) { (

super0; // Problernal

j
E, novamente, o compilador nos tratari com uma clareza impressionante:
Horse. java:7: cannot resolve symbol
symbol : constructor Animal_ ( )
location: class Animal
superO; // Problema!
Se voc6 tiver sorte (e for lua cheia), seu compilador talvez seja um pouco mais explicito. Mas novamente, o
problema ser6 o.fato de nlo haver uma corrispondAncia para o q.ri.rt"*os tentando chamar com super ( )
um construtor de Animal sem argumentos.
Outra maneira de colocar isso 6 que se sua superclasse ndo tiaer am consttator tem argllmentus, entio, em tua tubc/asse
uoc6 nio
podenl usar o conshvtorpadrdofomecidipek nrpilador. E simples assim. que o coirpilador s6 pode inserir a chamada a
Ji -
um construtor super ( j sem arg,rmerrios, voc6 nio conseg,riri rr.* -.r-o compilar;lg" .;;; ; lafii.
segurr: "--
class Clot.hing i
Clothing(String s) { }

)
class TShirt extends Clothing { }
IJma.tentativa de compilar esse c6digo nos traria o mesmo erro que obtivemos quando inserimos um construtor
na subclasse com uma chamada i versio sem argumentos de super ( ) :
Clothing. java: 4: cannot resolve symbol
<rmlrnl . .^ncf rrr^f ar ll nrlr.ir1f1r9
na / \
\ /

focation: class Clothing


class TShirt extends Clothing { }

Na verdade, o c6digo anterior de cloching e TShirt 6 implicitamente o mesmo mostrado a seguir, no qual
fornecemos um construtor para TShirt que 6 id6ntico ,o .onrt*tb, padrlo fornecido pelo compilador: "
class Clothing {
Clothang(String s) t )
]
class Tshirt extends Clothino {
t t constrl.,,tor identico ao construtor cadrdo
,/ / f ornaai dn nal n anmni I
^^^-
Tshirt ( ) {
supero; // Ndo vai funcionar!
j // Chama um construtor sem argumentos Clothing( )

j // mas esse construtor ndo existel


Um. riltimo ponto relacionado. a toda essa po.lAmica sobre o construtor padrio (e que provavelmente 6 muito
obvro' mas. temos que mostre-lo ou nos sentiremos culpados por anos), 6 que ar constratores nunca sdo herdados. EIes
nlo sio m6todos. Nio podem ser sobrescritos (porque nio sio m6todos, e s6 os m6todos podem ser sobrescritos).
82 Copitulo 2: Orientog6o o obietos
Poftanro, o(s) tipo(s) de construtor(e$ que sua superclasse_tiver, de maneira alguma determinar6 o tipo de
consrnrtor iia.ao q,r. rro.6 prr*"t acreditam que o construtor padrio de alguma forma
coincidiri ** o "bte.i.'Algrn",
da supercLsse, trot que ter6 (lembre de que o conshtttorpadrd.o i sempre am
"o'rrrt*to,
constrator sem argunento) ou nos usados
"rru*entos
na chamadi ) super ( ) fornecida pelo compilador.
"rgrr*.ntot
Por6m, embora os constnrtores nio possam ser sobrescritos, voc6 j6 viu que eles podem ser sobrecarregados, e

normalmente o sio.

Construtores sobrecarregados
Sobrecarregar um consrruror significa inserir v6rias vers6es dele, cada uma tendo uma lista de argumentos
diferente, como nos exemplos a seguir:
class Foo {
roo0 { }
Foo(String s) { }

A classe Foo anterior possui dois construtores sobrecarregados, o que usa.uma string e outro sem argumentos. Ji
que nio h6 um c6digo na versXo sem argumentos, na verdade, idAntica ao construtor padrio. que o
essa classe 6
compilador fornece."Mas, lembre-se de que como j6 existe um construtor nessa classe (o que usa uma string), o
.o*pil"dor nio fornecer6 um construtor padrXo. Se quiser que um construtor sem argumentos sobrecarregu.e a
lr.rrio com argumentos que voc6 j6 tem, tir6 que inseii-lo por sna conta, exatamente como no exemplo de Foo.
A sobrecarga de um construtor normalmente 6 usada para fornecer maneiras alternativas de os clientes
instanciareir objetos de uma classe. Por exemplo, se o-cliente souber o nome d9 animal, poderi pass6-1o para
".-
um construtor de Animal que use strings. Mas se ele nio souber o nome, poderi chamar o constnrtor que nio usa
argumentos, e este fornecei6 n* tto-. padrlo. Veja como funciona:
1. public class enimal {

2. String name;
3. Animal(String name) {

4. this.name = name;
s. )

7. Animal O {
8. this (makeRandomName O) ;

10.
11. Etatic String makeRandomNameo {
1,2. int x = (int) (Math.random(1 * 5);
1-3. String name = new Stringi] {"Fluffy", "Fido"'
"Rover", "Spike",
"Gigi"] [x] ;
L4. return name;
15. )
]-6.
17. public static void main (String [] args) i
18. Animal a = new animal0;
L9. System.out.println(a.name) ;
20. Animal b = new animal("zeus");
21. System.out.println(b.name) ;
22. ]
23. \
A execuglo desse c6digo quatro vezes produzir| a saida:
t java Animal
Gisi
Zeus
JAVA 5 83

I java Animal
Fluffy
Zeus
t java Animal
Rover

I java Animal-
Fluffy
Zeus
Muita coisa aconteceu no c6digo anterior. A Flgur_a 2-7 mostra a pilha de chamadas de construtores quando um
constnrtor 6 sobrecarregado. Examine a pilha de chamadas e, em seguida, percorreremos o c6digo desde o inicio.
r Linha 2 Declara avari|vel de instAncia de String nana
r Linhas3 a5 Insereoconstrutorqueusastringseoatribuiavari6vel deinstincianane.
r r,inha
T P ^qy;que fica divertido. Suponhamos que cada animal precise de um nome, mas o cliente (o c6digo
chamador) pode nio saber qual deve ser usado, porta.rto, voc6 attuir6 um nome aleat6rio. O construtor seir
argumentos gerarS, vm nome chamando o m6todo makeRandomName( ).
4. object ( )

3. Animal (Strinq s ) chama super ( ,r

2. Animal ( ) qhama this ( randoml-yChosenNameString)


l.main( ) chama new Animal( )

Figuro 2-7 - Construfores sobrecorregodos no pilho de chomodos


r Linha8 O construtor- sem argumentos chamar6 o constnrtor que o sobrec arrega e usa strings, da mesma
maneira que seria chamado se o c6digo-cliente estivesse executando o comando new para instinciar um
objeto, passando para ele uma string relacionada ao nome. A chamada sobrecarregada nsa a palavra-chave
tJris, empregando-a como se fosse o nome de um m6todo, this ( ) . Portanto, a linha 8 esi6 simplesmente
chamando o constrtrtor da linha 3, passando para ele uma string selecionada aleatoriament , emviz de um
nome escolhido pelo c6digo-cliente.
r Linha 11 Observe que o m6todo makeRandomName ( ) foi marcado com static! Isso porque voc6, ndo
pode chamar um m6todo de instAncia (em outras palavras, nio-static) ou acessar uma vari6vel ie instAncia,
at6 que o constnrtor da superclasse tenha sido exicuta do. E ji
que esse construtor seri chamado a partir do
construtor da linha 3, emvez de usar o da linha 7, alinha 8 s6 poderi empregar um m6todo static
para
gerar o nome. Se quis6ssemos que todos os animais sem nomes especificidos pelo chamador tivessem o
mesmo nome padrXo, digamos, 'Fred", enteo, a linha 8 poderia apresentar thls ( "Fred" ); em vez de
chamar um m6todo que retorne uma string com o nome escolhido aleatoriamente.
r Linha 12 A linha 12 nio tem nada a ver com construtores, mas j6 que estamos todos aqui para aprender... Ela
gera um nfmero aleat6rio entre O e 4.

r Linha 13 Sabemos que 6 uma sintaxe estranha. Estamos criando um novo objeto String (apenas uma instincia
de String), mas. queremol gue a string seja selecionada aleatoriamente em uma-lista. 56 {ue nio temos a lista,
portanto, precisamos cri6-la. Assim, apenas nessa linha de c6digo:
1. Declaramos uma vari6vel de String, nane.

2. Criamos um array de String (anonimamente - nio atribuimos o array a nada).


3. Recuperamos a string no indice [x] (sendo x o nrimero aleat6rio gerado na linha 12) do array de String
rec6m-criado.
4. Atribuimos a string recuperada no array i variivel de instAncia declarada, nama Poderiamos rer tornado
a leitura mais f6cil se tiv6ssemos escrito apenas:
String [ ] namel.ist = { "F1uf fy", "Fido" , "Rover" , "Spike", ,.ciqi,'} ;

String name = namelist [x] ;


Mys o.ndefc-a a diuersdo?Inserir uma sintaxe incomum (principalmente par^ um c6digo que nio esteja totalmente
relacionado ao cerne da questio) f.az pane do espirito do exame. Nlb fique (ceno, fique assusrado, mas
entAo apenas diga para si mesmo: "Calma", e d€ prosseguimento). "rsustlado

r Linha 18 Estamos chamando a versio sem argumentos do construtor (fazendo com que um nome aleat6rio
da lista seja selecionado e passado para o outro construtor).
84 Copitulo 2: Orientog6o o objetos
f Linha 20 Estamos chamando o constnrtor sobrecarregado que usa uma string representandQ o nlme.

O ponto chave a exrrair desse exemplo de c6digo esta na finha 8. Emvez de chamar super ( ) , estamos
chimando this ( ) que nmpre tWtf* una chinad.a a uatro cunstrator da mesma classe. Certo, mas o que aconteceri
depoisdachamada a this ( )i CJo outarde o construtor super ( ) ser6 chamado, nXo 6? L6gico..Uma.
cfr"-"d" a this ( ) significa apenas que vocA esti retardando o inevit6vel. Algum construtor' em algum local,
ter6 que Iazer a chamada a super ( ) .

Regra chave: a primeira linha de um construtor deve ser uma chamada a super ( ) ou a thig ( ).

Sem exceg6es. Se voc6 nXo tiver nenhuma dessas chamadas em seu construtor, o compilador inserir6 a chamada
semargumenrosasuper( ).Emoutraspalavras,seoconstrutorA( )tiverumachamadaathis( ),o
compiLdor saberi que ndo seri esse construtor que chamari super ( ) .
A regra anterior quer dizer que um construtor nunca pode ter tanto uma chamada a super ( ) quanto a this (

I . J6 que essas chamad"r p.eiim* ser a primeira instrug-Xo de um construtor, voc6. nio.pode usar de maneira
^.onrtrutor.
vilida as duas no -.r-o Issb tamb6m significa que o compilador nio inserir6 uma chamada a su-
per ( ) em um construtor que possua uma chamada a uhis ( ) .
Pergunta a se considerar: O que vocA acha que acontecerisetentar compilar o c6digo a seguir?
class A {
AO{
this("foo");
)
A(String s) {

this O ;
)

)
Seu compilador pode nio captar o problema (isso variari dependendo do compiladgl ml1 a maioria nXo
perceberi o pro6lema). Ele presumir6 que voc€ sabe o que esti fazendo. Conseguiu identificar a falha?-Dado. que o
'.onrt*to,
d. .t-" superclaise deve seriempre chamado, onde a chamada a super ( ) seria inserida? Lembre-se
de que o compilador nio vai inserir rr- .onit*tor padrio se voc6 i6tiver um ou mais construtores em sua classe.
Mesmo assim, ele aindainsere uma chamada a super ( ) em algum construtor que nlo tenha explicitamente uma
chamada ao construtor da superclasse - a menos que o construtor_ ji tenhauma chamada a this ( )' Ponanto, no
c6digo anterior, onde srrpei ( ) pode ser inserido? Os rinicos dois construtores da classe t6m chamadas a
thi; ( ), evoc6 obter6e*at"metrte o mesmo que conseguiria se digitasse o c6digo do m6todo aseguir:
public void goo t
doStuff ( ) ;

)
public void doStuff ( ) {
go(),.
)

AgoravocE consegue enxergar o problema? E claro que sim. Apithafoi exndida!Elaficou maior e maior, a!6 qu9 .
siirplesment. r. e o i6dig" do m6todo foi deiramado, esvaindo-se parafora daJVM e.caindo no chio. Dois
ibtin
.orrit-tor.r robrecarregados chinando this, sio dois construtores chamando um ao outro. Repetidamente, resultando em
* java A
Exception in thread \\main" java. Iang. StackOverflowError
O beneficio de ter consrrutores sobrecarregados 6 que voc6 oferecer6 maneiras flexiveis para a instanciagio de
objetos de sua classe. A vantagem de um construtor que chame outro construtor_sobrecarregado 6 evitat a
duplicaglo do c6digo. No exeLplo de Animal, nio hlvia nenhum c6digo a16m da co_nfiguragio do nome, mas
i*agine se depois d-a linha 4 houvesse ainda mais trabalho a ser feito no construtor. Pela insergio de tod-as as
t"raLt um constnrtor e, em seguida, fazendo 9om qge outros construtores o chamassem, voc6 nio teria
"ttr "p6tt"r
que escrerrei e fazer a manutengio de v6rias vers6es do c6digo desse construtor imponante. Basicamente, os
.b.rrt*to.., que nio fossem ,.iarr"rrt., chamariam esse outro constnrtor sobrecarregado, passando para ele os
dados que precisasse (dados que o c6digo-cliente nio forneceu).
Os construtores e a instanciagio se tornarXo ainda mais interessantes (agora que vocA achou que estava livre) _

quando chegarmos )s classes internas, mas sabemos q-ue voc6 s6 poder6 suportar tanta diversXo em outro capitulo,
ponanro, esramos guardando o resto da discussio sobre instanciagio de classes internas para o Capitulo 8.
JAVA 5 85
Obletivo poro o CertificoEdo

Static (Objetivo 1.3 do Exame)


1.3 Desenaoluer nidigo que dulare, inicialiry e use tipos primitiuos, arraJs, entlmr e objetos como uaridueis eshiticas, tle instdncias
e locais.
Aldm disso, usar identifcadores utilidos para nomes de uaritiaeis.

Variiveis e m6todos stat:c


O modificador static
tem um impacto de forma profunda sobre.o comportamento de um m6todo ou variivel que o
trataremos como um conceito inteiramente separado dos outros modificadoies. Para compreender a manerra como um
membrostatic funciona,examinaremosp-rimeiro arazioparausarum. Imaginequeioc6tivesseumaclasseutilit6ria
com um m6todo que sempre fosse executido da mesma mineira; sua rinica"fungio seria retornar, digamos, um
nrimero aleat6rio. Independente de que instAncia da classe execure o m6todo - ile sempre se compoitari '
exatamente da mesma f-orma..Em ouiras palavras, o comporramento do m6todo nio depende do Jstado (',ralor., da
variivel deinsA.ncia) de um objeto. Portanto, por que, entio, voc6 precisa de um objeto, j6 que o m6todo nunca
ser6 especifico da instAncia? Por que nio apenls soii.it"t a pr6pria classe para ."...rt"r'o m6todo?

Imaginemos outro cen6rio: suponha-que voc6 quisesse ter uma contagem ininterrupta de todas as instAncias
criadas _a partir de uma classe ispecifi-a. Onde irmazenaria essa variivel? Nio funcionar6 mant6la em uma
vari6vel de instAncia dentro da Classe cujas instAncias voc€ est6 registrando, porque a contagem ser6 reinicializada
com um valor padrlo a cada nova instAncia.

$ lesposta tanto parao cenlrio do m6todo utilitirio, sempre executado da mesma forma, quanro para a contagem
ininterrupta do total de instAncias 6 usar o modificador static. As variiveis e m6todos marcados co"m static
Pertencem i
classe, emvez de a qualquer instAncia especifica. Na verdade, vocA pode usar um m6todo ou variivel
static sem ter absolutamente nenhuna in$incia dessa classe. 56 precisa ter a classe disponivel para poder chamar um
m6todo static ou acessar uma variivel As variiveis static. tamt6tn static poi.-
ier acessadas sem ter
a instincia de uma classe. Mas se houver instAncias, avari|vel static
dessa classe ier6 companilhada por todas
as instAncias da classe; s6 haveri uma c6pia.

O c6digo a seguir declara e usa uma vari6vel static de contador:


class Frog {

static int frogCount = 0; // Decl.ara e inicializa a vari6vel static


public Frog0 {
frogfcount += 1; / / Modifica o valor do const.rutor
)
public static void main (String [] args) {
new Frog'O;
new Frog( ) ;
new FrogO;
System.out.println("Frog count is now .. + frogCount);
]
)

No c6digo anterior, a vari|vel static frogCount 6 configurada com zero, quando a classe Frog 6 carregada pela
priqgira vez pela JVM , antes que qualqaer a)aat (A prop6sito, ioc€. nilo precisard rellmente "
instdncia de Frog rc1a '
inicializar uma vari6vel static com zero; as variiveis est6ticas iecebem ot
-"r*or-rralores padrlo que as
varilveis de instAncia). Sempre que uma instAncia de Frog for criada, o construror ser6 executado e arrmlentari o
valor da vari6vel est6tica f rogCount. Quando esse c6digo for executado, tr6s instAncias de Frog serio criadas
emmain( ) e o resultadoser6:
Frog count is now 3

Agora imagine o que aconteceria se frogCount fosse uma variivel de instAncia (em outras palavras, ndofosse unidc):
Quando c6digo for executado, ainda criari tr6s instAncias de Frog em main ( ) , mas o resultado seri... Um
esse
erro do compilador! Nunca poderemos fazer esse c6digo ser executado, porque nem ele mesmo ser6 compilado.
class Frog {
i nf f rnaanrrhf - n. // DecTara e inicializa a vari6vel de instAncia
nrrhlin !E'r^ft/\
+vv \ / /L

fr^d/l^rrnf
rrvvvvsrrL r-,
-
1.
r, / / Nlodifica o valor do construtor
1
)
86 Copitulo 2: OrientoE6o o obietos
public static void main (String [] args) {

new FrogO;
new Frogo;
new FrogO;
System.out.println("Frog count is now " + frogcount);

]
AJVM nio sabe que objeto Frog de frogCount voc6 est6 tentando acessar. O problema 6 que opr6prio m6todo main (
) E estitico ., po.t*to, nio e# sendo"executado em relagio a lenhuma initAncia espegiTil" 4 classe, em vez disso
est6 relacionadb apenas a classe. Um m6todo static nXo pode acessar uma vari6vel (de instincia) nlo static,
porque falar que nio h6 instincias da-classe ativa na mem6ria e, mesmo se houvesse, o m6todo
ndo b,l ana instincialSem
nio O mesmo se aplica a m6todos de instAncia; um m6todo static nio pode
saberia nada sobre elas.
"trti. diretamente um m6todo nio staLic. Considere static : classe, nlo stat.ic : instlncia. Tornar o
chamar
m6todo chag{9 pelaJVM-(main ( ..)) static significa que aJVM nio teri que criar uma instAncia de sua classe
apenas para iniciar a execugio do c6digo.

oBSERVAQ6ES pene O EXAME


[Jm dos enos maisfreqiientet cometidos porprogramadoru laua iniciantet d tenlar acessar una uarihuel de in$6ncia (o qae ignfrca una
aaiiaelndostatic) apartirdomitodomain( ) (quendotennenhamainfomag1osobrein$incias,prrtantz,ndopodeaeessara
aaiduel). O aidigo a rcgair i um exenpk de acesso inudlido de ama aaidael ndo sLaLic a partir dt um mitodo s tat i c.'

class Foo {
int x = 3;
public static void main (String [] args) t
System.out.println("x j-s " + x) ;
)
]
E bon qae aoc6 saiba qae use aidigo nunca uri compilado, porque n6o 6 possiuel acessar uma uariiuel n6o sEaLic (de instdnciQ a patir
de um mitodo static. Apenas inagine o compilador diqpndo 'Ei, ndo tenbo iddia de que uaiduel x do objeto Foo aocd ettui tentando
exibir!" I-,embre-rc de qae t4 a cksse que execata o mitodomain ( | e ndo uma instdncia da classe. E claro que aparte corrplicada no
exane seni qae a perglnta ndo pareceni tdo 6bria quanto o c1digo anterior. O problena sobre o qual uocd estari sendo aualiado acesiar tlma -
uariduel ndo sLatic a paftir de am mitodo static senl. canuflado no aidigo qle pareceni aaa/iar oatra qautdo, Por exempk, seria
-
mais prouduel que o cddigo acina aparecese naforwa:

class Foo {
int x = 3;
fl-oatY=4.3f;
public static void main (String 1l args) {
for (int z = x; 7 < ++xi z-, Y = Y + z\ {
/ / c6digo complicado de looping e branching
)

Portanto, efiquantr uoc6 ertiaesse tentando acompanbar a hgica, o problena real seia qile x ey ndo poden ser ttsados dentro de main (

),porquesdoaaridaeisdeinstdnciaendostaticlOmetnose@/icaa0acervdemdtodosndosLaLic apanirdcummdtodo
static. Aregrai,omitodo static deumaclassendopodeacessarilmnembro-mitodoouaariiuel-ndouhitico(deinstdncia) de

nta pnlpria classe.

Acessando yari6yeis e m6todos static


Jriquevoc€nioprecisaterumainstinciaparachamarumm&odostatic ouacessarumavai|velstatic,entio,
iomo chamar6 ou usar6 um membro st;tic? Qual 6 a sintaxe? Sabemos que para um m6todo de instAncia comum, voc6
usaria o operador ponto na refer6ncia a uma instAncia:
nl:ce Frnn I

int frogSize = 0;
nrrhlia
vgvf!v+fr9Yv9rrvVv*!v\,
in{- aat-FranQizaI\ I

return frogSize,'
JAVA 5 87
public Frog(int s) {
frogSize = s;
)
public static void main (String [] args) {
Frog f = new Frog(25);
System.out.println(f.getFrogsizeO); / / Acessa o m6todo da instAncia usando f
)

No c6digo anterior, criamos uma instAncia de Frog, a atribuimos a variavel de refer6ncia f e, em seguida, usamos
essa referenciapara chamar um m6todo na instdnciaFrogque acabartos rriar.Emoutras palavras, o m6toio
getFrogsize ( ) est6 sendo chamado em um objei6 Frog especifico na memona.
Mas essa abordagem (usar a refer6ncia a um obieto) nio 6 apropriada para acessar um m6todo static. Doroue
pode nio haver absolutamente nenhuma insdncia da classei Portanto, a maneira de acessarmor .rm '
static (ou vari6vel static) serl usar o operador ponto n0 nome da classe, e nio na refer6ncia a uma-6ioldo
instAncia,
como vemos abaixo:
c]ass Frog {
static int frogCount = 0; // Dec]ara e inicializa a vari6vel static
public rrog O t
frogCount += !; / / Modifica o valor do construt.or
]
]
c]ass TestFrog {
public static void main (Stri_ng [] args) {
new FrogO;
new FroqQ;
new FrogO;
System.out.print("frogCount: "+Froq.frogCount.); //Acessa a vari5vel static

Mas apenas. p ar.a.tornar isso realmente confuso, a linguagem Java tamb6m permite que voc6 use uma uai,iuel de
refer€ncia de objeto para acessar um membro static:
Frogf=newFrog0;
int frogs = f.getFrogCount()t // Acessa o m6todo est6tico getFrogCount usando f
No c6digo anterior, instanciamos um objeto Frog, atribuimos esse novo objeto a variivel de refer0ncia f e, em
seguida, usamos a referAncia I para charnar um m6todo static! Mas mesmo que tenhamos usado uma instAncia
especifica de Frog.para acessar o m6todo static,-as^regras nio.foram alteradas. Isso 6 simplesmente um truque de
sintaxe para permitir que voc6 ase rrma uariduel de refer6ncia de objeto (mas nXo o objeto que ila referencia) pari
acessar uma variivel ou m6todo static, mas o membro stat.icainda nio tem conhetimento da instAncia
especifica usada para cham6lo. No exemplo, o compilador sabe que a refer6ncia f 6 do tipo Frog e, porranro, o
m6todo staticda classe Frog 6 executado sem conhecer ou se preocupar com a instAncia na outri exremi&de da
refer6ncia f. Em outras palavras, o compilador s6 se preocupari com o fato de a referdncia f ser declarada com o
tipo Frog. A Figura 2-8 ilustra os efeitos do modificador stat.ic sobre m6todos e variiveis.
Outro ponto a lembrar 6 que os n,itodos static ndopodem sersobrecarregadar! Isso nXo significa que eles nio possam
ser redefinidos em uma subclasse, mas redefinir e sobrecarregar ndo sio a mesma coisa.

Vejamos um exemplo de m6todo static redefinido (lembre-se, nio-sobrescritos):


class Animal {
static void doStuff O {
System.out.print ( "a " ) ;

)
class Dog extends Animal- {
static void dostuffO { // 6 uma redefinigd.o,
88 Copftulo 2: Orientogdo o objetos
/ / nd'o uma sobrescrj-qdo
System.out.print ( "d ") ;

)
public static void main(string [] args) {
Animal tl a = {new Animal O , new DoSO ' new Animal O };
for(int x = 0,' x < a.length; x++)
alxl.dosuuf,f Ot | / cli;ama o m6todo static
)
)

Executar esse c6digo produz a seguinte saida:

Lembre, a sintaxe a [x] .doStuf f ( ) 6 apenas um atalho (o truque da sintaxe)... O compilador usar6' emvez
disso,algocomoAnimal .doStuff O.Reparequenlousamosaquioloop for apimoradoloJava1.5
(abordaJo no Capitulo 5), embora pud6ssemos t6lo feito. Espere ver uma mistura de estilos de programaglo e
pr6ticas deJava 1.4 eJava 5 no exame.

classe Foo
int size = 42; O m6todo static neo 6 capaz de
slatic void doMore( ){ acessar uma variivel de inst6ncia
int x = sVe; (nio-static)
]

classe Bar
void go ( ); O m6todo static ndo 6 capaz
stat,ic. void doMore ( ){ de acessar um m6todo nio-
J
fft ); static

classe Baz
sEatic int count; O m6todo static 6 copoz de
static void woo( ){ } acessar um m6todo ou uma
static void doMore( ){ variivel static
woo( );
i nF v .
- ^^irnF
)

Figuro 2-8 Os efeifos de sfolic sobre m6lodos e voriiveis

Obietivo poro o CertificoE6o

Acoplamento e Coesio (Objetivo 5. I do Exame)


5./ Desenao/aeraldigo que inplemente enc@vt/ameato rigido, acoplanntofraco e alta coesio en c/assu, e desmueros benefciot.

Ji vamos admitir logo de cara. As definig6es do exame da Sun para coeslo e acoplamento gi9 u-m tanto subjetivas, de
modo que o que e$;mos discutindo neste capitulo 6 do ponto de,vista do exame, que nio 6 de forma nenhuma a
verdade absoluta sobre esses dois principios OO de projetos. Pode nio ser exatamente a forma como voc6 os
aprendeu, mas 6 o que vocA precisa entinder para responder as quest6es. Haveri bem poucas quest6es sobre
acoplamento e coesio no exame real.
JAVA 5 89
t6picos, acoplamento e coesio, t6m a ver c.om a qualidade de um projeto oo. Em geral, o bom projeto
RXt l?k acoplamentofraco
oo pede e evita o fofte, e pede tamb6m aha coetdo e evita a baixacoesio. ComJ na maioria ias'
drscuss6es sobre projetos OO, os objetivos para a aplicaqio sio
r Facilidade de criagio
I Facilidade de manurengio
r Facilidade de melhorias

Acoplamento
Vamos comegar f.azendo uma tentativa de definigio do_ acoplamento. Acoplamento 6 o grau em que uma classe
conheceoutraclasse.Seorinicoconhecimentoque.aclasseAtemsobreaclasseB6oqieaclasseBexp6satrav6s
dasua interface, entio diz-se das classes A e B qui-elas t6m acoplamento fraco... E isso 3 bom. Se, por o^utro lado,
a classe A,depende de panes da classe B quc nib fazemparte da interface da classe B, entio o
as classes 6 mais forte... E isso nlo 6 bom. Em outras palavras, se A ".oplr*.nro."r..'
sabe mais do que deveria sobre a maneira pela
qual B foi implementada, entio A e B t6m acoplamenio forte.
lJsandocste segundo cenirio, imagine o que acontece quando a classe B 6 aprimorada. E bem possivel que o
desenvolvedor que esteja aprimorando.a classe B ne* saib" da exist6ncia da classe A, afinal po. qrr. dev'eria? O
desenvolvedor da classe B deve panir do principio que quaisquer melhorias que nio danifiqfuem a interface da
classe deverlo ser seguras, entio.ele pode modificar pirte da classe que nlo se refira ) interface, o que
entio f.az a classe A ser danificada. "lg,rm"
Opiorcasopossivel6ahorrivelsituagioemqueaclasseAsabedecoisasnio-relativas)APlsobreaclasseB,ea
classeB sabe de coisas nio-referentes i API sobre a classe A... Isso 6 MUITO RUIM. Se qualquer uma das claises
for modificada, 6 possivel que a outra seja danificada. Vejamos um exemplo 6bvio de ..opl"-.rrto fone, que
resultou de um encapsulamento mal feito:
class DoTaxes {
float rate;
float doColorado O {
SalesTaxRates str = new SalesTaxRates ( ) ;
rate = str.salesRatei // oh nio
// isi.o deveria ser uma chamada a m6t.odo:
/ / raLe = str.qetSalesRate (..CO', ) ;
/ / faz coi-sas com rate
)

)
class SalesTaxRates {
guJrlic float salesRate; / / deveria ser private
pubJ.ic float adjustedSalesRat-e; / / deveria ser private

public float getSalesRate(String region) {


salesRate = new ItoTaxes() .doColorado( ) ; / | oh nAo, de novo
/ / faz c61culos com base na reqiSo
return adjustedSalesRate ;

]
Todas as aplicag6es OO nietriviais slo uma mistura de muitas classes e interfaces rabalhando juntas. O ideal seria que
todas.as interag6es entre objetos em um_sistema OO usassem as APIs, ou seia, os contratos, das respectivas'classes
dos objetos. Teoricamente, se todas as classes de uma aplicagio tiverem APis bem elaboradas, entXo deveria ser
possivel que todas as interag6es interclasses as usassemtxclusivamente. Como discutimos anteriormente neste
capitulo, um aspecto do bom projeto de classes e de APIs 6 que as classes devem ser bem encapsuladas.
A questio 6 que o acoplamento 6 um conceito um tanto subjetivo. Por causa disso, o exame ir6 lhe testar em
exemplos realmente 6bvios de acoplamento forte; nio lhe ser6 pedido que faga julgamentos sutis sobre o assunto.

Coesio
Enquanto que o acoplamento tem a ver com a forma como as classes interagem umas com as ouuas, a coesio se refere a como
uma determinada classe foi elaborada. O termo coudo 6. usado para indicar o grau em que uma classe tem um rinico e
90 Copitulo 2: Orieniog6o o obietos
bem-focado prop6sito. Tenha em mente que a coeslo 6 um conceito subjetivo. Quanto mais focada for uma classe,
maior a ,rr" io.ieo - isso 6 bom. O principal beneficio da alta coesio 6 que tais classes normalmente sXo de
manutenglo muito mais f6cil (e sio modificadas com meno.s freq-ii6ncia) do.que as classes com baixa coesio. Outro
beneficio'da alta coesio 6 que as classes com um prop6sito bem focado tendem a ser mais reutiliziveis do que outras'
Vejamos um exemplo de pseudoc6digo:

'ld;ri:':::T*::::.i.
{ }

void saveToFil-eO { }

void print0 { }
j

Agora imagine que o seu gerente chegue e diga "Ei, sabe aquela aplicagio de contabilidade em que estamos
tribalhand6t Oiclientes icabaram dJdecidiique eles tamb6m vio querer gerar um relat6rio de projegio de
receitas, ah, e eles tamb6m querem fazer alguni relat6rios de inventirio._Mas eles gostaram dos nossos recursos de
relat6rios, entio certifiqu.-r. d. que todos-esses relat6rios permitam a eles escolher um banco de dados, escolher
uma impressora e salvar os relat6rios gerados em arquivos"... Oh, nXo.
Em vez de colocar todo o c6digo de impressio em uma s6 classe de relat6rios, provavelmente ser6 melhor usar o
seguinte projeto desde o comego:
class BudgetReport {
Options getReportingOptionsO { }
void generateBudgetReport(Options o) { }

cl-ass Connect.ToRDBMS {
DBconnectj-on getRDBMSO { }
l

class PrintStuff t
PrintOptions getPrintoptionsO { l
)

class Fil-eSaver {
SaveOptions getFileSaveoptionsO { }

Este projeto 6 muito mais coeso. Em vez de uma classe que faz tudo, dividimos o sistema em quatro classes principais, ca&
tr-" iom .rm papel bastante especifico, ort clero. Uma vei que n6s construimos essas classes esp eirafizadas e reuttlrzl.veis,
serl muito rnaii f6cil .t..err.i um novo relat6rio, vmavez que j6 temos a classe para a conexio ao banco de dados,
a classe para impressXo e a classe que salva os arquivos, e isso significa que elas podem ser reutilizadas Por outras
classes que possam querer imprimir um relat6rio.

Resumo para a certificagio


N6s comegamos o capitulo discutindo a imponAncia do encapsulamento em um bom pro.ieto orientado a
objetos, e depois falamos sobre como o bom encapsulamento 6 implementado: com vari6veis de instAncias
privadas e com getters e setters priblicos.
Em seguida, abordamos a imponAncia da heranga, para que voc6 pudesse entender a sobrescrigio, a sobrecarga ,o
polimorfismo, a conversio de refer}ncia,os tipos de retorno e os constnrtores'

Abordamos E-UM e TEM-IIM. n-UVt 6 implementado usando-se a heranga, e TEM-UM 6 implementado usando-se
variiveis de instAncias para se referirem a outros objetos.
O polimorfismo veio em seguida. Embora o tipo de uma variivel de refer0ncia nio possa ser modificado, ele pode ser
*rdo p".* r. .eferir a um o6jeto cujo tipo seja um subtipo do seu pr6prio. Aprendemos como determinar quais m6todos
sio invociveis para determinada variivel de referOncia.
JAVA 5 9I
Examinamos. a diferenga entre m6todos sobrescritos e sobrecarregados, aprendendo que o m6todo sobrescrito
ocorre quando umasubclasse herda o m6todo da superclasse, e, entio, o reimpleme ni^ p^r^adicionar um
comPortamento mais especializado. Aprendemos que no tempo de execugio, a
JVM chamar6 a versio da
subclasse em uma instAncia dessa subclasr. . .rr.rr^io da superclass" .* u*" instAncia da superclasse. Os
"
m6todos abstract deuem. ser.sobrescritos (ncnicaruente os m6todos abstract devem ser ifihnentados, endo
sobrescritos, j6 que, na verdade , niolrd nada asobrescrever).
Vimos que os m6todos novos devem manter a mesma lista de argumentos e tipo de retorno (ou, do
Java 5 em
diante,, eles podem retornar um.subtipo do tipo de retorno decllrado do m6todo sobrescrito da srp.rclasr.f do
m6todo sobrescrito e que o modificador de acesso nio pode ser mais restritivo. O m6todo nono t"-b6* nio pode
langar nenhuma excegio verificada nova ou mais abrangente que nlo tenha sido declarada no m6todo ,obr.rcrito.
Voc6 tamb6m aprendeu que o m6todo sobrescrito pode ser chamado com o uso da sintaxe
super.doSomething( ) ;.
Os m6todos sobrecarregados permitem que voc6 reutilize o mesmo nome de m6todo em uma classe, mas com
argumentos diferentes (e op.cionalmente, um tipo deretorno diferente). Enquanto os m6todos q,a,e sobrcsTeuem
outros ndo devem alterar a lista de argumentos, os m6todos sobruanegaiot preiso, faz|-lo. Por6m, diferente dos
m6todos novos, os sobrecarregados podem variar o tipo de retorno; o modificador de acesso e as exceg6es
declaradas da maneira desejada.
Aprendemos o funcionamento da conversio (em geral redutora), das vari6veis de referdncia, quando ela 6
necess6ria e cemo usar o operador insLanceof .

A implementagio de interfaces veio em seguida. As interfaces descrevem um contrato que a classe implementadora
deve segu.ir. As regras para s€ implementar uma interface sio semelhantes )quelas p".a i. estender rr*" .lass.
abstract. Lembre-se tamb6m de que uma classe pode implementar mais d. n*" interface, e que as interfaces
podem estender outra interface.
Tamb6m examinamos os tipos de retorno dos m6todos, e vimos que voc6 pode declarar o tipo de retorno que
quiser (supondo-se. que tenha acesso a uma classe para usar um tipo de retorno de refer6ncia a objeto), *.not
que esteja sobrescrito um m6todo. Com a excegio de um retornocovariante, um m6todo novo deve ier" o mesrrro
tipo de retorno do m6todo sobrescrito da superclasse. Vimos que enquanto os m6todos novos ndodevem alterar o
tipo de retorno, os sobrecarre gados poden fai€-lo (contanto que tanbi) alterem a lista de argumentos).
Para concluir, voc6 aprendeu que 6 vilido retornar qualquer valor ou variivel que possa ser implicitamente
convertido no tipo-de retorno declarado. Portanto, pbr eiemplo, short pode ier ietornado quando o tipo de
retorno declarado for um int. E uma referAncia a Horse pode ser retornada quando o tipo de-retorno declarado
for um objeto Animal (supondo que Horse estenda Animil).
Abordamos os constftrtores em detalhes, aprendendo que, se voc6 nio fornecer um construto r para a sua classe, o
compiladorinserir6um. O construtorgeradopelo compilidor6 chamado de consrrutorpadrio, e6 sempreumcon$ruror
sem argumentos com uma chamada sem argumentos a super ( ) . O construtor padrionunca seri gerldo se houver um
s6 construtor que seja na sua classe (independentemente dos argumentos que ele r.rse), entio, se voc6
lrecisar de mais de um
constnrtor na sua classe e_quiser usar um sem argumentos, ter6 de escrevA-lo voc6 mesmo. Tamb6m vimos que os
constnrtores nio sio herdados, e que voc6 pode se confundir com um m6todo que tenha o mesmo nome da classe
(9 lue_6 vilido). O tipo de retorno indica que um m6todo nio 6 um consrruror, uma vez que este riltimo nio tem
tipos de retorno.
N6s vimos como todos os construtores da 6rvore de heranga de um objeto serio sempre chamados quando o
o.bjel^g 6 instanciado usando-se new. Tamb6m vimos que os construtores podem ser sobrecarregados, o que
significa definir construtores com listas de argumentoi dife.etrt.r. Um construtor pode chamaioutro dimesma
classe com a palavra-chave this O , como se o constnrtor fosse um m6todo chamado this O . Vimos que todo
construtor precisa ter ou this ( ) ou super ( ) como a sua primeira instrugio.
Vimos os m6todos e variiveis static. Os membros static se associam ) classe, e nio a uma instAncia, de
modo que s6 existe uma c6pia de cada membro static. lJm erro comum 6tentar referenciar uma variivel de
instancia a partir de um m6todo static. IJse o nome da classe com o operador ponto para acessar membros
static.
N6s discutimos dois conceitos da programagio orientada a objetos, que sio o acoplamento e a coesio. O
acoplamento fraco,6 o estado desejivel para duas ou mais classes que-interajam rrriras.orn as outras atrav6s das
zuas_respectivas APIs. O acoplamento fone 6 o estado indesej6vel para duas ou mais classes que conhegam
detalhes internos sobre outra classe, detalhes nio revelados na API da classe. A alta coesio 6b estado desei6vel
para uma classe cujos prop6sitos e responsabilidades sXo limitados e bem focados.
E, s6 para lembrar, vocA aprendeu que o exame inclui perguntas ambiguas, elaboradas basicamerite para restar sua
habilidade no reconhecimento do quanto elas podem ser enganosas.

{ Exercicios r6pidos
Aqui estXo alguns dos pontos-chave de cada objetivo para certificagio deste capitulo.
92 Copitulo 2: OrientoE6o o obietos

Encapsulamento, relacionamentos E-ut't e TEM-UM (Obietivo 5.1)


E O encapsulamento aluda a ocultar a implementagio por tris de uma interface (ou API)'
tr O c6digo encapsulado fornece dois recursos:
E As vari6veis de instAncia sXo mantidas protegidas (geralmente com o modificador private).
E Os m6todos capturadores e configuradores fornecem acesso a variiveis de insdncia.
E O relacionamento E-Uvt se refere ) heranga.
E O relacionamento n-UU 6 representado pela palavra-chave extends.
E "E-UM", "herda de" e "6 um subtipo de" sio todas express6es equivalentes.

tr TEM-UM significa que a instincia de uma classe 'tem uma" refer6ncia I instAncia de outra classe, ou a outra
instAncia da mesma classe.

Heranga (Objetivo 5.5)


D A heranga 6 um mecanismo que permite que uma classe seja uma subclasse de outra, e, dessa forma, herdar
variiveis e m6todos da superclasse.
D A heranga 6 um conceiro fundamental, que est6 por tr6s do E-UM, do polimorfismo, da sobrescrigio, da
sobrecarga e da conversio.
fl Todas as classes (exceto obj ect) sio subclasses do tipo obj ect, e, portanto, herdam os m6todos de ob-
i:ats

Polimorfismo (Objetivo 5.2)


E Polimorfismo significa "muitas formas".
U Uma vari|vel de refer6ncia 6 sempre de um s6 tipo imutivel, mas ela pode referir-se a um objeto do subtipo.
E Um mesmo objeto pode ser referido por vari6veis de instAncias de muitos tipos diferentes - desde que elas
sejam do mesmo tipo ou de um supenipo do objeto.
E O tipo da variivel de refer6ncia (nio o tipo do objeto) determina quais m6todos poderlo ser chamados!

E As chamadas polim6rficas a m6todos se aplicam apenas a m6todos de instAncias sobrescritos.

Sobrescrig6o e sobrecarga (Objetivos 1.5 e 5'4)


E Os m6todos podem ser sobrescritos ou sobrecarregados; os construtores podem ser sobrecarregados, mas nio
sobrescritos.
D Os m6todos abstrac L deuerz ser sobrescritos pela primeira subclasse concreta (nio abstract).
O No que diz respeito ao m6todo sobrescritos, o m6todo novo:

E Deve ter a mesma lista de argumentos;


D Deve ter o mesmo tipo de retorno, exceto pelo fato de que, em Java 5, o tipo de retorno pode ser uma
subclasse - isso 6 conhecido como um retorno covariante.

tr Nio deve ter um modificador de acesso mais restritivo;


O Pode ter um modificador de acesso menos restritivo;
tr Nio pode langar exceg6es verificadas novas ou mais abrangentes;
tr Pode langar exceg6es verificadas mais restritivas ou menos abrangentes, ou qualquer excegio nio
verificada.
E Os m6todos f inal nio podem ser sobrescritos.

tr 56 os m6todos herdados podem ser sobrescritos, e lembre-se de que os m6todos private nio sio herdados.
E Uma subclasse usar6 super. overridenMethodName ( )para chamar a versio da superclasse de um
m6todo sobrescrito.
EJ Sobrecarga significa reutllizar o mesmo nome de m6todo, mas com argumentos diferentes.
fl Os m6todos sobrecarregados:
D Devem ter listas de argumentos diferentes;
fl Podem ter tipos de retorno diferentes, contanto que as listas de argumentos tamb6m sejam diferentes;
El Podem ter modificadores de acesso diferentes;
E Podem lancar exceQ6es diferentes.
JAVA 5 93
E os m6todos de uma superclasse podem ser sobrecarregados em uma subclasse.
tr O polimorfismo 6 aplicivel i sobrescrigio e nio )sobrecarga.
Q O tipo de objeto (e nio o tipo da vari6vel de refer€ncia) determina qual m6todo sobrescrito seri usado no ternpo
cte execugao.

tr O tipo de refer6ncia determina qual m6todo sobrecarregado ser6 usado no tempo de compilaglo.

Conversio de Vari6veis de Refer6ncia (Objetivo 5.2)


E Existem dois tipos de conversio de variiveis de refer6ncia: a conversio redurora e a ampliadora.
E Conversio redutora: se voc6 tiver uma vari|vel de referAncia que aponte para um objeto de um subtipo, poder6
atribui-la a uma vari6vel de refer6ncia do subtipo. Voc€ precisa f^ie, u iconversio explicita p"." iso, I o
resultado 6 que voc6 pode acessar os membros-do subtipb com essa nova vari6vel de referAncia.
0 Conversio ampliadora: voc6 pode atribuir uma vari6vel de referAncia a uma varibvel de referAncia de um
supenipo explicita.ou implicitamente. Essa 6 uma operagio inerentemenre segura porque a atribuigio
restringe as capacidades de acesso da nova variivel.

lmplementando uma Interface (Objetivo 1.2)


fl Quando voc6 implementauma interface, est6 cumprindo o seu contraro.
tr Voc6-implementa uma interface ao sobrescrever apropriada e concretamente todos os m6todos definidos pela
interface.
E Uma mesma classe pode implementar muitas interfaces.

Tipos de Retorno (Objetivo 1.5)


fl Os m6todos sobrecarregados podem modificar os tipos de retornol os m6todos sobrescritos nio podem, exceto
no caso de retornos covariantes.
E Os tipos de retorno de referAncias de objetos podem aceitar nul-L como valor de retorno
D Um array 4 um tipo de retorno vilido para declarar e para retornar como um valor.
E Para m6todos com tipos de retorno primitivos, pode ser retornado qualquer valor que possa ser converrido
implicitamente para o tipo de retorno.
tr Nada pode ser retornado a partir de um void, mas voc€ pode decidir nXo retornar. E permitido que voc6 use
simplesmente return,
em qualquer m6todo com um tipo de retorno void, para inierrornper um m6todo antes da
sua finalizagio. Mas nio 6 possivel retornar nada a panir de um m6todo com um tipo de retorno nio-void.

tr M6todos com um tipo de retorno que 6 uma referOncia a um objeto podem retornar um subtipo.
E M6todos com um tipo de retorno que 6 uma interface podem retornar qualquer implementador.

Construtores e Instanciamento (Objetivos 1.6 e 5.4)


E Nio se pode criar um objeto sem que seja chamado um constnrror.

E Toda superclasse da 6rvore de heranga de um objeto chamari um construtor.


E Toda classe, mesmo as classes abstract, tem pelo menos um construtor.
D Os construtores devem ter o mesmo nome da classe.
E Os constnrtores nio t6m um tipo de retorno. Se houuer,entio, seri simplesmente um m6todo com o mesmo nome
da classe e nio um construtor,
E A execugio do construtor ocorrer6 da maneira a seguir:

E O construtor chamari o construtor de sua superclasse, que chamar6 o construtor de sua superclasse, e assim por
diante, at6 alcangar o consrrutor de Objea.

E O construtor de Object seri executado, retornando em seguida ao construtor chamador, que ser6 processado at6 sua
-eqii6nCia
conclusio, e por sua vez retornar6 ao construtor que o chamou; dando prosseguimento a essa at6 a execugio
do construtorda instAncia que estiver sendo criada.

E Os construtores podem usar qualquer modificador de acesso (at6 mesmo private!).


E O compilador criar6 um co nfirutor padraose voc6 nio criar nenhum construtor em sua classe.
E O construt or padrdo 6 wconstrutor sem argumentos com uma chamada tamb6m sem argumentos a super ( ).

E A primeira instrugio de todo construtor deve ser uma chamada a thi s ( ) (um construtor sobrecarregado) ou
super ( ).
94 Copitulo 2: Orientogdo o obietos
tr O compilador adicionarS,umachamada a super ( ),a menos que voc€ i|tenhainserido uma chamada a
this( ) ouasuper( ).
D Os membros de instAncia s6 podem ser acessados dqoir de o construtor da superclasse ser executado'
E As classes abstract possuem constnrtores que sio chamados quando uma subclasse concreta 6 instanciada.

D As interfaces nio t6m constnrtores.


B superclasse nlo tiver um construtor sem arg'umentos, vocA_teri que criar um construtor e inserir uma
Se sua
chamada a super ( ) com argumentos que coiniidam com os do construtor da superclasse'
D Os construtores nunca sio herdados, portanto, nXo podem ser sobrescritos.
tr Um constnrtor s6 pode ser chamado diretamente por outro constnrtor (usando uma chamada a super ( ) ou
rhis ( )).
E Quest6es relacionadas com chamadas a this ( ):

tr 56 podem aparecer como a primeira instrugio de um construtor.


O A lista de argumentos determina que construtor sobrecarregado ser6 chamado.
B Os construtores podem chamar outros construtores que podem chamar-ainda ourros eassim por diante;
mas, cedo ou iarde, 6 melhor que un deles chame super ( ) ou a pilha excederi o limite.

O Chamadas a this ( ) e super ( ) ndo poden ficar no mesmo construtor. Voc6 pode ter um ou outro' mas
nunca os dois.

Est6ticos (Objetivo 1.3)


D Use m6todos static para implementar comportamentos que nio sejam afetados pelo estado de quaisquer
instincias.
E Use variiveis static i instAncia - s6 existiri uma
paraarmazonar dados que sejam especificos ) classe, em vez de
static.
c6pia de uma vari6vel
E Todos os membros static pertencem i classe, e nio a uma instAncia.
tr Um m6todo static nio pode acessar uma vari6vel de instincia diretamente.
E Use o operador ponto para acessar membros esteticos, mas lembre-se de que usar uma,variivel de refer6ncia
o op.t"dor na verdade 6 um truque sint6tico, e o compilador substituiri a variivel de referAncia pelo
"om
nome da classe, por exemplo:
d.doStuff O ;
se torna:
Dog.doStuff ( ) ;
E M6todos static nlo podem ser sobrescritos, mas podem ser redefinidos.

Acoplamento e Coesio (Objetivo 5.1)


D O acoplamento refere-se ao nivel em que uma classe conhece ou usa membros de uma outra classe.
fl O acoplamento fraco 6 o estado desejivel para classes bem encapsuladas, que minimizam as referAncias umas is outras e
limitam a extensio do uso da API.
E O acoplamento forte 6 o estado indesejivel de se ter classes que desobedecem is regras do acoplamento fraco.

D A coesio refere-se ao nivel em que uma classe tem um rinico e bem definido papel ou responsabilidade.

E A alta coesio 6o estado desej6vel de uma classe cujos membros dio suporte a um rinico e bem definido papel ou
responsabilidade.

D A baixa coesio 6 o estado indesejivel de uma classe cujos membros dlo suporte av6rios pap6is ou responsabilidades
nio-focados.

Teste individual
l. Quais afirmativas sio verdadeiras? (Marque todas as corretas)
A Os relacionamentos Tem-Um sempre dependem da heranga.
B. Os relacionamento Tem-Um sempre dependem das vari6veis de instAncias.
C. Os relacionamento Tem-Um sempre precisam de pelo menos dois tipos de clasess.
JAVA 5 95
D. Os relacionamento Tem-Um sempre dependem do polimorfismo.
E. Os relacionamento Tem-Um sempre t6m acoplamento forte.

2. Dado:
class Clidders {
public final void flipperO { System.out.println("Clidder"l; }

]
public class Clidlets extends Clidders {
public void flipperO {
System. out.println ( "Flip a Clidlet" ) ;
super. flipper O ;
]
public static void main(String [] args) {

new Clidlets O . flipper ( ) ;


]
]
Qual6 o resultado?
A Flip a Clidlet
B. rlip a Clidder
C rfip a Clidder
Flip a Clidlet
D. rrip a Clidlet
F] in a a] iAA6r

E. A compilagio falha

3. Dado:
public abstract interface Frobnicate { public void twiddle(String s); }

Quais classes slo corretas? (lvlarque todx as corretas)

A. public abstract class Frob implements Frobnicate {


public abstract void twiddle(String s) t ]
]

B. public abstract class Frob implements Frobnicate { }

C. public class Frob extends Frobnicate {


public void twiddle(Integer i) { }

D. public class Frob implements Frobnicate {

public void twiddle(rnteger j-) { }

E. public class Frob implements Frobnicate {


public void twj-dd1e(String i) { }
public void twiddl-e(Integer s) { }
96 Copitulo 2: Orientogoo o obietos

4. Dado:
class Top {
public Top(String s) { System.out.print("8"); }

pubfic class Bottom2 extends Top {


public Bottom2 (String s) { System.out.print("D") ; }

public static void main(String [] args) {


new Bottom2 ( "C" ) ;
System.out.println( " ") ;

]
Qual 6 o resultado?
A. eo
B. DB
C. eoc
D. DBC
E. A compilagio falha.

5. Selecione as duas afirmativas que melhor indiquem uma situagio com baixo
acoplamento. (Marque duas)
,4. Os atributos da classe sio todos privados.

B. A classe refere-se a um pequeno nfmero de outros objetos.


C O objeto cont6m apenas um pequeno nrimero de vari6veis.

D. O objeto 6 referido atrav6s de uma variivel an6nima, e nio diretamente.


E. Avari6veldereferAncia6declaradaparaumtipodeinterface,enioumaclasse.Aintertacef.orneceumpequenonimero
de m6todos.

E
F 14.
E
t
improvivel
I
que modificag6es feitas em uma classe vXo exigir modificag6es em outra.

6. Dado:
cfass Clidder {
private final- void flipperO { System.out.prj-ntln(..C1idder,'l; }

)
public class Clidlet extends Clidder {
public final void flipperO { System.out.println("C1idlet"); }
public static void main(String [] args) {
new Clidlet ( ) . flipper( ) ;
)

Qual6 o resultado?
,{. Clidlet
B. Clidder
C clidder
Clidlet
D. Clidlet
Clidder
E. AcompilaSofalha
JAVA 5 97
7. Usando os fragmentos abaixo, complete o seguinte c6digo de forma que ele com-
pile. ObseruagSo, talvez nio seja preciso preencher todos os espagos em branco.
C6digo:
class AgedP {

public AgedP(int x) {

]
i
public class Kinder extends AgedP {

public Kinder(int x) {

o;
j
)

Fragmentos: Use cada um dos seguintes fragmentos quantas vezes for preciso, ou deixe sem uso:

AgedP this
( ) t

8. Dado:
1. class Plant {
2. String getNameO { return "p1ant"; }

3. Plant getTlpeO { return this; }


4. )
5. cl-ass Fl-ower extends Plant i
6. // insira o c6digo agui

8. class Tulip extends Flower { }

Quais instrug6es, inseridas na linha 6, irio compilar? (Marque todas as corretas)

,{. Flower getTlpe| { return this; }


B. String getTlpeO { return "this"; }
C.Plant getTypeO { return this; }
D. tulip getTlpe0 { return new Tulip0; }

9. Dado:
1. class Zing {
2. protected Hmpf h;

^1 ^^^ rr'^^- --.f anr{c 7i nn I }


+^ t ufa-D vvuvP YJ---^-

E nl:cc umnf I )

Quais opg6es slo verdadeiras? (Marque todas as corretas)

A. Woop 6-umFlmpf etem-umZing.


B. zingr 6-umWoop etem-umHmpf.
C. Hmpf tem-umWoop eWoop 6-umZingr.
D. Woop tem-umFlmpf eWoop 6-umZing.
98 Copiiulo 2: Orientog6o o obletos
E. zing tem-umFlmpf eZing 6-umWoop.

10. Dado:
1. class Programmer {
2. Progranmer debugrO { return this; }
3. )
4. class SCJP extends Programmer {
5. // jtnsira o c6digo aqui
6. )
Qual op91o, inserida na linha 5, iri compilar? (Marque todas as corretas)
A. Programmer debug ( ) { return this,' }
B. SC.fP debugfo { return this; }
C.object debugr0 { return this; }
D. i-nt debug ( ) { return 1; }
E. int debug(int x) { return l-; }
F.Object debug(int x) { return this; }

I l. Dado:
class Uber {
staticinty=);
Uber(int x) { thiso; y = y * 2; }
Ubero { y++; i
)
class Minor extends Uber i
Minor0 { super(y) ; y = y + 3; }
public static void main(String [] arqs) {
na\^t Mi nnr 1\ .

System. out.println (y) ;

])
Qual6 o resultado?
4.6
8.7
c.8
D.9
E. A compilagio falha.
F. SerS langada uma exceglo.

12. Quais afirmativas sao verdadeiras? (Marque todas as corretas)


A A coesio 6o principio da programagio OO mais intimamente associado com o ato de esconder os detalhes da
implementa$o.
B. A coesio 6 o principio da programagio OO mais intimamente associado com o ato de certificar-se de que as classes s6
conhecerlo outras classes atrav6s da" suas APIs.
C A coesXo 6 o principio daprogramaglo OO mais intimamente associado com o ato de certificar-se de que a classe foi
elaborada com um rinico e bem-focado prop6sito.

D. A coesio 6 o principio daprogramagio OO mais intimamente associado com o ato de se permitir que um mesmo
objeto seja visto como tendo muitos tipos.
JAVA 5 99

13. Dado:
1. class DoS { }
2. cl-ass Beagle extends DoS { }
3.
4. class Kennel {
5. public static void main(String [] arfs) {
6. Beagrle b1 = new Beagle ( ) ;
7. Dog dogl = new DogO;
8. Dog dog2 = b1-;
9. // insira o c6digo aqui
10. ) )
Qual opgio, inserida na linha 9, ir6 compilar? (Marque todas as corretas)

A. Beagle b2 = (Beagle) dogl;


B. Beagle b3 = (Beagle) dog2;
C. Beagle b4 = dog2;
D. Nenhuma das instrug6es acima irl compilar.

14. Dado o seguinte c6digo,


l-. class X { void do1 O { } }
2. c]ass Y extends X { void do20 { } }
?

4. class Chrome {
5. public static void main(String [] args) {

6. X x1 = new XO;
7. X x2 = new yO;
8. Y yl = new YO;
9. // inslra o c6digo aqui
10. ) )
Qual opgXo, inserida na linha 9, ir6 compilar? (tr4arque todas as corretas)

A. x2.do2O;
B. (Y) x2.do2O;
C. ((Y)x2).do2O;
D. Nenhuma das instrug6es acima ir6 compilar.

Respostas
1 Best6correta.

A e D descrevem outros t6picos relativos ) programagXo OO. C est6 incorreta porque uma classe pode ter uma instAncia
de simesma. E estiincorretaporque, enquanto relacionamentostem-umpodemlevar aum acoplamento forte, nio 6
sempre que isso ocorre. (Objetivo 5.5)

2. E estir correta. M6todos f inal nio podem ser sobrescritos.


A, B, C e D estXo incorretas com base no exposto acima. (Objetivo 5.3)

3. B estl correta, uma classe abstract nio precisa implementar quaisquer m6todos de uma interface.

E esti correta, a classe implementa o m6todo da interface e, adicionalmente, sobrecarrega o m6todo


twiddle () .

A esti incorreta porque m6todos abstract nlo t6m corpo.


100 Copitulo 2: OrientoEdo o obietos
C estA incorreta porque as classes implementam interfaces, mas nio as estendem.

D est6 incorrera porque sobrecarregar um m6todo nio 6 o mesmo que o implementar. (Objetivo 5.4)

4. E est6 correta. A chama implicita a super ( ) no construtor de Bottom2 nlo pode ser satisfeita, porque nio hL
um constnrtor sem arg.rmentos em Top. lJm construtor padrlo, sem argumentos, 6 gerado pelo compilador
somente se a classe nio tiver nenhum construtor definido explicitamente.

A, B, C e D estio incorretas com base no exposto acima. (Objetivo 1.6)

5. E e F estio corretas. O fato de se ter acesso a um pequeno nrimero de m6todos implica um acoplamento
limitado. Se o acesso 6 feito atrav6s de uma referAnia do tipo interface, pode-se argumentar que existem ainda
menos oponunidades para o acoplamento , umavez que o pr6prio tipo da classe nio se encontra visivel. Dizer
que modificag6es em uma parte de um programa provavelmente nio causario conseqiiOncia em outra, 6
realmente a ess€ncia do acoplamento fraco. Nlo existem variiveis an6nimas. Referir-se apenas a um pequeno
nrimero de outros objetos poderia implicar um acoplamento fraco, mas se cada objeto tiver muitos m6todos, e
todos forem usados, entio o acoplam-nto seri forte. As vari6veis (atributos) de uma classe devem
normalmente ser private, mas isso descreve o encapsulamento e nXo o baixo acoplamento. E claro que um
bom encapsulamento tende a reduzir o acoplamento, como conseqii6ncia.

A, B, C e D estio incorretas com base na tese de doutorado acima. (Objetivo 5.1)

6. A esti correta. Embora um m6todo f inal nio possa ser sobrescritos, neste caso o m6todo 6 private, e,
portanto, escondido. O efeito 6 que um novo e acessivel m6todo f lipper 6 criado. Assim, nXo ocorre
polimorfismo neste exemplo; o m6todo chamado 6 simplesmente o da classe-child, e neo ocorre nenhum erro.

B, C, D e E estio incorretas com base no exposto acima. (Objetivo 5.3)

Como nio existe um tile descan6vel para avari|vel x e os par6nteses (no constnrtor Kinder) j6 estio no seu lugar e
estio vazios, nio 6 possivel criar uma chamada ao construtor da superclasse que usa um argumento. Poftanto, a
rinica possibilidade restante 6 criar uma chamada ao construtor sem argumentos da superclasse. Isso 6 feito assim:
super ( ) ;. A linha nio pode ser deixada em branco, uma vez que os par6nteses j6 estio no lugar. Al6m disso, uma
vez que o construtor da superclasse chamado 6 a verslo sem argumentos, esse construtor precisa ser criado. Ele
nio seri criado pelo compilador porque jl existe um outro construtor. (Objetivo 5.4)
A, C e D estio corretas. A e D sloexemplosde retornos covariantes, ouseja, Flower e Tulip sio ambos
subtipos de Plant.
B est6 incorreta, String nlo 6 um subtipo de Plant. (Objetivo 1.5)

9. D est6 correta, Woop herda um Hmpf de zing.


A, B, C e E estlo incorretas com base no exposto acima. (Objetivo 5.5)

l0.A,B,EeFestiocorretas.AeBsioexemplosdesobrescrigXo;especificamente,B6umexemplode
sobrescrigio usando-se um retorno covariante. E e F sio exemplos de sobrecarga.

C e D estio incorretas. Sio de sobrescrigio inv6lidas, porque os seus tipos de retorno sio incompativeis. E sio
sobrecargas invilidas porque os seus argumentos nio se modificaram. (Objetivo 5.4)

lL Dest6correta.OconstnrtordeMinorfazumacharnadaoplicitaaoconstrutorcomumargunentodelJber,quefazumadramada
enplicia(trLis) aoconstrutorsemargumentosdeubeqqueporsuavezincrementayedepoisretomaparaoconstrutorcomum
argurnentqoq'.ulmuhiplicay'r2edepoisretomaparaoconstrutordeMinor,queadicioru3 ay.

A, B, C, E e F estao incorretas com base no exposto acima. (Objetivo 1.5)

12. A resposta C est6correta.

A refere-se ao encapsulamento, B refere-se ao acoplamento e D refere-se ao polimorfismo. (Objetivo 5.1)

13. A e B estio corretas. Entretanto, no tempo de execugio, A langari uma ClasscastException porque dogl
refere-se a um objeto Dog, o qual nio necessariamente s ericapaz de realtzar tarefx deBeagle.

C e D estio incorretas com base no exposto acima (Objetivo 5.2).

14. C est6 correta. Para poder chamar o m6todo do2 de v, voc6 precisa converter x2 para que ele se torne do tipo Y. A
instrugio B parece ser uma conversio correta, mas, sem o segundo conjunto de pardnteses, o compiladorpensari que se
trata de uma instrugXo incompleta.

A, B e D estio incorretas com base no exposto acima. (Objetivo 5.2)


AtribuiE6es

Obiefivos pqrq q
certificqe6o
I Usor Membros de Closses
I Desenvolver C6digos Wropper e de
Autoboxing
I Determinor os Efeitos de se Possor
Vqri6veis o M6todos
r Reconhecer Quondo os Obietos se
Tornom Quolificodos ooro o Coleto
de Lixo
I Argumentos de linho de comondo
poro o m6todo Moin

t Exerc(cios r6pidos

P&R Teste individuol


102 Copftulo 3: AtribuiE6es

Pilha e Heap - Uma Revisio


Para maioria das pessoas, entender os fundamentos sobre a pilha e o heap facilita bastante a comPreensio de t6picos
a
como passage* d.
a o polimorfismo, threads, exceg6es e coleta de lixo. Nesta segio, nos limitaremos a uma
"rg.r*.ntos,esseJt6picos virias vezes ao longo do livro.
visio geral, mas expan&remos
No gerd, as objetos) dos programas emJava residem em um dos dois seguintes lugares
virias partes (m6todos, variiveis e
da riem6ria, a pilha ou o heap. Por agora, nos preocuparemos apenas com tr6s tipos de coisas: varilveis de instAncias,
vari6veis locais e objetos:
I As vari6veis de instAncias e os objetos residem no heap.
r Asvarilveislocaisresidem napilha.
Vejamos um programa emJava, e como os seus diversos pedagos sio criados e mapeados na pilha e no heap:

l-. class Collar { l


2.
3. class Dog {
4. Co11ar c; // vari6vel de instAncia
5. String name; / / vari6vel- de instAncia
6.
7. public static void main(String [] arss) {

B.
9. Dog d; / / vari1vel 1oca1: d
l-0. d = new DogO;
i-1. d.so(d);
1.2. ]
13. void go(Dog dog) { // vari6veL Local: dog
L4. c=newCollaro;
1-5 . dog. setName ( "Fido" ) ;
16. )
I7. void setName(String dogName) { / / variSvel local: dogrName
18. name = dogName;
19. / / faz mais coisas
20. )
21.. j
A Figura 3-1 mostra o estado da pilha e do heap depois que o programa atinge a linha 19. Em seguida, apresentamos
alguns pontos principais:

objeto String

Vari6veis de
instAncias
setName O dogName - name

go O dog
main ()

pbleto co11ar

Figuro 3-l Visto gero/ do pilho e do heop


JAVA 5 IO3
I LinhaT-main ( ) 6colocadonapilha.
r Linha 9 - a variivel de referAncia d 6 criada na pilha, mas ainda nio existe um objeto Dog.
r Linha 10 - um novo objeto oog 6 criado, e6 atribuido i variivel de referAncia d.
I Linha 1 1 - uma c6pia & vari6vel de referAncia d 6 passada para o m6todo go () .

r Linha 13 - o m6todo go ( ) 6 colocado na pilha, com o parimetro dog como umavariivel local.
r Linha 14 - um novo objeto co11ar 6 criado no heap, e atribuido ) vari6vel de instAncia de Dog.
r Linha17-setName() 6adicionadoipilha,comoparAmetrodogName comoasuavari6vellocal.
r Linha 18 - a variivel de instincia name agora tamb6m se re{ere ao objero String.
I Repare que duas vari6veis locais difermtesreferem-se ao mesmo objeto oo9r.

I Repare que uma vari6vel local e uma variivel de instAncia referem-se ambas ) mesma String aiko.
I Depois que a Linha 19 fnal:.aa, setName ( ) termina e 6 removido da pilha. Nesse ponto, avari6vel local dogName
tamb6m desaparece, embora o objeto String ao qual ela se referia ainda esteja no heap.

Obietivo poro o certificog6o

Literais, Atribuig6es e Variiveis (Objetivos 1.3 e 7.6 do Exame)


| .3 Desenuo/uer aldigo que dukre, inicialiry e use primitiuos, affaJg enums e objetos romo aaiiaeis static, de in$1ncias e locais. Ahm disn,
asar identifeadores udlidos para nonet de uariiueis.

7,6 Evreaer aidigo qw @kque coffetamente ot operadores @mpiados, incluindo os de atribaigdo (initados a =, *=, -=)...

Valores literais de todos os tipos primitivos


Um literal primitivo 6 simplesmente a representagio do c6digo-fonte dos tipos de dados primitivos - em outras palavras,
um inteiro, umnrlmero de ponto flutuante, umbooleano oucaractere quevoc0 digite enquanto escreveumc6digo. A
seguir, temos exemplos de literais primitivos:
-b' // char literal
42 // inE literal
false // booTean literal
2546789.343 // double literal

Literais inteiros
Hi tr6s maneiras de representar nrimeros inteiros na linguagemJava: decimal (base 10), octal (base 8) e hexadecimal (base
16). A maioria das perguntas do exame que envolve literais inteiros usa representag6es decimais, mas vale a pena estudar
para as poucas que usam a representagio octal ou hexadecimal. Mesmo com as chances de voc6 algum dia usara
representagXo octal no mundo real, sendo extraordinariamente pequeni$, elas foram incluidas no exame apenaspor
dversao.

Literais decimais Os inteiros decimais nio precisam de explicagio; voc6 os tem empregado desde a primeira s6rie escolar
ou at6 antes disso. Hi
chances de que os esteja usando, j6 que voc6 nio preenche seus cheques em notagio hexadecimal. (Se
exiuerfaqgndoisso, nlo se preocupe, h6 um grupo de Nerds An6nimos (NA) pronto para ajudar). Na linguagemJavao eles
sio representados da maneira tradicional, sem prefixo de nenhum tipo, como descrito a seguir:
int length = 343;
Literais octais Os inteiros octais usam somente digitos de 0 a7 .Emlava, o inteiro 6 representado na forma octal com a
inclusio de um zero na frente do nrimero. como vemos abaixo:
class Octal {
public static void main(String [] args) t
int six = 06i // Igual ao 6 decimal
int seven = 07; / / Igual ao 7 decimal
int eight = 010; // IguaI ao 8 decimal
int nine = 011; / / Igual- ao 9 decimal
104 Copftulo 3: Atribuigoes
System.out.println("Octa1 010 = " + eight);

Observe que quando passamos do sete e nio temos mais digitos para usar (s6 podemos usar os digitos de 0 a 7 nos
nrimeros octaii), voltamos ao ponto de partida,ewznro 6, adicionado ao inicio do nrimero. Voc6 pode ter at62t digitos
em um n6mero oaal, nio incluindo o zero inicial. Se executarmos o programa anterior, ele exibiri o seguinte:

Octal 010 = 8

Literais hexadecimais Os nrimeros hexadecim is (hexnaabreviatura) slo construidos com o uso de 16 simbolos
distintos. J6 que nunca foram inventados simbolos num6ricos unit6rios para os algarismos que vlo de 10 a L5, usamos
caracteres alfab6ticos para representar esses digitos. A contagem de 0 a 15 na representagio hexadecimal ficaria assim:

0L23456'789abcdef
A linguagemJava aceita letras mairisculas ou minrisculas para os digitos adicionais (um dos poucos momentos em que nXo
diferencia mairisculas de minusrohr!). Voc6 pode us ar fie 76 didtos em um ndmero hexadecimal, nlo incluindo o prefixo
Oxou a extensio do sufixo opcional I. que serlo explicados depois. Todas as atribuig6es hexadecimais a seguir sio vilidas:
class HexTest {
public static void main (String [] args) {
int x = 0X0001-;
int v = }xlfffffff;
in|' z = 0xDeadCafe;
System.out.println("x = " + x + + y + " z = " + z);
)

A execu$o de HexTest produziria a saida abaixo:


x = 1 y = 21,4'1483647 z = -559035650
Nio se deixe enganar por alterag6es nas letras maiusculas de um digito hexadecimal ou do 'x' que o preceder6. 'Tanto
OXCAFE quanto 0xcafe siov6lidos.
Todos esses literais inteiros (octal, decimal e hexadecimal) sio definidos como int por padrXo, mas tamb6m podem ser
especificados como long com a inclusio de um sufixo L ou 1 depois do nrimero:
long jo = 110599L;
long so = 0xFFFFI; // Observe a letra '1' minriscula
Literais de ponto flutuante
Os nrimeros de ponto flutuante slo definidos com um nimero, um simbolo decimal e os outros n{meros que
representam afra$o.

double d = 11301-874.9881-024:
No exemplo anterior, o nime ro I1,3QI87 4.9881024 6 o valor literal. Os literais de ponto flutuante sio definidos como
double (64 bits) por p adrio, ponanto, se vocA quiser atribuir um literal de ponto flutuante a.umavariSvel do tipo
f loat (32 bits), tenl que anexar o sufixo F ou f
ao nimero. Se nio o fizer, o compilador reclamar6 de uma possivel
falta de precisio, porque voc6 estari tentando inserir o nrtmero em um "contAiner" (potencialmente) menos preciso. O
sufixo F fornece uma maneira de voc6 informar ao compilador: "Ei, sei o que estou fazendo e correrei o risco, muito
obrigado".
float f = 23.467890; // zrro de compilador, possivel perda da precisdo
ffoat s = 49837849.029847F; // ox; possui o sufixo "F"
Opcionalmente, voc6 tamb6m pode anexar um D ou d a literais double, mas nio 6 necess6rio, pois esse 6 o
compoftamentopadrio.
double d = 110599.995011D; // opcional, n5o 6 obrigat6rio
double S = 987.89'7; // Ndo 6 um sufixo 'D', mas est6 OK, pois 6 um literal- double
Procure literais num6ricos que incluam umavirgula, por exemplo,
int x = 25,343; // Nd.o ser6 compilado por causa da virguJ-a
JAVA5 IO5
Literais booleanos
Os literais booleanos sio a representaglo do c6digo-fonte para valores boolean. Um valor boolean s6 pode ser
definido como true ou f alse. Embora em C (e algumas outras linguagens) seja comum o uso de nrimeros para
rePresentart.rue oufalse,isondofuncionaniemJaua.Novamente,repitacomigo,Javanio6C++".
boolean t = true; // V6l-ido
bool-ean f = 0; // Erro do compilador!
Procure perguntas que usem nrimeros onde os booleanos seriam obrigat6rios. Voc6pode veruma avaliagio de
instrugio i f que use um nimero, como na linha a seguir:
int x = 1; if (x) { } // Erro do compilador!
Literais de caracteres
O literal char 6 representado porum fnico caractere entre aspas simples.
char a = 'a';
char b = 'G';
VocA tamb6m pode digitar o valor Unicode do caractere, usando a notaglo Unicode que acrescenta o prefixo \u ao valor,
como vemos nessalinha:
char letterN = '\u004e'; // e letra 'N'
Lembre-se de que os caracteres, na verdade, slo simplesmente inteiros de 16 bits sem sinal. Isso significa que voc6 pode
atribuir um literal num6rico, contanto que ele esteja no intervalo de 16 bits sem sinal (65535 ou menor). Pbr exemplo, as
linhas a seguir sio todas vllidas:
chara=0x892; //literalhexadecimal
char b -- 982; // literal inteiro
char c = (char) 70000; // A conversS.o 6 necess6ria; 70000 est6 fora do intervalo char
char d = (char) -98; // Absurdo, mas v61ido
E as descritas abaixo nlo sio vilidas e produzirlo erros de compilador:
char e = -29; // Possivel perda de precisSo; precisa de uma conversSo
char f = 70000 // Possivel perda de precisSo; precisa de uma conversSo
VocA tamb6m pode usar um c6digo de escape se quiser representar um caractere que nio possa ser digitado como um literal,
incluindo os caracteres de alimentaglo de linha, nova linha, tabulagio horizontal, backspace e aspas simples e duplas.
char c = '\"'; // Aspas duplas
char d = '\n'; // Nova linha
Agora que voc6 est6 familiarizado com os tipos de dados primitivos e seus intervalos, precisa ser capaz de identificar o tipo
de dado apropriado a ser usado em uma situagio especifica. A seguir serio apresentados alguns exemplos de quantidades
no mundo real. Tente selecionar o tipo primitivo que melhor represente a quantidade.

Valores literais para strings


Um literal de strng| arepresentagio do c6digo-fonte para o valor de um objeto String. Por exemplo, abaixo vemos um
exemplo com duas maneiras de representar um literal de string:
Strinq s = "BrII Jov";
System.out.println( "8i11" + ",Joy") ;

Embora strings nio sejam primitivas, foram incluidas nesta segio porque podem ser representadas com valores literais
as -
em outras palav.ras, digitadat dnetanente no aidigo. O rinico outro tipo nio primitivo que possui uma representagio literal 6 o
array, que examinaremos mais adiante neste capinrlo.
Thread t = ??? / / qtal vafor literal poderia ir aquil

Operadores de atribuigio
Atribuir um valor a uma variivel parece bem simples; simplesmente insira o valor i direita do s tnd, : para atribuilo )
variivel que estar6 i esquerda. Bem, certo, mas nio espere ser avaliado com algo do tipo:
x=6;
NXo, voc6 nio ser6 avaliado com atribuig6e s que selarnfchinha (termo t6cnico). No entanto, ser6 avaliado em atribuig5es
mais ambiguas que envolvam conversio e express6es complexas. Examinaremos atribuig6es primitivas e de vari6veis de
106 Copftulo 3: AtribuiE6es
referAncia. Mas antes de comegarmos, retomaremos um pouco para examinar uma variAvel por dentro. O que i uma
variivel? Com o a uariiuel e setr uabrestio relacionados?
As vari6veis sio simplesmente dep6sitos de bits, com um tipo.designado. VocA podeter um dep6sito int, umdouble,
um Butron e at6 um-dep6sito Stiing [ ] . Dentro desse dip6sito, teriamos um conjunto de bits representan{o g v.alor.
Para tipos primitivos, o1 bits representam um valor num6rico (embora nio saibamos qual o formato desse padrio de bits
p"r" o tipo noolean, mas nlo achamos isso importante). Um tip o futte devalor igual a 6, por exemplo, significa que o
padrXo de bits davariivel (o dep6sito de tipos @t) 6 igual a 000001.1.0, representando os 8 bits.

Portanro, o valor de um avariLvelprinitiw6 evidente, mas o que estaria dentro de um dep6sito de objea? Sevoc|escrever:

Buttonb=newButtono;
o que estar6 dentro do dep6sitg Bgaon blseria,o.objeto Button? N;o/Uma vari6vel referenciando um objeto seria
exaramenre rs so - ono ,oidatl de refeftncia. O dep6sito de bits de uma vari6vel de refer6ncia cont6m bits que representam
uma maneira d.e acessar o objeto.Nio iabemos qual-6 o formato; a maneira pela qual as referAncias ao objeto sio armaz.enadas 6,
especifica de miquinas virtuais (6 um ponteiro para algt, apenas nio sabemos o que esse algo 6 realmente). Tudo que
podemosdizer,iomcerteza,6 que ovdordavari6velnio 6 o objeto, masemvezdisso, umvalorrepresentar'dov.ggQea
itoecifuo danentiria. Ou ovalornull. Se umvalor nio tiversido atribuido avariivel de referAncia ou tiver sido atribuido
expiicitamente um valor nu11, a vari6vel armazenarL bits que representario - voc6 adivinhou - o valor nul1. VocA pode
h
Button b = nu1l;
da seguinte forma: "A vari6vel Button / nio est6 referenciando nenhum objeto".
Portanto, agora que sabemos que um avar:iilel|, apenas um pequeno dep6sito de bits, podemos dar prosseguimento e
trabalhar com a altera$o desses bits. Examinaremos, primeiro, a atribuigXo de valores a tipos primitivos e terminaremos
com as atribuig6es avari6veis de refer6ncia.

Atribuig6es primitivas
O sinal de igualdade ( = ) 6 usado para a atribuSno de umvalor a uma variivel e foi chamado adequadament e de Eeradar dz
atribuigdo.Naverdade, h6 12 operadores de atribuigio, mas apenas os cinco mais freqiientemente usados caem no exame, e
eles serio abordados no Capitulo 4.

Vodpode atribuirumavarilvel primitivausando umvalorliteral ou o resultado deumaexpressio. Examine o c6digo a


segur:
int x = 7; / / aurflqrvqv
/ /
arri1-rrlinin I ifar-1
ffLE!4f

int y = x + 2; // atribuiqdo com uma expressao (incluindo um valor literal)


inL z = x * y; // atribuiqao com uma expressao
O mais imponante a lembrar 6 que um inteiro literal (como 7) 6 sempre implicitamente um tipo int. Se voltarmos ao
Capitulol,vocAlembrar6queotipoint 6umvalorde32bits.Niohaveriproblemasevoceestiveratribuindoumvalor
a uma vari6vel int. ou long, mas, e se estiver arribuindo a uma variivel uyte? Afinal, um dep6sito do tamanho do
tipo fote nlo pode armazenar tantos bits quanto um dep6sito com o tamanho do tipo int. Aqui, as coisas comegam a
ficar estranhas. O c6digo a seguir 6 v6lido,

byLe b = 27;
mas somente porque o compilador compafiaautomaticanenrao valor literal para o tamanho de um tipo byte. Em outras
palavras, o compilador executa a conuersdo. O c6digo anterior 6 id6ntico ao seguinte:

vrus
k,,F^ ! -- /L,-r^\
h
\!rus/ 27;
' // Converte explicitamente o valor literal inteiro para um tipo byte
Parece que o compiladorlhe deuumachance e permitiu quevod tomasse um atdho com atribuig6es avari6veis inteiras
menorel que um tipo int. (fudo que estamos dizendo sobre o tipo byte se aplica igualmente a char e short, ji
que os dois sio menores do que um tipo int). A prop6sito, ainda nio entramos realmente na parte estranha.

Sabemos que um inteiro literal 6 sempre um tipo int, mas o que 6 mais importante 6 que o resultado de uma expresseo
que envolva qualquer item do tamanho de um tipo int, ou menor, ser6 sempre um tipo int. Em outras palavras, some
dois tipos byce e vocd ter6 um tipo int
- mesmo se esses tipos byte forem muito pequenos. Multiplique um tipo
int por um shorte ter6 um tipo int. Divida um tipo short
por um byte e ter6... Um tipo Certo, agora int.
chegamos )pane estranha. Veja isto:

byte b = 3; // Semproblemas, 3 cabe em um byt.e


byte c = B; / / Sem problemas, 8 cabe em um byte
byted=b+ct / / xeo deveria ter problemas, a soma dos dols bytes
/ / cabe em um tipo de byte

Aultimalinha nio seri compilada!Voc6 veri o erro aseguir:


JAVA5 IO7
TestBytes.java:5: possible loss of precision
found : int
ramli rad. lrrrt-a

bytec="lo'

Tentamos atribuir a uma vari6vel do tipo byte a soma de dois @tes culo resultado (11) foi pequeno o suficiente para caber
em um tipo byte, mas o compilador nio aceitou. Ele conhece a regra aplicivel a express6es "int ou de tipos menores"
sempre resultando em um tipo int. A compilagio teria sido executada se tMssemos feito a conversio explicita:
byte c = (byte) (a + b) ;

Conversio de tipos primitivos


A nnuersdopermitirl que vocA transforme valor-es primitivos de um tipo em outro. Examinamos a converslo de tipos
primitivos anteriormente neste capinrlo, na seglo de atribuig6es, mas agora, a discutiremos com mais detalhes. A conversio
de objetos foi abordada no Capitulo 2.

As convers6es podemser implicitar ou explicitat.Uma conuersdo inpliatasignifica que.voc6 nio precisa escrever um c6digo para
elE a conversao ocorTera automatrcamente. I\onnalmente, unVI conversao lmplrclta ocorre quancto lazemos uma
transformagio que envolva anpl)agno.Em outras palavras, quando inserimos'um item menor (digamos, um tipo byte) em
umcontein-ermaior(comoumtipoint).Lembradaqueleserrosdecompilador"possintiloss of freci-'
sion" que vimos na secio de atribuiE6es? Eles ocorrem quando tentamos inserir um item maior (digamos, um tipo
long) emumcont6ineimenor (comoumtipo sho.rt). Atransformaglo "valormaioremumcontdinermenor"6
conhecida como compactaglo e requer uma c onversio.explhita,em que voc6 esari informando ao compilador que conhece o
perigo e aceita toda a r?:sponsabilidade. primeiro, exarunaremos uma conversio implicita:
int a = 100;
long b = a; / / Conversdo implicita, um valor int sempre cabe em um long
(Jma conversio explicitatem o formato a seguir:
float a = 100.001f;
int b = (int)a; // ConversSo explicita, um tipo de float pode perder informag6es como
um tipo de j-nt
Os valores inteiros podem ser atribuidos a uma variivel double sem a conversio explicita, porque qualquer valor inteiro
pode ser inserido ein um tipo double de 64 bits. A linha a seguir demonstra isso:
double d = 100L; // ConversSo implfcita
Na instrucio anterior. um tiDo double 6 inicializado com um valor do dpo lonq (como indicado pelo L depois do
valor num6rico). Nenhuma ionversio 6 necessiria nesse caso porque um tipo dgu5le po{e ar.mqzenir todas ai
informag6es que um tipo l ong poderia conter. Se, no entanio, q-uisermos atribuir um valor do tipo doubl e a um tipo
rntefo, estafemos tentancto uma conversao Por compactagao eo comPilactor sabera drsso:
^1 ^^^ r
UIdDD LqDLTITIJ
^-^Ll-^ \

public static void main(String [] argrs) {


int x = 395'7.229; // n5o 6 v61ido
)

]
Se tentarmos compilar o c6digo anterior, o erro a seguir ser6 produzido:
Sjavac Casting.java
Casting.java:3: Incompatible tlpe for declaration. Explicit cast
needed to convert doub]e to int.
int x = 3957.229; // nd.o 6 v51ido
1 error
No c6digo anterior, um valor de ponto flutuante este sendo atribuido a uma vari6vel inteira. Ji que um inteiro nio
consegri armazer,tar casas decimais, um erro ocorrer6. Para fazer isso ftmcionar, converterem6s o ndmero de ponto
ilutuante emum lntero:
class Casting i
public static voj-d main(String [] args) {
int x = (int)3957.229; // conversSo v5lida
System.out.println("int x = " + x);
108 Copftulo 3: AtribuiE6es
)

Quando voc6 converter um nrimero de ponto flutuante em um tipo inteiro, o valor perder6 todos os digitos depois do
- I ' r r r I r. a 1 . , ,l
POntOdecmal. A^ execugao do coctrgo antenor proctuara a sarch a seguf:
Bjava Casting
int x = 3957
Tamb6m podemos converter um tipo de nrimero maior, como long, em um menor, como b1te. Observe o c6digo abaixo:
nla<c l-acfina I

public static void maj-n(String [] arqs) {


long 1 = 56L;
byte b = (byte)1;
System.out.println("The byte is " + b);

O c6digo anterior seri compilado e executado adequadamente. Mas, o que aconteceria se o valor long fosse muor que t27
(o maior nrimero que um byte pode armazenar)? Alteremos o c6digo para descobrir:
ala<c l-acf ira I

public static void main(String [] args) {


long 1 = 130L;
byte b = (byte)1;
System.out.println("The byte is " + b);

]
O c6digo ser6 compilado adequadamente, e quando o executarmos, obteremos o resultado a seguir:
O; --.-
tJovd l
ud>Lf119
^-^r --

The byte is -126


Voc€ nio vera um erro de tempo de execugio, mesmo quando o valor que estiver sendo compactado for grande demais para
o tipo. Os bits ) esquerda do 8 inferior simplesmente... desaparecerlo. Como vimos na seglo de atribuig6es, se o bit da
extrema esquerda do tipo byte, por acaso , agora,for t, ele nio far|mais parce do vatorl emvezdisso se tornari o bit de
sinal do novo tipo byte.

Exercicio 3- |

Convertendo tipos primitivos


Crie um tipo de nrimero f loat de qualquer valor e atribua-o a um tipo short usando a converseo.

1. Declare umavariivel f loat: f loat f = 234 .56F;


2.Atribuaotipo float aumtiposhort: short s = (short) f;
Atribuindo nirmeros de ponto flutuante Os nrimeros de ponto flutuante apresentam um compoftamento de
atribuigio um pouco diferente dos tipos inteiros. Primeiro, voc€ precisa saber que todo lberal depontoflutuante d
implicitanenteantipodouble @abit)endoantipofloat.Portanto,oliteral 2.3,porexemplo,6consideradoumtipo
double. Se voc6 tentar atribuir um double a um f loat, o compilador saberi que nio h6 espago suficiente no
cont6iner do tipo float de 32 bits paraarmaenar aprecisXo do tipo double de 64 bits, e ele lhe informarl isso. O
c6digo a seguir parece adequado, mas nio ser6 compilado:
float f = 32.3;
VocApode achar que 32 .3 deveria caber satisfatoriamente emumavari6vel com o tamanho de um tipo f 1oat, mas o
compilador nio permitir6 isso. Para atribuir um literal de ponto flwuante a uma variivel f 1oat, voc6 precisa converter o
valor ou acrescentar um f ao final do literal. As atribuic6es abaixo serlo compiladas:
floatf= (f1oat) 32.3;
fl_oar g -- 32.3f ;
float h = 32.3F:
JAVAs 109
Atribuindo um literal que seia muito grende para avariivel Tamb6m veremos um erro do compilador se renrarmos
atribuir um valor literal que ele saiba que E muito grande para caber em uma va/riryel.
byte a = 1,28; // byte s6 pode armazenar at6 o nirmero \27
O c6digo anterior renrltard nesse effo:
llact- R\rl- aq i:rr: f : h^6ri
.. q. possroJ_e
1-.1 l aa-
^ -Loss or
^f preclsaon
Found : int
required: byte
byte a = t28;
Podemos corrigi-lo com uma conversio:

bvtea= (bYte) 128;


Mas entio qual seri o resultado? Quando vocA compactar um tipo primitivo, aJava simplesmente descartar6 os bits de
ordem superior que nio se enquadrarem. Em outras palavras, ele perder6todos os bits ) esquerda dos que voce estiver
conveftenoo.

Examinemos o que aconteceri no c6digo anterior. Nele, 128 6 o pa&io de bits 10000000. Esse pa&io usa exatamente 8
bits para representar o nfmero 128. Mas j6 que o literaJ,I2S 6umtipo int, na verdade, obteremos 32 bits, estando o
nrimero 128 nos 8 bits da extrema direita (ordem inferior). Portanto, 128 seria realmente igual a:
000000000000000000000000L0000000
Vocd tem nossa palavra; hL 32bits u.
Para compactar os 32 bits que representam o nrimero 128, a linguagemJava simplesmente elimina os 24 bits da esquerda
(ordem superior). Ficamos apenas com 10000000. Mas lembrese que um byte tem sinal e o bit da extrema esquerda
representa esse sinal (e nio pane do valor da vari6vel). Ponanto, terminamos com um ntimero negativo (o nrimero 1 que
usamos para representar llS,agorarrepresentao bit do sinal negativo). Nio se esquega: para descobrir ovalor de um
nrimero negativo usando a notagio biniria complementar, inverta todos os bits e, em seguida, adicione 1. Ao inverter os
oito zeros ficaremos com 011111 1 1 e adicionando L a esse resultado obteremos 10000000 ou novamente 128! E quando
aplicarmos o bit do sinal, terminaremos com -128.
VocA precisa usar uma conversio explicita para atribuir 128 a um tipo byte e a atribuigio resultar6 no valor -1.28. Uma
converseo nada mais 6 do que sua maneira de dizer ao compilador, "Confie em mim. Sou um profissional. Assumo total
responsabilidade por qualquer coisa estranha que possa vir a ocorrer quando esses bits superiores forem eliminados".

Isso nos leva aos operadores compostos de atribuigXo. O c6digo a seguir seri compilado,
byte b = 3;
// Sem problemas - adiciona 7 a b (o resultado 6 10)
e equivalente a:

byte b = 3;
b = (byte) (b + '1 l; / / Nd.o ser6 compilado sem a
// aantrers1o. iA en:e b + 7 resulta em um tioo int
O operador de atribuigio composto + = permitir6 que voc6 adicione o valor ) b, sem incluir uma conversio explicita. Na
: :
verdade, * =, - : r'r e / usario todos uma conversio implicita.

Atribuindo uma vari6vel primitiva a outra vari6vel primitiva Quando voc6 atribuir uma vari6vel primitiva aoutra, 0
conteildo da aari,iuel da direita seni copiado, por exemplo,
int a = 6;
intb=a;
O c6digo anterior pode ser lido como: "Atribui o padrio de bits do ntmero 6 I variivel int a. Em seguida, copia o
padrio de bits de a e insere a c6pia na variivel b.
Portanto, as duasvari6veis, agora, contem o padrio de bits do nrimero 6, mas nio apresentam outro relacionamento.
IJsamos a vari6vel , somente para copiar seu conterido. Nesse momento, as duas vari6veis possuem conteridos id6nticos
(emoutraspalavras,uakresid€nticos),massealterarmososconteidosdea oub,aoutravari6velnloser6afetada".
Examine o exemplo abaixo:
class Val-ueTest {
public static void main (String ll args) {
int a = 1-0; // Atribui-se um valor a a
I l0 Copfiulo 3: Atribuig6es
System.out.println("a = " + a);
intb=a;

System.out,println("a = " + a + "after change to b");

A saida desse programa serA:

tjava ValueTest
a=10
a = 1-0 after change to b
Observe que o valor de a permaneceu igual a 10. O ponto chave a lembrar 6 que mesmo depois que voc6 atribuir a a b, as
duas variiveis nio referenciario o mesmo local da mem6ria. As vari6veis a e b nio companilham apenas um valor; elas
t|m aipiasid|nricas.

Atribuig6es de vari6veis de refer6ncia


VocO pode atributum objeto rec6m-criado aumavariivel de refer€ncia de objeto da maneira abaixo:

Button b = new Button0;


A linha anterior executa tr6s operag6es essenciais:
I Cria uma vari6vel de refer6ncia chamada b, do tipo Button.
I Criaumnovo obieto Button namem6ria.
r Atribui o objeto zutcon rec6mcriado ) vaiivelde referlnciab
Voc6 tamb6m pode atribuir o valor nul1 a uma vari6vel de refer€ncia de objeto, o que significa simplesmente que a
vari6vel nio referenciar6 nenhum obieto:

Button c = null;
A linha anterior cria umespago para a vari 6vel de rcfer1neiaButton (o dep6sito de bits para um valor de refer6ncia) , mas nio
gera realmente um objeto Buuon.

Como discutimos no Capinrlo anterior, voc6 tamb6m pode usar uma vari6vel de referdncia para referenciar qualquer objeto
que seja uma zubclasse do tipo declarado para a vari6vel, como descrito a seguir:

public class Foo {


nrrlrlin
vglrfv
rzniA AnFnncfrrff
vveLBLL\/ /\ Ir

)
i
publj-c class Bar extends Foo i
public void doBarStuff O { }
]
)

class Test {
public static void main (string [] args) {
Foo reallyABar = new BarO; // V6lido, pois Bar 6 uma subclasse de Foo
Bar reallyAFoo = new FooO; / / Ndo 6 v6lido! Foo ndo 6 uma subclasse de Bar

A regra 6 que voc6 pode atribuir uma subclasse do tipo declarado, mas neo uma zuperclasse desse tipo. Lembrese de que
um objeto Bar , com cfrtez4pode fazer o mesmo que Foo, portanto, qualquer pessoa que tiver uma refer6ncia a Foo poder6
chamar m6todos Foo, mesmo se o objeto na verdade for um objeto Bar.
No c6digo anterior, vimos que Foo possui um m6todo doFooStuf (
f ) , que algu6m com uma refer6ncia a essa classe
poder6 tentar chamar. Se o objeto referenciado pela variivel Foo for realmente um objeto Foo, nXo haverl problemas. Mas
tamb6mniohaver6problemasseeleforumobjetoBar,jiqueBarherdouom6tododoFooStuff ( ).Voc6niopode
JAVA 5 'I1I

fazer isso funcionar de maneira inversa, no entanto. Se algu6m tiver uma refer6ncia aBar, poderi chamar
(
doBarStuf f ) , mas se o objeto referenciado na verdade for um objeto Foo, ele nio saber6 como responder.

Escopo Vari6vel
Depois que vod declarou e inicializou uma variivel, uma questlo naturd 6 "por qwmto tempo essa vari6vel vai existir?"
Essa_ 6 uma,pergunta que se refere ao escopo das vari6veis. E o escopo nXo 6 ipenas uma coisa imponante & se entender de

modo geral, mas ele tamb6m tem um papel imponante no exame. Comecemos examinando um arquivo de classe:
alaqc T.2\r^rrf I / / classe
stati-cints=343; // vari6vel est6tica
int x; // var!6ve1 de instAncia
{x=7;intx2=5;} // bLoco de inicializaqdo
Layouto { x += B; int x3 = 6;} // construtor
rrnid dnQFrr++l\ I // m6Lodo
inty=6; // vari6vel 1ocal
for(intz=0iz<4;z++li // bl-oco de c6digo 'for'
y+=z+x;
]
]
]
Como acontece com as vari6veis em todos os programas Java, as deste programa (s, x, x2, x3, y e z) t6m todas um
escoPo:

I s 6 umavariivelstatic.
I x 6umavariiveldeinstAncia.
I y 6 uma vari6vel local Qs vezes chamada de vari6vel "local de m6todo").
I z E.umavariiveldebloco.
I x2 |umavarilvel de bloco init, um tipo de variivel local.
I x3 6 uma variivel de construror, um tipo de vari6vel local.

Para o prop6sito de explicagio do escopo das vari6veis, podemos dizer que existem quatro escopos bisicos:
I Asvari6veisstatic t6moescopomaislongo;elassiocriadasquandoaclasse6carregada,eduramportodoo
tempo em que a classe permanecer carregada naJVM.
r As vari6veis de instAncia sio o segundo tipo mais longevo; elas sio criadas quando uma nova instAncia 6
criada, e existem at6 que a instAncia seja removida.
I As vari6veis locais v0m em seguida; elas existem durante todo o tempo em que o seu m6todo permanecer na pilha.
Como veremos em breve, no entanto, as variiveis locais podem estar vivas e ainda assim estar "fora de escopo".
I As vari6veis de bloco s6 existem durante o tempo em que o bloco de c6digo esti sendo executado.

Os erros de escopo t6m muitos tamanhos e formas. IJm engano comum acontece quando umavarihvel| sonbreadaedois
escopos interferem um com o outro. Veremos o sombreamento com detalhes daqui a dgumas p6ginas. A razio mais
comum Para acontecerem erros de escopo 6 quando vod tenta acessarumavariivel que nio est6no escopo. Vejamos tr6s
exemplos comuns desse tipo de erro:
r Tentaracessarumavari6veldeinstAnciaapartirdeumcontexto static (normalmenteapartirdemain () ).
class ScopeErrors {
i-nt x = 5;
public static void main(Stringll args) 1

x++, / / n5o compilar6, x 6 uma wari6.ve1 de .instAncia,

]
I Tentar acessar uma vari6vel local a partir de um m6todo aninhado.

Quando um m6todo, por exemplo go ( ) , chama outro m6todo, por exemplo so2 O, 9o2 ( ) nio ter6 acesso is
vari6veis locais de go ( ) . Enquanto so2 ( ) esr6 rodando, as vari6veis locaii de go O ainda estXo atiuar, mas estio fora
deescopo.Quando go2O f:urralua'.6removido&pilhaego () continuaasuaexecugio.Nesseponto,todasasvarilveis
I 12 Copitulo 3: AtribuiE6es

de go ( ) anteriormente declaradas estio de volta ao escopo. Por exemplo:


class ScopeErrors {
pubfic static void main(Strj-ng [] args) {

ScopeErrors s = new ScopeErrorsOi


s.go();
)
rrniA
wvls an/\
Yv \ / IL

int Y = 5'
902();
Y++ i // depois que go2O finaliza, y volta ao escopo
]
vvrv vv! \, L

y++; t/
/ / Ltav
^<^ LUrttIJf
^^-^il- Jqr ,,;'lnaal
y E rvuqt :
q nn/\
vv \ /

]
I Tentar usar uma vari6vel de bloco depois que o bloco de c6digo jA terminou de executar.

E bastaote co-n- declarar e usar uma variivel dentro de um bloco de c6digo, mas cuidado para neo tentar usar a vari6vel
depois que o bloco finalizou:

void so3 O {
for(int z=0; z<5; z++l {
boolean test = false;
if(z == 3) {
test = true;
break;
]
)
System. out.print (test ); // 'test' 6 uma ex-vari6vel,
t | ^1 ^ -=^ ^-.1 ^ts^ -,ila]-s. . .

]
Nos dois ultimos exemplos, o compilador dir6 algo como:
cannot find symbol
Essa 6 amaneira de o compilador dizer "aquela vari6vel que voce tentou usar? Bom, ela pode ter sido vllida no passado
remoto (por exemplo, urna linha de c6digo atris), mas estamos na era da Internet, baby, nio tenho nenhuma lembranga
dessavari6vel".

oBSERVAQ6ES pnne o E)GME


Tenba um caidado eEecial cum efflr de escEo de blocos de aidigo. Vocd podeni ai-los em swiLches, try- catctres, e em :.oops
for, do rwhife.

Usando uma vari6vel ou elemento de array que neo tenha sido


inicializado e atribuido
A linguagemJavanos fornece aop$o de inicializarumavari6veldeclarada oudeix6-lasem serinicializa<la. Quandotentarmos
usmalaiive[nloncialuadarpoderemos obterumcomportamento diferente dependendo dotrpo devariivel ou arraycom o
qual estivermos lidando (primitivos ou de objeto). O comportamjntg tamb6m depender6 d9 niyel (eryopo) no qual
estivermos declarando nossa variivel. Um a umhfunl de inrt4ncia6 declarada dentro da classe, por6m, fora de qualquer m6todo ou
con$ruror, en qtrxnotmauarititvl bca/6declaradadentro de um m6todo (ou na lista de argumentos do m6todo).
As vari6veis locais, )s vezes, sio chamadas de variiveis de pilha, tempor6rias, autom6ticas ou de m6todo, mas as regras
aplicadas a elas serio as mesmas, independente do nome dado. Embora possamos deixar umavari6vel local nXo inicializada,
o compilador reclamar6 se voc6 tentar usar uma vari6vel local antes de inicializ6la com um valor, como veremos em breve.
JAVA5 I13
Variiveis de instincia de tipo primitivo e de objeto
As umidueis de instdncia (tarnb|mchamadas de vari6veis membros) sio vari6veis definidas no nivel da classe. Isso significa que
a declaragio da variivel rrio 6feita dentro de um m6todo, construtor ou qualquer outro bloco incializador. As vari-6veis de
instAncia sio incializadas com um valor padrio sempre que uma nova instAniia 6 criada, embora possam receber um valor
explicito depois de os superconstrutorei do objeto ierem fin ahzado o seu trabalho. A Tabela 3-i lista os valores padrio para
os tipos primitivo e de objeto.

Vari6veis de instincia primitivas


No exemplo a seguir, ointeiro year 6 definido como um membro da classe, pois esti dentro das chaves iniciais dessa
classe e nio nas chaves de um m6todo:
public class BirthDate {
int year,' / / Yari6vel de instdncia
public staLic void main(String [] args) {
BirthDate bd = new BirthDate ( ) ;
bd. showYear O ;
)
public void showYearO {
System. out.println ( "The year is
]
)

Quando o programa for iniciado, atribuir6 o valor zero avari|vellear, o vaior padrXo para variiveis de instAncia primitivas
relacionadas a nfmeros.

Iobelo 3-l Vqlores podrdo de tipos primifivos e de refer6ncio

Tipo de variivel Valorpadrio

Vari6vel de refer6nciade obieto nu11 (nio faz refertncia anenhum objeto)


byte, short, int, long
float, double 0.0
boolean €-f
!4Abe ^^

char '\u0000'

AOTRABALHO
Voc6 deue inicialiqar todas as suat uariiueis, nesnl se estiuer atribaindo a elas o ualor padrdo. Sea cr6digo fcanl nais fricit de ser lido; os
pmgramadores qtre precisarem faryr a manutengdo en sea aidigo (dEois qae uoc6 ganbar na loteria e mudar para o Taiti)
fcardo gratos.

Vari6veis de instincia de refer6ncia a obietos


Quando comparadas com as vari6veis primitivas nio inicializadas,uvari|veis de referdncia de obieto nio inicializadas
representam uma hist6ria completamente diferente. Examinemos o c6digo abaixo:
public class Book {
private String title; / / vari6,ve1 de referGncia de instAncia
nrrtrl ic (t-rina nal-rFit- urs
l6/\ \ / II
Ysurf
return t.it1e;
1

public static void main(String [] args) {


Book b = new Booko;
System.out.println("The title is .. + b.getTitleO );
]
I I4 Copitulo 3: AtribuiE6es
Esse c6digo seri compilado adequadamente. Quando o executarmos, o resultado seri:
The title is nu1l
A variivel title nio foi explicitamente inicializada com a atribuigio de uma string, portanto, o valor da
variivel de instAncia ser6 nuII.
Lembre-se de que nu11 nio 6 o mesmo que uma stringvazia (""). IJm valor
nu1l significa que a variivel de referdncia nao foi atribuida a nenhum objeto da pilha. Sendo assim, a alteragio
abaixo no c6digo da classe Book apresentari problemast
public class Book {
private String title; / / vari6vel de refer6ncia de instAncia
public String getTitle ( { )

ratrrrn |. if16.

]
public static void main(String [] args) {
Bookb=neweook0;
String s = b.getTitle0; // Ser6 compilado e executado
String t = s.tolowercaseO; // Exceqdo de tempo de execuqSol
)

Quando tentarmos executar a classe Book, a JVM produzirS, o erro a seguir:


Exception in thread "main" java. lang.NullPointerException
at Book.main (Book. j avaz !2
Recebemos esse erro porque a variivel de referAncia nio esti apontando (referenciandg) para um objeto. Podemos
verificar se urn objeto foi irstanciado com o uso da palavrachave null, como o c6digo revisado abaixo demonstra:
public class Book {
private String title, / / vari6vel de refer6ncia de instAncia
public String getTitle( ) {
r6t-11rh t i t- l a '

)
public static void main(String [] args) {
Book b = new Booko;
String s = b.getTitle(l; // Ser6 compilado e executado
if (s != nu]I) {
String t = s.tolowercase0;
)

O c6digo anrerior verificou se o objeto referenciado pela variivel s nio 6 nulo antes de tentar us6Jo. Fique atento
p"r" ..i6rior do exame em que voc6 tenha q.te procrrrat no c6digo se a referAncia a um objeto possui.o valor
nul-1. No c6digo anterior, por exemplo, examinamos a declaraglo da variivel de instAncia title, vimos que nio
houve inicializigio explicita, confirmimos que avai|vel title recebeu o valor padrXo nu11 e, em seguida,
vimos que a vari6vel s tamb6m apresentari o valor nul-I. Lembre-se, o valor de r 6 um1 c6pia do de title
(como retomado pelo m6todo gretiitte ( )), portanto, se title for uma variivel de referdncia nulI, s tamMm ser5"

Vari6veis de instincia de array


O array 6 um objeto; portanto, uma vari6vel de instAncia de array que for declarada, mas nio explicitamente
inicializada,teri'o valor nu11, exatamente como qualquer outra variilelde instAncia de referAncia a objeto.
Por6m, se o array forinicializado, o que acontecer6 aos elementos contidos nele? Todos os elementos do array
receberio seus valores padrio - os mesmos valores padrio que os elementos desse tipo recebem quando sio
variiveis de instAncia. Conclusio: Os elementos do analt receberio iemPre sempre nnpre uakret padrdo, independente de onde o
pnlpio aral for dularado oa in$anciado.

Quando inicializarmos um array, os elementos de refer6ncia ao objeto serio iguais a nuI1, se nio forem
inicializados individualmente com valores. Se houver tipos primitivos em um array, eles receberio seus resPectivos
vdores padrio. Por exemplo, no o6digo abaixo, o array year ter6 1@ inteiros todos iguais a zero por padrio:
JAVA5 I15
public class BirthDays i
static int [] year = new int[100];
public static void main(String [] args)
f or ( int i.=0; j-<l-00 ; i++ )
Syst.em.out.println("year[" + i + "] = + rrarrIi]\.
' Jve+ L1J
'
I

Quando o c6digo anterior for executado, a saida indicari que todos os 100 inteiros do array sio iguais azero.

Tipos primitiyos e obietos locais (de pilha, autom6ticos)


As vari6veis locais sio definidas dentro de um m6todo, o que tamb6m inclui os parAmetros desse m6todo.

OBSERVAQ6ES pene O EJGME


'Automdtico" i apenas niltrr tennl para "aariduel local". Ndo :igntfca qrc um ualor d atribuido automaticanente a uaritluel automdtica! O
oposto 6 qae d uerdadeiro; um ualor deue rcr atribuido a uma uai&uel automitica no cddigo; do contnlrio, o conpilador reclamani.

Tipos primitivos locais


No simulador de viagem no tempo a seguir, o inteiro year 6 definido como uma vari6vel autom6tica, porque esr6 dentro
das chaves de um m6todo.
public class TimeTravel {
public static void maj-n(String [] args) t
int year = 2050;
System.out.println("The year is .' + year),.

)
As uaidueis kcais, incluindo w tipos prinitiuos, senprq nmprq sempre deuem rcr iniciali4adas antes de aocd tentar rcd-las (embora nXo
necessariamentenamesmalinhadec6digo).AlinguagemJavaniofome,aalsvariiveislocais,umvalorpadrio; wcdtenlque
infuiali4i-las explicianntecom um valor, como no exemplo anterior. Se tentar usar um tipo primitivo nlo inicializado em
seu c6digo, receber6 um erro do compilador:
public class TimeTravel {
public static void main(String [] args) {
int year; / / YariSvel local (declarada, mas nao utilizada)
System.out.println("The year is '* + year) i // E,rro de compilaqSo

)
A compila$o produziri a saida a seguir:
I j avac TimeTravel . java
TimeTravel.java:4: Variable year may not have been initialized.
System.out.println("The year is " + year);
l- error
Paracorrigir seu c6digo, precisamos fornecer um valor para o inteiro year. Neste exemplo atualizado, ele foi declarado em
uma linha separada, o que 6 perfeitamente vilido:
public class TimeTravel {
public static void main(String [] arqs) {
int year; / / DecLarada, mas n5o inicializada
int day; / / DecTarada, mas nio j-nicj-alizda
System. out . println ( "You step into the port.al . ,, ) ;
year - 2050; // Inieialj-zada (nm valor foi atribuido explicitamente)
1 16 Copitulo 3: AtribuiE6es
System.out.print.ln("Welcome to the year " + year);

]
Observe no exemplo anterior que declaramos um inteiro chamado day que nio 6 inicializado e mesmo assim o
c6digo foi compilado e executaao adequadam.nt.. E v6lido declarar uma variivel local sern inicializ|-la, contanto
que ela nlo seja usada, mas convenhamos, se voc6 a declarou, provavelmente tinha umarazaa para isso. (Embora
tenhamos ouvido falar de programadores que declaram variiveis locais aleatoriamente s6 por diversio, para ver se
elas conseguem descobrir como e porque estio sendo usadas).

AO TRABALHO
O compilador ndo podeni irforrnar sempre se uma uaiduel localfoi inidaliqada antes do uto. Por exempl0, n uoci inicialiqti-la dentro de um
bloco condicional ldgico (en outras palauras, am bloco de aidtgo que pode ndo ser executado, como o bloco de uma instrugdo if
, ou }oop
f or rcm un ualor literal true
ou f a l- s e como altematiua), o conpi/ador saberd que a inicialiTgjdo talueq nio ocorra e podeni produ{r
um effo. O cddigo a seguir deixani o compilador confuso:

public c]ass Testlocal {


public static void main(String [] args) {
l-nt x/'
if (arqs [0] l= nu11l { //suponhamos que voc) soubesse que este resuitado seja
<amore Erue
x ='J; / / o compilador ndo poderd informar se esta instrugdo ser1. executada
)
inf
LLLv ar
t --
v'
^t
// o compilador ter5 problemas agui

O cddigo antenorprodu{nl o ero abaixo, qaando uoc€ tentar compi/6-/o:

Testl,ocal.java:8: variable x might not have been initialized


Por causa do problena do conpilador ndo poder infomar com cerieqa, em algamat situagdes uoci ter,i que inicialiTar saa uaiduelfora do bloco
condiriona/, cpenat para deixar o conpilador satisfeito, Voci sabe porque isso d importante seji uiu o adesiuo de pdra-cboqae: "puando o

compilador n1o eshi mtisfeito, ninguin ufli".

Refer6ncias de Objetos locais


Tamb6m as referdncias dos objetos se compoftam de maneira diferente quando declaradas dentro de um m6todo em vez de
como var-i6veis de instAncia. Nas refer6ncias a objetos em variiveis de instAncia, voc6 pode ter bons resultados, deixando a
refer6ncianio ffigializada, contanto que o c6digoverifique realrnente se elanio 6 nul1antes deus6-la. Lembre-se de que
para o compilador, nu11 /um valor. Voc6 nlo pode usar o operadorponto emuma referAncia nu1l, porque-ni9 hquer,i
um objeto im sua outra extremidade, mas o*i n|trAocianuLl ndo i o mesmo que una referdncia ndo inicialiqada. ReferAncias
declaradas localmente n5o poderio apresentar bons resultados quando um valor nullfor procurado antes do uso, a menos
quevoc6 inicialize explicitamente avariivel local com nul1. O compilador reclamarido c6digo a seguir:
'i mnor1- i arza rrl- -i 1. . Date;
public class TimeTravel- {
public static void maj-n(String [] args) {

Date date;
iF (Aaf a == nrrl I I

System.out.println( "date is nu11" ) ;

]
A compila$o do c6digo resukarino erro abaixo:
B j avac TimeTravel . j ava
TimeTravel.java:5: Variable date may not have been initialized.
rf (date == nu11)
1 error
JAVA 5 117
As refer6ncias de vari6veis de instAncia recebem sempre um valor padrio igual a nu1l, at6 serem inicializadas
explicitamente- com outro valor. No entanto, as refer6ncias locais nio recebem um valor padrXo; em outras palavras,
ndo sdo nwII. Se voc6 nio inicializar uma vari6vel de refer6ncia local, enteo, por padrio,ieu valor ser6... Bem 6 ai que
-
est, todo o problema - ela nio teri absolutam ente nenham valor! Portanto, simplilcaremos a questeo: configure o
item incompleto com null explicitamente, at6 que esteja pronto para inicializi-lo com outro valor. A vaii6vel local
a seguir ser6 compilada apropriadamente:

Date date = nufl . / / canFi ^1,r^ avcficitamente a vari6vel de referancia 1oca1


// com nul-]"

Arrays locais
Exatamente como em qualquerorrtra refer6ncia aobjeto, deve-se atribuirumvaloris refer€ncias de arrays declandasdentro de
um m619d9 ante; que sejamusadas.Isso significa apenas que voc6 precisadeclarar e constnriro nio ser6
necessirio.inicializar explicitamente os elementos de um array.J6dissemos iso antes, mas 6 imponante "o"y.Irio.ntanto,
o srficiente para que
seja repetido: Elementos de arrE recebem seas ualorespadrio (0, fa1se, nu11, ' \u0000 '
e asimpordiante) indepentte;tu d0;ffq
-
terida &ckrarlo como umauaitluel local oa de instincia. O proprio objeto de affay, contudo, nio ser6 inicializado se for declarado
localmente. Em outras palavras, vod ter6 que irnci.altzar exphcitamente a referAncia a um array, se ela for declarada e usada dentro
de um m6todo, mas, no momento em que construir um objeto de array, todos os elementos receberio seus valores padrio.

Atribuindo uma variivel de refer6ncia a outra


Com relagio as vari6veis primitivas, aatribuigig de gma variivel a outra significa que o conterido (padr6es de bits) de uma
vari6vel seri copiado em outra variivel. As vari6veis de refer6ncia de objeto-funcionam ex"t"*.nte-cla m.sma maneira. O
conterido de uma vari6vel de referAncia 6 um pa&lo de bits, portanto, se voc6 atribuir a vari6vel de referAncia a ) variivel de
refer6ncia b, o padrlo de bits de a seri copiado e a nova c6pia seri inserida em b. Se atribuirmos a instAncia existente de um
objeto auma novavariivel de referOncia, entio, duasvari6veis de refer6nciaarmazenarioo mesmo padrio de bits -um
padrlo de bits referenciando um objeto especifico da mem6ria. Examine o c6digo a seguir:
i **^*!
rlrryvr u IJ4vq.
---- -- -- f)i mon<.i nn
dwL .

class ReferenceTest {
public static void main (String [] args) {
Dimension a = new Dimension(5,10);
SvStCm ottf nrinFlh/\\-
eJeuerlr.vqury!rlrurrr\ 1-'^i^Lf
q.rrsIVIIu \\ _,
+ a hoiahf
4.rrurVrrL/, \
--
Dimension b = a,-

vi4re+Y11u Jv,
-

Srrsl-cm 6ttf nr.irf'lh/\r-


uJuuerLLtvuu.y!frlLrrr\ L^.i-L+
a.rrcr9lrL tr +: hoinlrt
, q.rrsfvrrL r
-- I

"after change to b" ) ;

]
No exemplo anterior, um objeto Dimension a 6 declarado e inicializado com uma largura igual a 5 e altura igual a 10. A
seguir, o objeto Dimension b 6 declarado e o valor de a the 6 atribuido. Nesse momento, is duas vari6veiJ(a e n)
cont6m valores id6nticos, porqr,re o conterido d9 a foi copiado em b. Ainda hi apenas um objeto Dimension- aquele que
tanto a quantob estio referenciando. Para concluir, a propriedade de altura 6 alterada com o uso da referOncia a b. Agora,
Pense Por um minuto: Isso tamb6m irimudar apropriedade de altura de a? Vejamos qual ser6 o resultado:
Bjava ReferenceTest
a.height. = 10
a.height = 30 after change to b
Por essa saida, podemos concluir que as duas vari6veis referenciama mesmainstAncia do objeto Dimension.
Quando
fizemos a alteragio em b, a propriedade de altura tamb6m foi alterada em a
Encontramos uma exceglo ) maneira como as refer€ncias a objetos sXo atribuidas no objeto String. EmJava, esses objetos
recebem-tratamento especial. Em primeiro lugar, os o\etor.stringtdo inalteniueir,vocA nlo pode alter:ar o ,ralor de um objeto
String. Mas is so parece ser realmente possivel. Examine o c6digo a seguir:
class Strinqs {
public static void main(String [] args) {
String x = "\Tava"; ,// Atribui- valor a x
af ri
eulfrrv na
! - ^t // Agora, y e x referenciam o mesmo objeto String

Svstem orrf nri nl- l n 1"\/


\ J
qtri nn = \\ +' \/l
ru!+lry J I t'
-
'18
I Copftulo 3: AtribuiE6es
x = x + " Bean"i / Agora, o objeto foi alterado
/ com o uso da
/ /referlncia a x
System.out.println("y string = " + y);

)
VocA pode achar que o objeto String y
armaz.enar| os caracteres Java Bean depois que a variivel x for alterada, porque
as strings sXo objetos. Examinemos qual seri a saida:

9'i:rr: cf ri nft

Y Strr-ng = ,Java
Y string = ,Java
Como vocA pode ver, mesmo se y for uma vari6vel de refer6ncia ao mesmo objeto que x referencia, quando alterarmos x isso
nio dterari l Com qualquer outro tipo de objeto, onde dtras refer6ncias apontem para o mesmo objeto, se uma delas for
usada para aher6Jo, as duas saberio da aheragio, porque ainda haveri somente um obj eto. Mas sempre qnf4tmot alteraldes dc
qaaQaer tipo em urua String, o I,/M ataaliqani a uai,iuel d.e refer€nciaparafa(-k @ontarpara am objeto dtfermte. O objeto diterente
poderiserumnovo objeto ounio, masdefinitivamente serlumobjetodiferente. ArazAopelaqudniopodemos dizercom
ceneza se foi criado um novo objao reside no pool de corstantes Strings, que abordaremos no Capinrlo 6.

VocA precisa memorizar o que ocorre quando usamos umavari6vel de refer6ncia Stringpara aheraruma$ring:
r [Jma nova string 6 criada, deixando o objeto String original intocado.
I A referAncia usada para alterar o objeto String (ou em vez disso, para criar um novo objeto String pela alteragio de uma
c6pia do original) seri atribuida ao novo objeto String.

Poftanto, quando vod escrever,


1. Strind s = *Fred";
2. String t = s, // Agora, t e s referenciam o mesmo objeto String
3. t.touppercase0; / / Chama um m6todo String que altera o objeto String
na verdade, neo ter6 alterado o objeto String original criado na linha 1. Quando a execugio da linha 2 for conclui&' tanto t
quanto s referenciarXo o mesmo objeto Stiing. Mas quando a linha 3 for executadao em vez de alterar o objeto referengia{9
t
por (que 6 o rinico objeto String at6 esse mo-.trto),.tm novo objeto String seri criado. E, em seguida, abandol{tg Ji.
que o n&o objeto String nio 6 atribuido a uma variivel String, esse objeto rec6m-criado (que armazena a string "FRED") 6
eiquecido. Portanto, embora dois objetos String tenham sido criados no c6digo anterior, somente um ser6 realmente
referenciado e tanto t quanto s o referenciario. O comportamento das strings 6 extremamente importante no exame, de
modo que o abordaremos com muito mais detalhes no Capitulo 6.

Obietivo poro o Certificog6o

Passando variiveis para m6todos (Obietivo 7.3 do exame)


7.3 Detenninar o efeito nbre as refer€ncias dc olxos e sobre os ualoru pimitiuos quando eles sdo passados a mdtodot que realilam atribuipdes
oa niltras operagdu de nodtftagdo nos parimetros.

Os m6todos podem ser declarados para usar refer6ncias primitivas e/ou de objetos. Voc6 teri que saber como (o9 se) a
valiavel do chanadorpoderi ser afetada pelo m6to do chanadt. A drlerenga entre variiveis primitivas e de refer6ncia de obieto,
quando passadas para m6todos, 6 grande e importante. Para compreender esta segio, voc6 teri que estar familiaizado coma
segXo de atribuig6es abordada naprimeirapane deste capinrlo.

Passando variiveis de referGncia de objeto


Quando voc€ passar uma vari6vel de objeto para um m6todo, teri que se lembrar que estar6 passando a r{edncia ao objeto e
nio o pr6prio o@eto.I-embrese de que uma vari6vel de refer6ncia cont6m bits que representam (para o VM subjacente) uma
rn*rit" d. um objeto na mim6ria (no heap). O mais imponante que voc€ precisa lembrar 6 que nio estari
".essar
passando nem mesmo a variivel de refer6ncia real, mas, emvez disso, uma c6pia dos bits dessa vari|vel, P.ortanto'
qnando passar uma variivel de refer€ncia, estar6 passando wa alpia dos bits que representam como um objeto
eipecifico pode ser acessado. Em outras palavras, tanto o m6todo chamador quanto o chamado agora terio c6pias
id6nticas da refer6ncia e, portanto, referenciario exatamente o mesmo objeto (e nio uma c6pia) na mem6ria.

Nesse exemplo, usaremos a classe Dimension do pacote java.a:wt:


JAVA 5 I'I9
f . import java.awt. Dimension;
2. class ReferenceTest {
3. public static void main (String [] args) {
4. Di-mension d = new Dimension(5,10) ;
5, ReferenceTest. rt = new ReferenceTest ( ) ;
6. System.out.println("Before modifyO d.height = " + d.height);
7. rt.modify(d) ;
8. System.out.println("After modifyO d.height - " + d.height);
f. i
10. void modify(Dimension din) {
1-1. dim.height = dim.height + 1;
1,2. System.out.println("dim = " + dim.height) ;
l-3. )
14.j
Quando executarmos essa classe, poderemos ver que o m6todo modi fy ( ) realmenre conseguiu alterar o objeto
Dimension originat (e rinico) ciado nahrta4.
C:\ Java Pro j ec ts \Re f erence> j ava Ref erenceTes t
Raf^r6 mndi€rz/\ r{ haia}rf
srrlsrvrrL 1A
fv
\/ --

dim = 11

After modifyO d.height = 11

Observe que a paftir do momento em que o objeto Dimension da linha 4 for passado para o m6todo modi fy ( ) ,
qudquer alteragXo que ocorrer dentro do m6todo estari sendo feita no objao cuja refer6ncia foi passada. No exemplo
anterior, tanto a variivel de refer6ncia d quanto d.im apontam para o mesmo objeto.

A linguagem faya usa a semantica de passagem por valor?


Se alinguagemJavapassaobjetos usando avariivel de refer6ncia, isso significa queempregaaparsagempnrrcfefinciano que
da resryito a objetos? N5o exatamente, embora seja comum ouvirmos falar e vermos em livros que ela fazisso. Na
verdade, elapassanlpor aakr todas xvariiveis que forem executadas dentro do mesmo VM. Passar por valor significa passar
por valor da uai,luel. E isso quer di zer, pa$arpnr aipia da uaiiuel (eis apalavra "c6pia" novamente) !
Nio. faz diferenga se voce est6 passando vari6veis primitivas ou de refer6ncia, sempre estari passando uma c6pia dos bits da
vari6vel. Portanto, no que diz respeito a uma variivel primitiva, vocO estari passando uma c6pia dos bits qrr. i.pr.s.nt"m o
valor. Por exemplo, se vocd passar uma vari6vel int
de valor 3, estari passando um a adpia dosbitsque representam 3.
Assim, o m6todo chamado obteri sua propria c6pia do valor, para fazer com ela o que quiser.

E se voc6 estiver passando uma vari6vel de refer6ncia de objeto, estari pas sando wa aipiados bits que represenram a
refer6ncia a um objeto. Assim o m6todo chamado obter6 sua propria c6pia da variivel & refer6ncia e far6 com ela o que
quiser. Mas j6 que duas variiveis de refer6ncia id6nticas referenciam exatamente o mesmo objeto, se o m6todo chamado
dteraro objeto (chamando m6todos de configuragio, porexemplo), o chamadorperceber|,qteo o$eaque suavariivel
origind referenciou tamb6m ter6 sido aherado. Na pr6xima segfo, examinaremos iomo o cenirio se ahera quando falamos
sobre tipos primitivos.

A conclusio sobre a passagem por valor 6 a seguinte: o m6todo chamado nlo pode alterar a uairlaeldo chamador, embora
no que diz resp eito avariiveis de reter|ncia deobjeto, o m6to do chamado pdc aherar o objao que avari|velreferencia. Qual
a diferengaentre alterar
l variivel e alterar o objao? Quanto )s referAncias a objetos, significa que o m6todo chamado nio
pode reatribuir avariivel de referAncia original do chamador e fazer com que ela referencie um objeto diferente ou ovdor
nu1l. Porexemplo, no c6digo abaixo,
void bar( ) t
Foof=newFooO;
doStuff ( f) ;
)
void dostuff (Foo g) {
'120
Copfiulo 3: Atribuig6es

q.setName("Boo");
9 = new FooO;
)

reatribuir g nio reatribuir6 f ! Quando a execugeo do m6todo bar ( ) for concluida, dois objetos Foo terio sido
criados, um referenciado pela vari6vel local f e outro pela vari6vel local (vari6vel de argumento) 9r. J6 que o
m6todo doStuf f ( ) possui uma c6pia davari|vel de referAncia, tem uma maneira de acessar o ob)eto Foo
original,porexemplo parachamar om6todo setName ( ). Por6m, doStuf f ( ) ndotemc0m0acessarauariduelde
referlncia f. Assim,( ) pode alterar o que f estiverreferenciando, mas nio o conterido real (padrio de
doStuf f
bit$ deste. Em outras palavras, dostuf f ( ) pode modificar o estado do objeto a que f se refere, mas nio pode
fazer com que f se refta a um objeto diferente!

Passando vari6veis primitiyas


Examinemos o que acontece quando uma vari6vel primitiva 6 passada para um m6todo:

class ReferenceTest {
public static void maj-n (String [] args) {

int a = l-;
ReferenceTest rt = new ReferenceTest ( ) ;

System.out.println("Before modifyO a = " + a);


rF mnr{ i frz /\a);
r*..,.-*--f

System.out.printl-n("After modifyO a = " + a) ;


]
void modify(int number) {
number=number+1;
System.out.println("number * " + number);
r

Nesse programa simples, avariivel a


6 passada para um m6todo chamado modify ( ) , que a aumentari em
uma unidade. A saida resultante teri este formaro:
Refnremndifvll rllvgf !J \ , a=l
number = 2

Aftermodifvl) a=1
Observe que a nio se alterou depois que foi passada para o m6todo. Lembre-se de que somente uma alpia de a
foi m6todo. Quando uma vari6vel primitiva 6 passada para um m6todo, ela 6 pasadapor ualor, o que
passada para o
significa "passar por c6pia dos bits davari|vel,.

Na sala de aula
O mundo sombrio das variiveis
No momento em que vod pensou que havia decifrado tudo, viu um trecho de c6digo com variiveis que nlo estavam se componando da maneira
que, na sua opiniio, deveriam estar. VocA pode ter encgntradg c6digo variiveis sombreadas. E possivel sombrear uma variSvel de v6rias
-um .com
manerras; examinaremos apenas a que mais provavelmente the confundir6 - omltaruma uarihnl fu iutdncia sombreanda-a com ama uarirhnl locaL

O sombreamento envolve redeclarar uma vari6vel que j6 tenha sido declarada em algum outro local. O efeito do sombreamento 6 a ocuha$o
&variAveldeclaradaanteriormente, detalmodo quepossaparccerqlrevod estiusando avariiveloculta, mas o queestar6realmenteusando
ser| avai|vel de sombreamento. VocA pode encontrar raz6es para sombrear uma variAvel intencionalmente, mas normalmente
ocorre por acaso, causando erros dificeis de detectar. No exame, vocA pode esperar perguntas nas quais o sombreamento teri uma
panicipagio.
VocA pode sombrear uma variivel de instAncia declarando uma variivel local com o mesmo nome, diretamente ou como
parte de um argumento, como vemos abaixo:
class Foo {
JAVA 5 I2I
static int size = 7;
static void changelt(int size) {
size=size+200;
System.out.println(..size in changelt is .. + size);
)

public static void main (String [] args) {

Foo f = new FooO;


System.out.println("size - " + size);
changelt (size) ;

System.out.println("size after changeft is " + size);


)

)
O c6digo anterior parece alterar a variivel de instAncia size, no m6todo changert ( ) , mas ji que changert ( ) possui um
parimetro chamado s i z e, a variivel local s i z e ser6 alterada enquanto a vari6vel de instAncia a1e permaneieri intocada. A execu$o da classe
Fooexibirl
Sjava Foo

size = 7
size in chandcTr- is 207
size after changelt is 7
Tudo fica mais interessante quando a vari6vel sombreada 6a referOncia a um objeto, em vez de um tipo primitivo:

class Bar {
int barNum = 28;
]
class Foo {

Bar myBar = new Bar ( ) ;


void changelt(Bar myBar) {

myBar.barNum
= 99;
System.out.println("myBar.barNum in changelt is " + myBar.barNum);
myBar = new BarO;
myBar.barNum = 420;
System.out.println("myBar.barNrm in changelt is now " + myBar.barNum);
]

public static void main (String [] arqs) {


Foo f = new t'ooo;
System.out.println("f .myBar.barNum is " + f .myBar.barNum) ;

changelt (f.myBar) ;

System.out.println("myBar.barNum after changelt is " + f .myBar.barNum) ;

O c6digo anterior exibir6 isto:


f.myBar.barNum is 28
myBar.barNum in changelt is 99
122 Copftulo 3: AtribuiE6es

myBar.barNum in changelt is now 420


f.myBar.barNum after changelt is 99
Como voc€ pode ver, a variLvel de sombreamento (o parAmetro local myBar de changel t ( ) ) ainda po der5. afetar a variivel &
instAncia myear, porque o parlmetro myBar receberl uma refer6ncia ao mesmo objeto Bar. Por6m, quando ) vari6vel local myBar
for atribuido um novo objeto Bar, que em seguida modificaremos alterando seu valor barNum, avariivel de instAncia myear origi-
nal de Foo permanecerl intocada.

Al . ,.1.
\-/oleTrvo po ro o cenrTrcocoo
Declaragio, construsio e inicializagdo de arrays
(Objetivo I.3 do exame)
1.3 Desenuoluercddigo qae dulare, inicialiry e unpimitiuos, affEtq ertramt e obletos como aaidueis esfliticag de instincias e /orais.Akn
disso, usar ident'ficadores uilidos para nomes de aaridaeis.

EmJava, os arrays sio objetos que armazenam diversas variiveis do mesmo tipo. Eles podem conter variiveis de refer6ncia
primitivas ou de objeto, mas o array propriamente dito sempre ser6 um objeto da pilha, mesmo se for declarado para
armazenarelementos primitivos. Emoutraspalavras, nXo exise algo comoumarrayprimitivo,mxvoc|podccriarum array
de elementos primitivos. Para esse objetivo, vocd teri que conhecertr6s itens:

I Como criarumavariivel de nfunciade xray (declaraio)


r Como criar um ofrxo de array (consrugXo)
I Comoprymcheroarraycomelementos (inicializagXo)

H6v6rias maneiras diferentes de executar cadauma dessas tarefas e voc6 teri que conhecertodas para o exame.

AOTRABALHO
Ot aralt fio efcientes, mas na rzaioria das sitaagdu seri melhor uocd asar ilrt dos tipot Collection da claxe jaua.util (incluindo HathMap,
ArrEList e TreeSet). As classes de co@unto oferuem mandras maisflexiueis de acessar un o\eto (para insergdo, exclusdo, leitura e assim
por diante) e diferente dos an'a1s, poderdo rcr expandidat ou mnhaidas dinamieamente quando uocd adicionar ou remouer elementos (na
uerdade e/as s6o arrals gerencidueiq jd H,i am tipl Cnlkctinn para ama grand.e uariedade de neces$dades. Vocd
que os usam em sua estruturQ.
precisa de ama classficagdo nlpida? De un gwpo de objetos rcm repetigdu? Uma maneira de acersar um plr nomef ualor? Una lista
encadeada? O Capitalo 7 os abordani com mais detalhes.

Declarando um array
Os arrays sio declarados atrav6s da descriglo do tipo de elemento que armazenario, os quais podem ser um objeto ou um
tipo primitivo, seguido de colchetes ) esquerda ou direita do identificador.

Declarando um array de tipos primitivos


int[] key; // Colchetes anLes do nome (recomendado)
int key []; /,/ Colchet.es depois do nome (v61ido, mas menos legivel)
Declarando um array que referencie objetos

Threadl] threads; // Recomendado


Thread threads []; // v6Lido, mas menos legivel
Quando declanr avanivelde refer6ncia de um affry, insira sempre os colchetes do array imediammente ap6s o tipo
declarado, em vez de depois do identificador (nome da variivel). Dessa forma, qualquer pessoa que ler o c6digo pod."6
perceber que, por exemplo, key 6 uma variivel de referAncia do objao de array int e nio um tipo primitivo int.

Tamb6m podemos declarar arrays multidimensionais, que, na verdade, sio arrays com outros arrays
armazenados. Isso pode ser feito da maneira a seguir:

Stringtl tl tl occupantName,' // recomendado


String[] ManagerName []; // feio, mas v61ido
JAVAs I23
O primeiro.exemplo 6um_array tridimensional (um aray com outros arrays tamMm alrrrra?.Enrerrdo arrays) e o segundo 6
um-array bidime-rsional. Observe que no segtndo exemplo, temos um colchete antes do nome davariivei eum delois. Isso 6
perfeitamente v6lido para o compilador, o que prova mais vnavez que fipaque,t t,t/ida nao signfu que 6 eio.

Nunca 6 considerado vilido incluir o tamanho do array na declaraEio. Sim, sabemos que voc6 pode fazer isso em
algumas outras linguagens, e 6 por isso que poder6 se deparar com uma ou duas perguntas que incluam um c6digo
semelhante ao seguinte:

int[5] scores;
O c6digo anterior nio conseguir6 passar pelg compilador. Lcmbre-se de.que a JVM nio alocarS.espago at6 que
voc6 instancie realmente o objeto de array. E ai que o tamanho importari.

Construindo um array
Construir vm array significa criar o objeto de array na pilha (onde todos os objetos residem) - em outras palavras,
trarapalavra-chavenew comotipo doarray.Paracrnrumobjeto dearray,aJavateriquesaberquant;espago
alocar na pilha, ponanto, voc6 precisa especificar o tamanho do array na hora da const^glo. Esse tama.rho seri
igud a quantidade de elementos que o array armazenar|.

Construindo arrays unidimensionais


A maneira mais-simples de construir um array 6 usar a palavra-chave new seguida pelo tipo do array, com
colchetes. especi{icando quantos elementos desse tipo o array armazenarS.A seguiriemos um exemplo da
construgio de um array de tipo int:
int[] testscores; / / Declara o array de tipo int
testscores = new int[4]; //constr6i um array e o atribui a vari6vel testscores
O c6digo anterior insere um novo objeto na pilha - um objeto de array contendo quatro elementos - com cada
elemento contendo um tipo int de valor padrio igual a 0. Considere esse c6digo como se ele dissesse ao
comPjlaior: "Crie na pilha um objeto de array que armazenar6 quatro tipos inJ primitivos e atribua-o i vari|vel
de refer6ncia declarada anteriormente chamada Lestscore=. E ..tq.t".rt o fizer isso, aproveite paraconfigurar
cada elemento int com zero. Obrigado". (O compilador aprecia boas maneiras). A Figura 3-2 mostra como o
array testscores aparecer| na pilha, depois da construglo.

varidvel de
refer€ncia do
array int[ ]

FFT;T;I
0123
Valores

Indices

Figuro 3-2 - Um orroy unidimensiono/ no pilho


Voc6 tamb6m pode declarar e construir lma arc^y em uma instrugio como vemos abaixo:
int[] testscores = new int[4];
Essa instrugXo individual produz o mesmo resultado das duas instrug6es anteriores. os arrays de tipo de objeto
podem ser construidos da mesma maneira:
Thread[] threads = new Threadt5l;
O ponto chave a lembrar aqui 6 que - apesar da apar6ncia do c6digo - o constratorTbread ndo eshl sendo chanado. Nio
estamoscriandoumainstdnciadeThread,mas,emvezdisso,umrinico objetodearEThread.Depois&inclusXodas
instrug6es anteriores, aindanio haver6, realmente, objetos Thread!

oBSERVAQAO pene O EXAME


Contidere cuidadoumente qilantts objetos estardo napilha, dtpois que uma instrugdo ou bloco do aidigofor exuutado, No exame seri
esperado que uoci taiba, por exenpk, qae o aidigo anteriorpmduq@enas m objxo (o aral atribuido a uaiiuel de refer€ncia cbamada
124 Copitulo 3: AtribuiE6es
thread). O ilnico objeto referenciadopor threafu contim cinco uaridaeis de referinciaTbread, mas nenbum objetoTbreadfoi criado ou
atribaido a essas uaridueis de referincia.

Lembre-se de que os arrays devem senpreterum tamanho atribuido no momento em_que forem construidos. A
de array. Nunca 6
JVM precisa do tamanho a fim de alo."r o espago apropriado na pilha para o novo objeto
considerado vilido, por exemplo, fazer o seguinte:

int[] carlist = new int[]; // Ndo serii compilado, precisa de um tamanho

Portanto, nlo o faga, e se voce ver isso no teste, nio hesite em marcar a resPosta "A compilagio falhar| '

oBSERVAQAO pene O EXAME


Voc€ pode uer as palauras conslrair, criar e instanciar usadas alternadamente. Todas elas signficam: 'Un objeto rcrd construido e inseido na

pilha;'. Essas pilanas tanbdm inplicam qae 0 cunstrutor do objeto senl executado, como resultado d.o aidigo de nnstragdo/triaydo/
-instanciagdo.
itodeno, di7,er con cirteqa, ltor exenplo, qae qua/.quer aidigo que use a palawa-chaue r,ew (se for exuutado eon sucesso) fanl
com qae o construtor da classe e todot os clnstrxttores de saperr/asses sqiam exeratados.

Al6m de ser consrruido com new, os arrays tamb6m podem ser criados com o uso de um tipo de abreviatura na sintaxe que
gerari o array, ao mesmo tempo em que inicializari seus elementos com valores fornecidos no c6digo (e nlo com valores
iadrXo) Examinaremos isso com detalhes na segio sobre inicializagXo. Por enquanto, memorize que, Por causa desses
atalhos tra ritttaxe, os ob.ietos ainda poderio ser criados mesmo que voc6 nXo use ou veja a palavra-chave new.

Construindo arrays multidimensionais


fumbre,se de que os arrays multidimensionais sio simplesmente arrays com outros arrays. Portanto, um array
bidimensioni de tipo int, na verdade, seri um objeio com o tipo de array int (int I I ), em que cada elemento
desse array fari uma referAnci a a outro array int. A segunda dimensio arm azenerL ostipos primitivos int reais. O
c6digo a seguir declara e constr6i um array bidimensional de tipo int:

inttl[] ratings = new j-ntt3l tl;


Observe que apenas os primeiros colchetes possuem um tamanho. Isso 6 aceitivel em Java, i6 que a JVM precisa
saber somente o tamanho do obieto atribuido avariivel ratings.

objeto do array int[ ]

array 2-D int[ ][]


vari6vel de refer6ncia (do
array 2-D) de int[ ] [ ]

A figura demonstra o resultado do seguinte c6digo:


intt l[ ] rnyArray = new inti3lt 1;
rnyArraylO] = new intt2l;
myArray[0] [0] = 6;
myArray[0] t]-l = 7;
myArrayll] = new intt3l;
mYArraYlll I0l = 9;
rnyArray [1] l1l = 8;
mYArraY[1] [2] = 5;

A Figuro 3-3 mostro como um orroy int bidimensionol funciono no pilho.


JAVA 5 I25
Inicializando um array
lniciel i"x1' qn array significa inserir itens n ele. Os iterc (Srorque, sim, esse /um rermo t6cnico) do array sio seus elemenros,
osquaispoderioservaloresprimitivos(2,'x',fa1se eoutros)ouobjetoscitadospelasvariiveisderefer€niradoarray.
Se voc6 tiver um array de objetos (e nXo de tipos primitivos), na verdade , ele nilo armaTenar,ios objetos, exatamente como
nenhuma outra vari6vel que nio seja primitiva, nunca cont6m realmente o ofiea, mas, em vez disso, armazenavma r{er€ncia
a ele. Por6m, nos referimos a arrays como, por exemplo, "um array de cinco strinp", embora isso, na realidade, signifique,
"um array de crnco refer€nciat a objetos String". Portanto, a grande pergunta p"srJa ser s. essas refer6ncias estio riesm^o ou
nlo apontando (opa, issodJava, q-ueremos drzer refercnciando) pariobjetos Siring reais ou se sio simplesmente null.
Lembre-se de que uma referAncia ) qual nio tenha sido atribuido um objeto seri uma refer6ncia nuil. E se voc6 tentar
usar essa referOncia nu11, digamos, aplicando o operador ponto para chamar um m6todo com ela, receber6 a detestivel
exceglo Nu1 1 PointerExcept i on .

Os elementos individuais do array podem ser acessados com um ntmero de indice. O nrimero de indice sempre comega no
zero' Portanto' Para um array de dez objetos os nrtmeros de indice irio de 0 a 9. Suponha que cri6ssemos um .lrray com tr6s
Animais como descrito a seguir:

Animal [] pets = new Animal[3];


Temos_um objeto de array na pilha, com tr6s refer6ncias nu11 do tipo Animal, mas ainda nio temos nenhum objeto
Animal. A pr6xima etapaser6 criar alguns objetos Animal e atribuir a eles posig6es de indice no array relerenciado por
peES:
pets[0] = new Animalo;
Pets [1] = new animal ( ) ;
Pets [2] = new Animal O ;
Esse c6digo insere tr6s novos objetos Animal napilha e os atribui atrAs posig6es (elementos) de indice do arraypets.

OBSERVAQ6ESPARAOE)(AME
Procure aidigos qae tentem acetsar um indice de arralfora do intervalo. Por exerup/0, re am affal tiaer trls e/enentot, a tentatiua de acessar o
elemento pl knpani a excegdo ArraylndexOutOfBoundsExcept ion, pois em ltm affal de tu€s elementos, os ualores atllidos
para os indices serdo 0, I e 2, Voci tambin pode
uer a tentatiua de utiliqagdo de um nilmero negatiuo clmo am indice do anE. seguir, A
temos exenplot de tentatiuat ud/idas e inud/idas de acesso ao affaJ. Certfique-w de reconhecer quando elas causam exagdes de tempo de
exuagdo e ndo erms de nmpilador! puase todas as petgtlntas do exame listam tanto exngdu de tempo de execugdo quanto envs de
compilador como re spostas possiueis.

int[] x = new int[5];


x[4] = 2; / / OX, o riltimo elemento est6 no indice 4
x[5] = 3; // Exceqd.o de tempo de execuqSo. Nao h5. nenhum elemento no indice 5!

int [] z = new int[2];


int Y = -3'
zlyl = 4; / / ExceqSo de tempo de execugSo. y 6 um nfmero negativo
F las poden ser dfrceis de loca/iqar em um kop complexo, mas ese seri o momentr mais prouiuel em que suryirdo problemas con os indiees
dos anals de perguntas do exame.

Um array bidimensional (um array preenchido com outros arrays) pode ser inicializado da maneira a seguir:
inttl tl scores = new int[3] [];
/ / Declara e cria um array contendo tr6s refer6ncias a arravs int
scores[0] = new int[4];
/ / o primeiro elemento do array scores estii em um array int de quatro elementos int
scores[1] = new int[6];
/ / o segundo elemento do array scores est6 em um array int de seis elementos rnt
scores[2] = new int[1];
/ / o terceiro elemento do array scores est6 em um array int de um el-emento int
126 Copftulo 3: AtribuiE6es
Inicializando elementos em um loop
Os objetos de array possuem somente uma vari6vel priblica, length (tamanho), que {ornece a quantidade de
elementos do array.-Port"trto, o valor do riltimo indice 6 sempre uma unidade menor do.que essa variivel. Por
exemplo, se o tarnanho de um array for igual a 4, os valores dos indice irio de 0 a 3. Geralmente' vemos os
elementos do array incializados em um loop conforme descrito abaixo:
Dog[] myDogs = new Dogt6l; // cria um array de 6 referQncias a Dogi

for (int x = 0; x < myDoqs.length; x++) {


myDogslx] = new DogO; // aErlbui um novo elemento Dog a posigSo de indice x
)

A variivel length nos informa quantos elementos o array cont6m, mas n6o se esses elementos foram
inicializados. Como veremos no Cipitulo 5, a partir do Java 5 n6s poderiamos ter escrito o loop f or sem usar a
vari6vel length:
for(Dog d: myDogs)
d = newDog( );

Declarando, construindo e incializando em uma linha


VocA pode usar dois atalhos de sintaxe especificos de arrays tant o para ainciahza$o (atribuir valores especificos aos
elementos de um array) quanto para a construgio (instanciar o proprio objeto de array) em uma rinica instru$o. O primeiro
ser6 usado para declarar, criar e inicializar, usando uma instrugeo como a seguinte:
f. int x = 9;
2. ing[] dots = {6,x,8};
A linha2 do c6digo anterior executa qlrdro operag6es:
I Declara uma vari6vel de refer6ncia ao array int chamada dots.
I Cria um array int de tamanho igual a tr6s (tr6s elementos).
I Atribui aos elementos os valores 6,9 e 8.
I Atribui o novo objeto de array ) vari6vel de refer6ncia dots.
O tamanho (extensio do array) 6 determinado pela quantidade de itens separados por virgulas entre as chaves. O c6digo 6
funcionalmente equivalente ao mais longo descrito a seguir:
int[] dots;
dots = new int[3];
intx=9;
dots[0] = 6;
dots[1] = x;
dots[2] = B;
Issotraz apergunta: "Por que algu6musaria aformamais longa?" Uma razXo vem )mente. VocA pode nio saber- no
momeruo em q.r. .rr", o ,ir"y --os ,ralores que serlo atribuidos aos elementos. 56 esse atalho de array vale o prego deste
livro (bem, isso combinado com amaravilhosa apresentagio).
Com refer6ncias a objetos em vez de tipos primitivos, ele funcionar6 da mesma maneira:
Dog PUPPY = new Dog("Frodo");
Dog[] myDogs = {PuPtry, new Dog("Clover"), new oog("Aiko")};
O c6digo anterior cria o array Dog, referenciado pela variivel myDogts, com um tamanho de tr6s elementos. Ele atribui o
objeto Dog criado anteriormente (atribuido ) vari6vel de referAncia puppy) ao primeiro elemento do array e tamb6m cria
dois novoJobjetos Dog ("clover" e "Aiko") atribuindo as duas instAncias rec6m-criadas aos dois riltimos elementos
&variivel de referAnciaDog, do arraymyDogs. AFigura 34 mostrao resultado.
Vodtamb6mpode usarasintaxe de atalho com arrays mukidimensionais, como nalinhaabaixo:
inttl [] scores = {{5,2,4,1}, {9,2}, t3,4}};
O c6digo anterior cria um total de quatro objetos na pilha- Primeiro, um array contendo arrays int 6 construido (o
objao {ue ser6 atribuido ) variivel de refer€ncia scores). O array scores tem um tamanho igual a tr€s, derivado da
q"."tid.d" de itens (separados por virgula) entre as chaves externas. Cada um dos tr& elementos doarray scores 6 uma
v,iriivel que faz refeiOncia a um-array in{ portanto, os tr6s arrays int foram constnldos e atribuidos aos ffes elementos
do affay scores.
JAVA 5 I27

vori6vel de
re{er6ncio do orroy oog [ ]

A figuro demonstro o resuhodo do c6digo seguinfe:

Dog PtrBtrY = new Dog("Frodo');


OoSt I myDegs * ipuppy, nsw Dsq('Clover,lr rsr. Oog{'Aiko"}};
Quofro obielos s6o criodos:
1 objeto Dog referenciodo por puppy e por myDogs ( 0 )

i orroyde Dog [ ] re{erenciodo pornyDogs

2 obieios Dog re{erenciodos pormyDoss [1 ]e myDoss [ 2 ]


Figuro 3-4 - Declorqndo, construindo
e iniciqlizondo um arroy de obletos
O tamanho de cada um dos tr6s arrays int 6 derivado da quantidade de itens dentro das chaves internas
corresPondentes. Por exemplo, o primeiro array tem um tamanho igual a quatro, o segundo array 6 igual a dois e o
terceiro tamb6m 6 igual a dois. At6 agora, temos quatro objetos: um array contendo arrays int (cadi elemenro 6 uma
referAncia a umar:rey int) e tr6s arrays int (cada elemento dos tr& arrays int 6 um valor int). Para concluir, os tr6s
arrays int foram inicializados com os valores int reais das chaves internas. Portanto, o primeiro array int cont6m
os valores 5, 2 ,4 e7 . O c6drso a seguir mostra os valores de alguns dos elementos desse ariay bidimensional:

scores t}l / / um array de quatro ints


scores 1Ll / / Lrm array de 2 ints
scores t2l / / um array de 2 ints
scoresl0l t1l // o valor int igual a 2
scores t2l l1l / / o va]-or int igual a 4
AFigura3-5 mostrao resultadodadeclaragio, consruglo einicializagXo deum arraybidimensionalemumainstruso.

Construindo e inicializando um array an6nimo


O sggundo atalho 6 cham ado de aalao ac an'a1 andnimo epode ser usado para construir e inicializar um array e, em seguida,
atribui o arrayaumavari6veldeclarada anteriormente, que fagarefer6nciaaoutro aftay:
i nf I l l-6cl- q-^ra<
- --- -i,'
testscores = new int [ ] {4 ,7 ,2} ;

O c6digo anterior criouum array int com tr6s elementos, inicializou os tr6s com os valores 4, 7 e 2, e, em segu^ida,
atribuiu o novo array i variivel de refer6ncia testscore s do array int declarado anteriormente. Chamamos
essa operagio de criagio le array an6nimo, porque com essa sintaxe, voc€ nem mesmo precisa atribuir algum
valor ao novo array. Voc6 pode estar pensando, "Qual a vantagem do array, se ele nXo for atribuido a umivari6vel
de refer6ncia?" Ele pode_ser usado na criagio de um array just-in-tine a ser empregado, por exemplo, como
argumento de um m6todo que use lm arr^y como parAmetro. O c6digo abaiio demonstra um argumento de array
,u$-rn-ume:
public class Foof {
void takesAnArray(int [] someArray) {
/ / usa o array como pardmetro
)
public static void main (String [] args) {
128 Copftulo 3: Atribuig6es
Foof f = new Foof();
f . takesAnArray (new int [] {1 ,'7,8,2,5}); / / precisamos de um argumento aray

objeto Cat objeto Cat

objeto do array Cat objeto do array Cat

variivel de refer6ncia (do


array 2-D) de Cat[ ][] variivel de referGncia (do array 2-.
D) de cat[ ][

A figura demonstra o resultado do seguinte c6digo:


cat[ ][ ] myCats = {tnewCat("Fluffy"}, newcat('zeus")},
{new Cat("Bilbo"), new Cat("Legolas"), new Cat("BerE") }}
56o criados oito obietos:
I obieio orroy 2-D Cat t I t l
2 obietos orroy de Cat [ ]

5 obietos cat

Figuro 3-5 - Um orroy bidimensiono/ no pilho

OBSERVAQ6ESpeneoE)(AME
Itmbre-se de ndo especifcar am tarnanho quando usar a intaxe da criagdo de arral an6nimo. O tamanho d deiuado da quantidade de itens
(separadot por uiryu/a) existentes entre as cbauer. Preste bastante atengdo na intaxe de arals usada nas pergantar do exame (e bauer,i
ntuitas). Vocd pode aer xtrta czmo essa

nar^r f\lrioal-f ?l Inrr'l'l


trrufrr
naur
rlvvv nl-rian|-
vvJvvL\r, /l row Oh'iccl- {)}:

/| // '^x^ : --<r
Ltsv s I r^,
varauq; o tamanho nao deve ser especificado

Atribuig6es vilidas para os elementos do array


O que podemos iruerir em um array especifico? Voc6 teri que saber no exame que os arrays s6 podem ter um tipo declarado
(int t J , Dog [ ] , string [ ] e outros), mas isso nlo significa necessariamente que somente objetos ou tipos
primitivos podem ser atribuidos aos elementos do array. E a variivel de referAncia do array? Que tipo de objeto de array
pode ser atribuido ivariivel de refer6ncia especifica de um array? No exame, voce ter, que saber a respostaparatodas essas
perguntas. E, por coincid6ncia, iremos abordar esses mesmos t6picos nas seg6es seguintes. Preste atengeo.

Arrays de tipos primitivos


Os arrays primitivos aceitam qualquer valor que possa ser atribuido implicitamente ao tipo de array declarado. Por exemplo,
vm arlay inL armazenar6 qualquer valor que seja permitido para uma vari6vel int
de 32 bits. Portanto, o c6digo a seguir
6v61ido:

int[] weightlist = new int[5];


JAVA5 I29
byte b = 4;
char c = 'c';
short s = 7;
weightlisttOl = b' // OK, byte 6 menor do que int
weightlisttll = c' // OK, char 6 menor do que int
weightlist[2] = si // OK, short 6 menor do que int

Arrays de refer6ncia a objetos


Se o tipo declaradopuaoarray forumaclasse, voc6poder6inserirnele objetos de qualquersubclasse do tipo declarado. Por
exemplo, se Subaru for uma subclasse de Car, voc6 poderi inserir tanto objetos Subaru quanto objetos Car no array, como
vemos no exemplo abaixo:

class Car { }
class Subaru extends Car { }
class Ferrari extends Car { }

Car [] myCars = {new Subaru0, new CarO, new Ferrario};


E bom lembrar que os elementos do array Car nXo sio nada mais do que varilveis de refer6ncia Car. Portanto, qualquer item
que possa ser atribuido a uma variivel de refer6ncia Car poderi ser concedido de maneira v6lida a um elemento do array Car.

Se o array for declarado como um tipo de interface, seus elementos poderAo fazer refer|ncia a qualquer instAncia das classes
que implementem a interface declarada. O c6digo a seguir demonstra o uso de uma interface como tip o de auay:

interface Sporty {
void beSporty( );
]
class Ferrari extends Car implements Sporty {
nrrhlia rznid
v v+\4
l-raannrtrr/\
vvvyv! ef \ /
t

Zf i*pf"*.nt.a o m6todo sporty (esportivo) especificamente atrav6s de Ferrarj.


)

)
class RacingFlats extends AthleticShoe implements Sporty {
public void beSportyO {

U ) i*pf"*"nta o m6todo sporty atrav6s de Racingshoe (t6nis de corrida)


)

)
class GolfClub { }
class festsportyThings {
public static void main (String [] args) {
Sportyl] sportyThings = new Sporty [3];
sportyThinss[0] = new Ferrari); // OK, Ferrari implementa Sporty
sportyThings [1] = new Racingplats ( ) ;
/ / OIr., RacingFlats implementa Sporty
sportyThinSs[2] = new GolfClubO;
/ / I{Eo 6 v6l.ido; GolfClub (clube de golfe) ndo implementa Sporty
/ / Nao importa se as pessoas n5o me considerarem moderna por causa disso
I30 Copftulo 3: AtribuiE6es

A conclusio 6 a seguinte: qualquer objeto que passe no teste "E-MEMBRO" aplicado ao tiPo de array declarado
pode ser atribuido a um elemento desse array.

Atribuig6es de vari6veis de refer6ncia de a?rays unidimensionais


No exame, voc6 ter6 que reconhecer atribuig6es vilidas e invilidas de vari6veis de refer6ncia de arrays. Nio.
estarnos falando sobre vari6veis de refer6nciis dn array (em outras palavras, elementos do array), mas, em vez 4isso,
de refer6ncias ao objeto de array. Por exemplo, se vocA'declarar um array inL, avariivel de referAncia declarada
podeni ser reatribuida a qualquer array (de qualquer tamanho), mas ndo a um item que ndo seja um array inL,
inL
lnclusive valores Lembre-se de que todos os arrays sXo objetos, portanto, uma aaiduel de reueftncia de atral nio
int.
pode ser atribuida a um tipo primitivo int. O c6digo a seguir demonstra atribui$es vilidas e inv6lidas de arraln primitivos:
infIl <nlafc.

int[] dats = new int[4];


char[] letters = new char[5];
splats = dats; / / Ox, dats se refere a um array int
splats = letters; / / NAo ESTA coRRETo, letters se refere a um array char
E tentador presumir que j6 que uma variivel de tipo byte, short. ou char pode ser promovida e atribuida
explicitamente a um tipo int, um array de qualquer &sses tipos poderia ser atribuido alum array int. Voc€ nio po&.
fazer isso emJava, mas seria bem pr6prio deises elaboradores de exame maldosos e impiedosos (por6m, interessantes)
inserir perguntas ambiguas sobre atribuig6es de arrays no exame.
Os arrays que podem conter referdncias a objetos, e nio a tipos primitivos, nio slo tio restritivos. Da mesma forma que
voc6 pode inserir um objeto Honda em um array Car (porque Honda esten& a classe Car), pode atribuir um aray detipo
Hondaaumavariivel de refer€nciado array Carcomo descrito abaixo:
Car [ ] cars,.
Hondal] cuteCars = new Honda[S];
cars = cutecars; / / OK, poi-s Honda 6 um tipo de Car
Beerl] beers = new Beer [99];
cars = beers; // llAo nsrA conReTo. pois Beer nao 6 um tipo de Car
Apliqueotest.ti-l,tgUnnOparalhe ajudaradistinguiro que6vilidodo quenio 6. HondaII-MEMBROdo grupo Car,
portanto, um arrayHondapodeseratribuido aum array Car. A assertivaBeerE-MEMBRO do grupo Carnio est6correta;
Beer ndo estendea classe Car (para nio mencionar o fato de que nio tem sentido l6gico, a menos que voc6 j6 tenha bebido
bastante).

oBSERVAQoESPARAOE)(AME
Un anal Car nio pode ser atibuido ao anal Honda. Nem todo carro i da marca Honda,
Vocd ndo pode inuerter at atribai{6e! udlidas.
portanto, te uoc6 tiuesse an aral Honda, ele ndo comportaria o arral Car atribaido a aai,iael de refer1ncia Honda. Pens bem: am
dtclarado
anal Carpodeia conter ama referdncia a Fenari, e algudm qae achasse ter am arral de Hondas se depararia repentinamente com a Fenai.
L.cmbn+e qae o teste E-MEMBRO pode ser executado no nidigo, atrauds do operador instanceof .

A regras de atribui$o de arrays se aplicam tanto a interfaces quanto a classes. IJm array declarado como um tipo de interface
pode referenciar um array de qualquer tipo que implemente a interface. le mbrese de que qualquer objao de uma classe que
implemente uma interface especifica passari no teste E-MEMBRO (instanceof) dessa interface. Por exemplo, se Box
implementar Foldable, o c6digo a seguir ser6 v6lido:
Foldable [ ] foldingThings;
Box[] boxThings = new eox[3];
foldingThings = boxThings;
/ / oK, Box implementa Fo1dab1e, portanto. Box f-MeMeRo de Foldable

Atribuig6es de vari6veis de refer6ncia de arrays multidimensionais


Quando voc6 atribuir um array a uma vari6vel de refer€ncia de array declarada anteriormente, 0 affal teri que estar
na metma dimeudo da uaiduel de refeftncia a qual estiuer sendo atribuido. Por exemplo , um array bidimensional de arrays int
ndo pode ser atribuido a uma vari6vel de refer6ncia de um array inL comum, como vemos abaixo:

int[] blots;
inttl tl squeegees = new intt3l tl;
blots = squeegees; // NAo ti v:furoo, squeegees 6 um array bidimensional de arrays int
int[] bl-ocks = new int[6];
blots = blocks; / / OK, blocks 6 um array int
JAVA 5 I3I
Preste.atengao elpgcialmente nas atribuig6es de arrays envolvendo dimens6es dif".ente". VocA pode, por exernplo,
ser i.r.rdagado se 6.vilido atribuir um array int ao primeiro elemento de um array composro de arrays int, c&no
nas linhCI a seguir:

int[] tl books = new inr[3] [];


int[] numbers = new intt6l;
int aNumber = 'l i
books[0] = aNumber; //NA.o 6 vdlroo, espera-se um array r-nt. em vez de um valor int
books[0] = nunbers, //vALrDo, numbers 6 um array int
A Figura 3-6 mostra um exemplo de atribuig6es v6lidas e invilidas para refer6ncias a um array.

Blocos de Inicializageo
falamos sobre dois lugares de uma classe onde voc6 pode colocar c6digo que realize operag6es: m6todos e contrutores.
E
Os blocos de inicializagio.sio o terceiro lugar, em um programaJava, onde as operag6ei poi.- t.t r."lir*I"r. Os blocos de
y".ldrye.- t"fap quando aclasse€ garregadapeQprimelavez (umbloco deitticializ"gio esrfuico) ouquandouma
insdncia6 criada (um bloco de inicializagio de instAncia). Vejamoi um exemplot
class SmallInit {
sLatic int x;
int y;

\lari{vel de refer€ncia ao Afiay


Cat[ ]
A YariAvel de ref€rencia ao anay
SOMENTE pode se referir a um
a.ray Cat l-D

i Cat obj6to
cat obj€to cat
aluffy

-n o .loato uh a.r.y Cat t-D


r a 8m pdo- .. t.f.stE . u

Variavel de referencia ao
ArayCatllll2-D
A variavel d6 refer€ncia 2-D o .loato d. u dj.ro e .rr.y
SOMENTE pode s€ referir a cahtl Il2-D8mrbd...
um array Cat 2-O r.l.rlr I u E!.y Cat l-D

Figuro 3-6 AtribuigOes de oroys volidos e inv6lidos

Atribuig6es Inv6lidas de Refer6ncias de Arrays |


A mycats = myCats [0]; "*,r,
I

/ / Nd,o 6 possivel atribuir um array 1-D a uma I


refer6ncia a array 2-D I
B mycats = myCats [0] tOl ; | ----------*
v61.ido
// N5o 6 possivel atribuir um objeto ndo-array a I
uma refer6ncia a array 2-D
I
c mycats [1] = mycats [1] l2l; | ---"-"--'--">
/ / Nl,o 6 possivel atribuir um objeto ndo-array a I Inv6lido
uma refer€ncia a array 1-D
D myCats [0] [1] = morecats'
/ / N5o 6 possivel atribuir um objeto array a uma
refer6ncia n5o-array
// q€ats [0] [1] s6 pode se referir a um objeto Cat
132 Copitulo 3: AtribuiE6es
Como voc6 pode ver, blocos de inicializaglo 6 bem complexa. Eles nXo t6m nomes, nio usam-
a sintaxe dos
argumentos nada. Um bloco de inicializagdo esttitico ,6d^ oro ue7, quando a classe 6 carregada pela
. ,rio ,.iorrram
pr?meira vez. IJm bloco de inicializagio de instincia roda ti*pn qae ama noaa instdncia i criada.Lembra {..q}Tdo- ,
i"l"mos sobre a ordem em que o c6digo de cada construtor era executado? o c6digo de blocos de inicializaglo de
instincia roda logo depois da chamadia super ( ) em um construtor, ou seja, depois que todos os
superconstnrtores tenham rodado.
VocA pode ter muitos blocos de inicializagio em uma classe. E impottattte notar que' ao contr6rio de m6todos ou
apareceril em uma clarefaqd&rtofo. Quando chega a hora de os blocos
constnrtores , a ordem em qae 0s blocos de inicialiqagdo
de inicializa$o .*"..rt"r'"-, se uma classe iiver mais de um, eles roditao na ordem em que.aParecem no arquivo
da classe... Ern o,rtr", palavras, de cima para baixo. Com base nas regras que acabamos de discutir, voc6 consegue
determinar a saida do seguinte programa?
class rnit {
rnit(int x) { system.out'println("1-arg const"); }
InitO { System.out.println("no-arg const") ; }
static { System.out.println("1st static init"); }
{I Slzstem.orri-nri
efrullr!vuu.yt4.Ae+ nl- ln("1st insl-a.nce init"); }

{ System.out.println("2nd instance init"); }

Svst^* arrts nvj-r1-/""nd


staf ir: {t slpusrrrrvuu.y!rrru+rr\ 4rr Static init"); }

public statj-c void main(String [] args) {

new InitO;
new Init(7) t
]
]
Para descobrir a resposta, lembrese destas regras:

I Os blocos deiriciahzagiro rodam na ordem em que aParecem.

r Osblocosde'tncialuagXoest6ticosrodamumavez,quandoaclasre.6.carregadapelaprlmeiravez.
I Os blocos de inicializagio de instincias rodam sempre que uma instl.ncia de classe 6 criada.

I Os blocos de inicializagio de instAncias rodam depois da chamada que o construtor faz a super ( ) .

Com essas regras em mente, a seguinte sai da deverifazer sentido:

1st static init


2nd static init
1st instance init
2nd instance inic
nn-arff a6nql.

1st i-nstance init


2nd instance init
1-arg const
Como voc6 pode ver, os blocos de rnicia\izaglo de instAncias rodaram duas vezes. Esses tipos de blocos sio usados
como um lugar para se colocar c6digos que todos os constnrtores de uma classe devam compartilhar. Dessa
forma, o c6digo nio precisa ser duplicado em todos os construtores.
Finalmente, se voc0 cometer um erro no seu bloco de inicializagio estatico, a JVM pode langar um
Exc ept i onlnlnini ta1 i z at i onError. Veiamos um exemplo,
class hitError {
static int [] x = new i-nt[4];
static { xt4l = 5; } // indice de array inv6.1ido!
public static voj-d main(String [] args) { }
JAVA5 I33
J

que produz algo como:

Exception in thread *main" j ava. 1ang. Exceptionrnrnitial_izerError


Caused by: java. lang.ArraylndexOutOfBoundsException: 4
at InitError. <clinit> (Tnit.Error. iava: 3)

OBSERVAQ6ESpeneoEJ(AME
Porconuengdo, os b/ocos de inicialiqagdo nonzalmente aParecempertt do inicio do arquiuo da c/asre, en algum lugarpefto rlot construtores.
Entretanto, utamosfalandn do exame SCJP aqui. Itfdo se surpreenda se acharum bloco de inicialiqg4do esconditlointre alguns ndtodos,
di$argado de um en'o de nmpilapao prlnta para acontecer!

nl .r. ..f.
\,roleTtvo poro o cefitttcocoo
Usando classes wrapper (Obietivo 3.1 do exame)
J.IDesenuoluer aidigo que ase ar classes wr@perprinitiuas (tais como Boolean, Character, Doable, Integer, etc.), ef ou autoboxing e
unboxing. Discutir as dzferenpas entre as classes Sting, StingBuilder e StringBffin

As classes wrapper da API Java seryem a dois prop6sitos principais:


r Fornecer um mecanismo para "empacotar" valores primitivos em um objeto de modo que possam ser
incluidos em atividades reservadas a obietos, como ier adicionados a coniuntos on retornadbs de um m6todo
que tenha como valor de retorno um objeto. Observagio: com a adigio do autoboxing (e unboxing) emJava 5,
que veremos- daqui a algumas p6ginas, muitas das operag6es de wrapping que os programadores costumavam
fazer mantalmente agora sio feitas de forma autom6tica.
I Fornecer um conjunto de fung6es utilitirias para tipos primitivos. A maioria dessas fung6es esti relacionada
com v6rias convers6es: de-tipos primitivosem.objetbs Siring e vice-versa, de tipos primitivos e objetos String
para bases (ou radicais) diferentes - como binirias, octais e hexadecimais, e viie-virsa.

Uma vis6o geral das classes wrapper


Hi uma classe wrapper para cada tipo primitivo em Java. Por exemplo, a classe v/rapper para o tipo int 6
Integer, para f loat 6 Float, e assim por diante. I-,embre-s de qae o noie do tipoprinitiuo iinpisnente o iome em minrisculat
do wrapper, excetl para cbar, que passa a w Cbaracter, e inL, qae passa a ser Integer. A Tabela 3-2 lista as classes wrapper da
APIJava.

Criando obietos wrapper


No exame voc6 ter6 que saber as tr6s abordagens mais comuns para a criaglo de objetos wrapper. Algumas
abordagens usam a representagio em String de um tipo primitivo como argum.nto. Ar qrre .tram Strings lanEario
exceg6es NumberFormatException se a String fornecida nio puder ser converrida no ripo primitivo
apropriado. Por exemplo, "dois" nio pode ser convertido em "2". Os objetos wrapper sio inaltir6veis. lJma vez
que receberem um valor, ele nio poderi ser alterado. Falaremos mais sobre a imutabilidade dos wrappers quando
estivermos discutindo o boxing, daqui a algumas p6ginas.

Os construtores wrapper
Todas as classes wrapper exceto Character fornecem dois construtores: um que usa como argumento o tipo
primitivo que esta sendo criado e outro que usa uma representagio em String do tipo sendo Jonstruido. Pbr
exemplo,
i1
fntegfer = new Integer(42);
hteger i2 = new Integer (,.42,, 1 ;
ou
Fl-oat f1 new Float (3.IAf\ ;

E roaL 12 new Float ( "3 .14f" ) ;


134 Copitulo 3: AtribuiE6es
Tobelo 3-2 C/osses wrapper e os orgurnenios de seus conslrulores

Tipo primitivo Classe wrapper Argumentos do construtor

Boolean Boolean booleano ou String


Byte Byte byte ou String
Char Character char
Double Double doubleString ou

Float Float float ou String


Int Int.eger int ou String
Long Long long ou String
Short Short short ou String
A classe Character fornece s6 um construtor, que usa o tipo char como argumento. Por exemplo,
Character c1 = new Character('c');
Os construtores da classe wrapper Boolean usam um valor booleano true ou f a1se, ou uma String que nlo
diferenciamaiusculasdeminisculascomovalortrue oufalse.AntesdeJava5,umobjetoBooleanniopodiaser
booleano - por exemplo,
usado como expressio em um te$e

Boolean b = new Boolean("fa1se") ;


i f /h\
// ndo compila com Java 1.4 ou anterior
ApartirdeJava5,umobjeto Boo:.earropodcserusadoemumtestebooleano,porqueocompiladorir6,f.aznr
automaticamente o unboxing do objeto para um boolean. Iremos nos concentrar nas fun96es de autoboxing deJava 5
na pr6xima seglo - entio fique alena!

Os m6todos valueOf( )
Os dois (bem, geralmente dois) m6todos estiticos valueof ( ) fornecidos na maioria das classes wrapper lhe
proporcionario outra abordagem paraacriaglode objetos wrapper. Os dois m6todos usam uma Stringpara representar o
iipo apropriado de seu primeiro argumento, sendo que o segundo m6todo (quando fornecido) usa um argumento
a&cional, int radix, que indica em que base (como 6in6ria, octal ou hexadecimal) o primeiro argumento foi representado.
Por exemplo,
Integer i2 = Integer.valueOf("101011". 2); / / converte 1-0101-1 em 43 e
/ / atrlbui o val-or 43 ao
/ / nbi'ero
t I vv)Yvv Tnfcacr i2

Float f2 = Float.valueOf ("3. l-4f") ; // atribu:- 3.1-4 ao objeto Float f2

Usando os utilit6rios de converseo das classes wrapper


Com dissemos anteriormente, a segunda grande fungio de um wrapper 6 converter coisas. Os m6todos a seguir
sio os mais freqiientemente usados e mais proviveis de estar no exame.

m<Value( )
Quando voc6 precisar converter o valor de um objeto wrapper num6rico em um tipo primitivo, use um dos
muitos m6todos xxxValue ( ) . Todos os m6todos dessa familia sio m6todos sem argumentos. Como voc6 pode
ver na Tabela 3-3, existem 32 m6todos xxxValue ( ) . Cada uma das seis classes v/rapper num6ricas possui seis
m6todos, de modo que todos os objetos wrapper num6ricos podem ser conveftidos em qualquer tipo primitivo
num6rico. Por exemplo,
JAVAs 135
Integer i2 = new Integer(42); / / cria um novo objeto wrarx)er
byte b = i2.byteValue0; // conwerte o valor de i2's em um
/ / nrimi t- i rrn ].xrf a

short s = i2.shortValueo; / / vm outro m6todo xxxValue


/ /
/ ,
Aa
sv
Taraaar
4A4vvYe!

double d = i2.doubleVa1ueO; / / mais um m6todo xxxValue


/ / Aa 'rnranar

Float f2 = new Float(3.14f); / / cria objeto wrapper


um novo
short s = f2.shortvalue0t // converxe o valor de i2's em um
// primitivo short
System. out.println (s ) ; // o resultado 6 3 (truncado, nao
// arredondado)

Iobelo 3-3 M6todos wrapper comuns de conversdo

M6todo
s=static
n=excegeoNFE Boolean Byt€ Character Double Float Integer Iong Short

ByeVdue

doubleValue

FloatVdue

IntValue

IongVahre

ShortMue

ParseX:o<42

ParseX:o< 4z (com a base)

valueOf. s,n

valueOf s,n (com abase)

Tosfting

toStringi(primitivQ x
toString s (primitivo, base)

Resumindo, as assinaturas essengiais dos m6todos wrapper de conversio sio:


primitivexorValue$ -paraconverterumtilfrapperparaumprimitive
primitive parsdGo<(String) - para converter um String para um primitive
\(lrappervahrcOf(String) -paraconvefterumStringparaum\ilfrapper

pansexuO e valueOf( )
Os seis m6todos parsexxx ( ) (um de cada tipo wrapper num6rico) estio intimamente relacionados com o m6todo
va]ueof ( ) que existe em todas as classes wrapper num6ricas. Tanto parsexxx ( ) quanto valueof ( ) usam
uma String como argumento, langamuma excegio NuberFonnatException se o argumento Stringnio estiver no
formato apropriado e podem convener objetos String de diferentes bases (radicais), quando o tipo primitivo subjacente for
qualquer um dos quatro tipos inteiros (consulte a Tabela 3-3). A diferenga entre os dois m6todos 6 que:
I parseXxx( ) retornaotipoprimitivonomeado.
I ValueOf ( ) retorna um objeto wrapper rec6m<riado do tipo que chamou o m6todo.

Alguns exemplos desses m6todos em agio:


136 Copitulo 3: Atribuiqoes
double d4 = Double.parseDouble ("3.14") ; / / converte um Strinq em um primitivo
System.out.println("d4 = " + d4); // o resul_tado 6 "d4 = 3.14"
Double d5 = Double.valueOf ("3. 14" ) ; / / cria um objeto Double
System.out.println(d5 instanceof Double ) ; // o resultado 6
Os exemplos abaixo envolvem o uso da base como argumento (nesse caso, biniria):
long L2 = Long.parselong("101010", 2); / / S:uringbin6ria para um primitivo
System.out.println("L2 = " + L2) ; // o resultado 6 "L2 = 42'
Long L3 = Long.vafueOf("101010", 2t; // Strrng bin6ria para objeto Longl
System.out.println("L3 value = " + L3); // o reswLtado 6 "L3 value = 42"

toString( )
A classe Object, que 6 a classe primordial, o item superior, possui um m6todo toString ( ) . Como sabemos
que todas as outras classes Java sXo herdadas da classe Object, tamb6m sabemos que todas elas t6m um m6todo
toString( ). Oobjetivodom6todo toString( ) 6permitirquevoc6obtenhaalguma representagdosrgnficatiua
de determinado objeto. Por exemplo, se voce tiver um conjunto de v6rios tipos de objetos, poderi percorrA-lo e
exibir alguma forma de representagio significativa de cada objeto usando toString (
) , que com cefteza pode
ser encontrado em todas as classes. Discutiremos mais o m6todo toString (
) no capitulo sobre Conjuntos,
mas, por enquanto, enfocaremos como esse m6todo est6 relacionado com as classes wrapper que, como sabemos,
sio marcadas com f ina1. Todas as classes wrapper possuem a versio de uma in$6ncia de ) sem toString (
atgamentls e ndo-sLaLic. Esse m6todo retorna uma String com o valor do tipo primitivo encapsulado no objeto.
Por exemplo,
Double d = new Doubl-e("3.14");
System.out.println("d= " +d.tostring0 l; // o resuLtado6 "d= 3.14"
Todas as classes wrapper num6ricas fornecem um m6todo static toString ( ) sobrecarregado que usa o
tipo num6rico primitivo apropriado (oouble. toString ( ) usa um double, Long. toString ( ) usa um
long, e assim por diante) e, 6 claro, retorna uma String.
Stri-ng d = Double.toString(3.14) ; / / d = "3.t4"
Para concluir, as classes Integer e Long fornecem um terceiro m6todo toString ( ) . Ele 6 sLatic, seu
primeiro argumento 6 o tipo primitivo apropriado e o segundo 6.luma bas, O argumento da base informa ao
m6todo p^r^ peg r o primeiro argumento (que, por pa&io, estari na base 10 ou teri o radical 10) e convert6Jo
para a base fornecida, retornando, em seguida, o resultado como uma String. Por exemplo,

String s = "hex - "+ Long.toString(254,1,6); // s = r\hex = fe"

toXxString( ) (base bin6ria, hexadecimal e octal)


As classes wrapper Integer e Long permitem que voc6 converta para outras bases nrimeros que estiverem na base
1.0. Esses m6todos de conversio, toXxxString ( ) , usam um tipo int ou long e retornam uma
representagio em String do nrimero convertido, por exemplo,
String s3 = Integer. toHexstring(254) ; / / converLe 254 para hexa
system.out.println("254 in hex - " + s3); // o resultado 6 "254 in hex = fe"
String s4 = Long.tooctalstring(254); // converLe 254 para octal
System.out.println("254 in octal = "+ s4); // o resul-tado 6 "254 in octal = 376"
Estudar a Tabela 3-3 6. a melhor maneira de se preparar para esta segio do teste. Se voc6 conseguir entender bem as
diferengasentre xxxvalue( ),parseXxx( ) evalueOf ( ),devesesairbemnessapartedoexame.

Autoboxing
Introduzido emJava 5, este recurso 6 conhecido por vlrios nomes: autoboxing, auto-unboxing, boxing e unboxing.
IJsaremos os termos boxing ("encaixotar") e unboxing ('desencaixotar'). Boxing e unboxing tornam mais conveniente o
uso de classes wrapper. Antigamente, no mundo pr6-Java 5, se voc6 quisesse criar um w rapper, abriJo, usiJo e depois
fech6lo novamente, vocA poderia fazer algo como:
Integer Y = new Integer(5671; / / cria
int x = y.intValueO; / / abre
x++,' / / rrca aql-a
JAVA 5 I37
y = new fnteger(x),' / / fecha novamente
Svstem orrl- nrinf
vgu.yt4rrUJlr\f_ lnI"rr = " + it. / / exibe

Agora, com o novo e aprimorado lava 5, voc6 pode usar

Integer y = new Integer(557) ; / / cria


Y++ i // abre, incrementa,
// fecha novamente
System.out.printl-n("y = " + i); // exlbe
Ambos os exemplos produzem a saida:

Y=568
E sim, voc6 leu corretamente. O c6digo parece estar usando o operador de p6s-incremento em uma vari6vel de referdncia a
objeto! Mas isso 6 simplesmente uma conveniAncia. Nos bastidores, o compilador faz o unboxing e a reatribuigio para
voc6. Anteriormente, n6s mencionamos que os objetos wrapper sio imut6veis... Este exemplo parece contradizer isso.
y
Com certeza parece que o valor de mudou de 567 para 568. Mas o que realmente aconteceu foi que um segundo objeto
wrapper foi criado, e o seu valor foi definido como 568. Se pelo menos n6s pud6ssemos acessar aquele primeiro objeto
wrapper, poderiamos provar isso...

Vamos tentar o seguinte:


Integer Y = 567; / / cri-a um wrapper
T- |
rllLeljer ^-^e
^ -
y, / / atribui uma segunda vari5vel
/ / de refer6ncia AO wrapper

System. out.println (y==x) ; / / verifica se elas estao se


// referindo ao mesmo objeto
Y++ i // abre, usa, fecha novarnente
System.out.println(x + * " + y); // exibe os valores
System. out.println (y==x) ; // verifica se elas estao se
// refcri ndn : ntrietos diferentes
O que produz a saida:
Erue
567 568
false
Assim, nos bastidores, quando o compilador chegou i linha y++; ele teve de substitui-la por algo como isto:
int x2 = y.intValue0 ; / / abre
x2++; // usa
y = new Integer(x2); / / fecha novamente
Como suspeit6vamos, precisa haver uma chamada a new em algum lugar do c6digo.

Boxing, ==r€equalsQ
Acabamos de usar ::
parafaznr uma pequena exploragio dos wrappers. Vamos dar uma olhada com mais detalhes em
como os wrappers trabalham com : : , ! : e equal s O . Falaremos muito mais sobre o m6todo equal s O em
capitulos posteriores. Por agora, tudo o que temos de saber 6 que a intengio do m6todo equals ( ) 6 determinar se duas
instAncias de uma dada classe slo "significativamente equivalentes". Essa definigSo 6 subjetiva de prop6sito; fica a cargo do
criador da classe determinar o que significa "equivalente" para os objetos da classe em questio. Os desenvolvedores da API
decidiram que, para todas as classes wrapper, dois objetos sio iguais se forem do mesmo tipo e tiverem o mesmo valor.
Nio deve ser surpreen&nte que
Integer i1 = 1000;
Integler i2 = 1000;
if (i1 != i2) System.out.println("different objects") ;
if (i1. eguals (i2) ) System. out.println( "meaningfully egual" ) ;
138 Copfiulo 3: AtribuiE6es
Produza a saida:
different objects
meaningfully equal
SXo apenas dois objetos wrapper que, por acaso, tAm o mesmo valor. Pelo fato de eles terem o mesmo valor int, o
m6todo equals ( ) os consi&ra iomb sendo "significativamente equivalentes", e, portanto, retorna true. E quanto a
isoaqui:
Integer i3 = 10;
Integer i4 = L0;
if (i3 == i4) System.out.println("same object") ;
if (i3.equa1s (i4) ) System.out.print.ln( "meaningfullv equa1" ) ;
Este exemplo produz a saida:

sameobject
meaningfully equal
Ugh! O maodo equals ( ) parece estar funcionando, mas o que aconteceu com : : s : Por que razio : est6 nos
! ? !

diiendoqueil- ei2 sXoobjetosdiferentes,quando:: est6dizendoquei3 ei4 sioomesmoobjeto?Para. .


economizar mem6ria, duas instAncas dos seguintes objetos wrapper serio sempls : : quando os seus valores primitivos
foremo mesmo:
I Boolean
I Byte
r character de\u0000at6\u007f (7f 6I27 emdecimal)
I Short ernteger de-I28a&127

Onde Pode ser Usado o Boxing


Conforme discutimos anteriormente,6 bastantecomumusarv/rappers emcombinagio comconjuntos. Sempre que quiser
que o seu conjunto armazene objetos e primitivos, voc6 usar6 wrappers para tornar esses primitivos compativeis com os
cbnjunros. A regra geral 6 que boxinge unboxinqfuncionam em todos os lugares onde voc6 normalmente possausarum
primirivo ou um obJeto wrappect. L, segumte coogo demonstra algumas mineiras vilidas de se usar boxinf:
class UseBoxing {
public static void main(String [] args) {

UseBoxing u = new UseBoxingO ;


u.go(5);
]

boolean go(Integer i) { // encapsula o int que recebeu


Boolean ifSo = true; // encapsula o literal
Short s = 300; // encapsula o primitivo
if (ifso) t / / abrindo
System. out . println ( ++s ) ; / / abre, incrementa, encapsula novamente
i
return !ifSo; / / abre, reLorna o inverso

oBSERVAQoES pene O DC{ME


I-*mbre-se de qae as uaiiueis de refer€ncia wr@perpodem serrrwJ_l-,. Isso signfica que uoci precita tomar euidado com algum nidigo que
parega e$arrealiqando operagdu seguras conprinitiuos, nat queplssan lanprumaNullPointerException.'
class Boxing2 {
static Integer x;
JAVA5 I39
public static void main(String [] arqs) {
evves!! \^/ |

)
static void doStuff(int z) {
inX z2 = 5:
System.out.println(22 + zl ;
JJ

Ette aidigo conpila unproblemas, mat aJI/M knga umaNullPointerException quando tenta ehamardoSXuf f (?<),
Pzrqae x nio se refere a um oQeto Integec pnftantl, ndo hi nenbum ualor para abir.

Obietivo poro o CertificoE6o

Sobrecarregando (Objetivos 1.5 e 5.4 do Exame)


1,5 Dado um exemplo de aidtgo, deterwinar se um mitodo eshi sobresmuendo oa sobncamgando comtanente ouho mitodo, e identifcar
aalores de retomo udlidot (incluindo retnrnls coaaiades) para o mitodo en questdo.
5.4 Dado un ceniio, dueruolueraidigo que dulan ef or ebame mdtodat sobrescritos ou sobrecamgados...

Sobrecarregando da Maneira Dificil - Correspond€ncia de M6todos


Embora ji tenhamos abordado algumas regras para a sobrecarga de m6todos no Capitulo 2, neste capitulo n6s
adicioaaremos alguns itens ) nossa caixa & ferramentasJava. Nesta segio, daremos uma olhada em ti6s fatores que podem
difi cultar um pouco a sobrecarga:

r Ampliago
I Autoboxing
f Var-arp

Quando umaclassetem m6todos sobrecarregados, umadastarefas do compilador6 determinar qual m6todo usarsempre
que encontrarumachamadaao m6todo sobrecaregado. Vejamos umexemplo que nlo usanenhumrecurso novo deJava5:
class EasyOver {
static void go(int x) { System.out.print("int "); }
sLatic void go(long x) { System.out.print("1ong "); }
static void go(double x) { System.out.printl"double "); }
public static void main(String [] args) t
byte b = 5;
short s = 5;
long 1 = 5;
float f = 5.0f;

go (b) ;
go (s) ;

so (1) ;

go(f );

Que produz esta saida:


int int lonq double
140 Cop(tulo 3: Atribuig6es
Isso provavelmente nlo serl nenhuma surpresa; as chamadas que usam byte e os arguryentos shon sio
implicitamente ampliados para bater com a versio do m6todo go ( ) que usa um int. E claro que a chamada
.o* long usa a rierslo tong de go ( ) e, finalmente, a chamada que usa um f l-oat 6 convertida para bater
com o m6todo que usa um double.
Em qualquer caso, quando uma correspond6ncia exata nio puder se encontrada, a JVM usa o m6todo com o
menor argumento que seja mais amplo do que o parAmetro.
VocA pode verificar que, se houver apenas uma versio do m6todo go ( ) , e ele usar um double, essa versio se r|usaAapara
todas as quatro chamadas a go ( ) .

Sobrecarga com Boxing e Var-args


Vamos agora volar ao nosso exemplo anterior e adicion ar boxinga elel.

class AddBoxing {
static void gro(Integer x) { System.out.println("Integer"); }

static void go(1ong x) { System.out.println("1ong"); }

public static void main(String [] args) {

int i = 5;
9o (i) ; / / q)al go O ser6 chamado?
]
]
Como vimos anteriormente, se a tnica versio de go ( ) fosse a que usa um Integer, o recurso de boxing de Java 5
permitiria que go ( ) fosse chamado com sucesso. Da mesma forma, se apenas a verseo long existisse, o comPilador a
usaria para lidar com a cham adaago ( ) . A questXo 6, dado que ambos os m6todos existem, qual deles ser6 usado? Em
outras palavras, seri que o compilador pensa que ampliar um parAmetro primitivo 6 melhor do que realizar uma operaEio
de autoboxing? A resposta 6 que o compila dor preferirlaampliagio, entio a saida seri:

long
Os elaboradores deJava 5 decidiram que a regra mais imponante deveria ser que os c6digos pr6existentes devem continuar
funcionando como antes, entio, uma vez que o recurso de ampliagio j6 existia, um m6todo chamado por meio da
ampliaglo n5o deveria ser trocado por um m 6todo rec6m-criado que depende do boxing. Com base nessa regra, tente prever
a saida do seguinte c6digo:

class Addvarargs {
static void go(int x, int y) { System.out.println("int,int");}
static void go(byte... x) { System.out.println("byte... "); }

public static void main(String[] args) {


byte b = 5;
qo{b,b); // qual go0 ser5 chamado?

Como voc6 provavelmente adivinhou, a saida 6

int, int
Porque, mais uma vez, mesmo que cada chamada requeira algum tipo de conversio, o compilador escolher6 o estilo antigo
em vez do estilo novo, mantendo os c6digos existentes mais robustos. At6 aqui, vimos que:
r A ampliagio 6 preferida em vez do boxing
r A ampliagio 6 preferida em vez dos var-args
Neste ponto, as mentes curiosas querem saber: o boxing 6 preferido em relaglo aos var-args?
class BoxOrVararg {
static void gro (Byte x, Byte y)
{ System.out.println("Byte, Byte") ; }
static void go(byte... x) { System.out.println("byte... "); }
JAVA 5 I4I

public static void main(StrinS [] args) {


byte b = 5;
qo (b, b) ; // qoaT go$ ser6 chamado?
)

E a saida 6

Byte, Byte
IJma boa maneira de memori zar essa regra t.perceber que o m6todo var-args 6 mais "solto" que o outro m6todo, no
sentido de que ele pode lidar com chamadas contendo qualquer nrimero de parAmetros int. Um m6todo var-args funciona
mais como um m6todo de captura total, em termos & quais chamadas ele pode lidar; e, como veremos no Capitul o 5,faz
mais sentido que recursos de captura total sejam usados c omo vm illtimo recurso.

Ampliando Vari6veis de Refer6ncia


Ji vimos que 6 vilido ampliar um primitivo. E possivel ampliar uma variivel de refer6ncia e, em caso positivo, o que isso
significaria? Voltemos o nosso raciocinio para a nossa atribuigio polim6rfica favorita:
Animal_ a = new DogO;
Mantendo esse mesmo raciocinio, uma chamada poderia ser:

cl-ass enimal {statj-c void eatO { } i


class Dog3 extends Animal {
public static void main(String[] args) i
Dog3d=newooq3o;
d.so(d); // Lsso 6v61ido?
)
void go(Animal a) { }

Sem problemas! O m6todo go ( ) precisa de um Animal, e Dog3 f-UM Rni*al. (I-embre-se de que o m6todo go ( )
pensa que est6 recebendo um objeto Animal, entXo ele lhe pediri que faga apenas coisas referentes a Animal, as quais, 6 claro,
qualquer coisa que herdar de Animal tamb lmpoderifazer.) Assirn, neste caso, o compilador amplia a referAncia Dog3 para
um Animal, e a chamada tem sucesso. A principal questlo aqui 6 que a ampliagio da refer6ncia depende da heranga" em
outras palavras do teste E-IJM. Por causa disso, nio 6 vilido ampliar de uma classe wrapper para outra, porque as classes
wrappersXo semelhantes entre si. Porexemplo, NAO 6 vfido dizerque Short E-UM Integer.

oBSERVAq6ESpeneoE)(AME
E tentadorpensar que uocd poderia atnpliar am wr@perlntegerpara torniJo an un@per l-ang, mas 0 seguinte exemp/o I\AO rcrrpilar,i:

class DagL {
pubfic static void main(String [] args) {
Dog4d=newDog4O;
d. test (new Integer (5) ) ; ,/,/ impossivel ampliar um Inteqer
| / ^^-^ q ..* T
/ / IJAL UrL ^6-
!V1r9

]
void test (Long x) { }

]
I--embre-sedequenenhartadasclasseswr@perpodeseamp/iardeumaparaoutralByLes ndoseampliamparashorts,Shorts
ndo se ampliamparaLongs, etc.

Sobrecarga na Combinagio de Ampliagio com Boxing


Ji vimos as regras que se aplicam quando o compilador consegpe estabelecer uma correspond6ncia entre chama& e m6todo
realizando uma tinica convenio. Vejamos agora o que acontece quando 6 preciso fazer mais de uma conversio. Neste caso, o
compiladorter6 de ampliar e depois fazer autoboxing do parAmetro para que haja uma correspond6ncia:
142 Copitulo 3: AtribuiE6es
class WidenAndBox {
sLatic void go(Long x) { System.out.println("Long"); }
public static void main(String [] args) {
byte b = 5,'
go (b) ; / / preclsa ampliar e depois fazet boxing - inv6lido

)
Isso 6 &mais para o compilador:
WidenAndBox.java: 5 : gto ( java. lang.Long) in WidenAndBox cannot be
applied to (byter
Mas o 6 estranho que o compiladorPODE fazerumaoperagio de boxingseguidaporumaopera$o de ampliagio para
criar uma corresponddncia entre chamada e m6todo. Este exemplo podera lhe deixar confuso:

class goxAndWiden {
static void go(Object o) {
Byte b2 = (Byte) o; / / ok - 6 um objeto Byte
qrrqf6m .
sJ p Lvlr!. vqu.}/t nriniln
nrrt- frrufLL /Lr?\
\p- t,

)
public static void main(String [] args) t
byte b = 5;
go(b); // este byte pode ser transformado em um Object?
)
)
Esse exemplo compila (!), e produz a saida:

Uau! Eis o que aconteceu nos bastidores quando o compilador, e depois aJVM, chegou i linha que chama o
m6todo go O :
1. O byte b foi encapsulado com boxing em um Byte.
2. A refer€ncia Byte foi ampliada para se tornar um Object (uma vez que Byte estende Object).
3. O m6todo go ( ) recebeu uma refer6ncia Object que, na verdade, aponta para um objeto Byte.
4. O m6todo so ( ) convefteu a referOncia Object de volta para uma refer6ncia Byte (embre-se, nunca houve
um objeto do tipo Object neste cenirio, apenas um objeto do tipo Byte!).
5. O m6todo so ( ) exibiu o valor de Byte.
Porque o compiladorniotentouusaral6gicaboxingdepois-amplia$o quando tentoulidarcom aclasse
WidenAndBox? Pense nisso... Se ele tentasse fazer boxing primeiro, byte seria convertido em um Byte. E ai estariamos de
volta i situagio & tentar ampliar um Byte para um Long e, 6 claro, o teste E-UM falha.

Sobrecarga em Combinagio com Var-args


O que acontece setentarmos combinarvar-argp oucom a ampliagio ou com o boxingemum cenirio de buscapela
correspond6ncia de um m6todo? Vejamos:
class Vararg {
static void wide-vararq(1ong. . . x)
{ System.out.println("1ong. . . " ) ; }
static void box_vararg(Integer. . . x)
{ System.out.println( "fnteger. . . " ) ; }
public static void main(String [] args) t

wide-varars(5,5); // precisa ser ampliado e usa var-args


box_vararg(5,5) ; / / preclsa ser encapsul-ado com boxing e usa var-args
'143
JAVA 5

]
Esse exemplo compila eproduz:
long. . .

Integer...
Como podemos ver, 6 possivel combinar com sucesso var-args corn ampliagio ou com boxing. Eis uma revisio das regras
para m6todos sobrecarregados que usem ampliaglo, boxing e var-args:

r A ampliagio de primitivos usa o "menor" argumento possivel do m6todo.


I Usados individualmente, boxing e var-args sio compativeis com a sobrecarga.
r NAO 6 possivel ampliar de um tipo wrapper para outro. @-tnt frlha.;
r NAO 6 possivel ampliar e depois fazer boxing. (Jm int nlo pode se tornar um Long)
I E possivel fazer boxing e depois ampliar. (Um int pode se tornar um Object, via Integer.) E possivel combinar var-
args com ampliagio ou com boxing.

Existem aspectos mais complexos relativos i sobrecarga, mas, tirando algumas poucas regras referentes aos gen6ricos (que
abordaremos no Capinrlo /), isso 6 tudo o que voc6 percisarl saber para o exame. Caramba!

Obietivo poro o certificoEdo

Coleta de lixo (Objetivo 7.4 do exame)


T.4Dadoumexemplodealdigo,reconheceropontoemqueumoletosetornaqualifcadoparaacoletadelixo,edeterminaroquedeoquendoi
pek $stema de colcta de lixo. Reeonhuer 0 cnnpnftamentr de Slsten.gc e dafnaliryg1o.
gmantido

Visio total do gerenciamento da mem6ria e da coleta de lixo


Esta 6a seglo pela qual voc6 estava esperando! Finalmente chegou a hora de nos aprofundarmos no interessante universo
do gerenciamento da mem6riae coleta de lixo.

O gerenciamento da mem6ria 6 um elemento crucial em muitos tipos de aplicativos. Considere um programa que leia
grandes quantidades de dados, digamos, em algum local de uma rede e, em seguida, os grave em um banco de dados na
unida& de disco rigido. Umpro.ieto tipico serialeros dados em algumtipo de conjunto namem6ria, executar algumas
operag6es com eles e grav6Jos no banco de dados. Depois que os dados fossem gravados, o conjunto que os armazenou
temporariamente precisaria eliminar os dados antigos ou ser excluido e recriado antes do processamento do pr6ximo lote.
Essaopera$opodeserexecutadavAiuvezns,eemlinguagenscomoCouC+ +,queniooferecemacoletaautom6ticade
lixo; uma pequena falha na l6gica que ewazie ou exclua as estruturas de &dos do conjunto pode permitir que pequenas
quantidades da mem6ria sejam inadequadamente recuperadas ou perdidas. De maneira definitiva. Essas pequenas
perdas sXo chamadas de uaTamentot de memriia, e depois de virias iterag6es podem tornar inacessivel uma quantidade
suficiente de mem6ria para finalmente causar a interrupgio dos programas. A criagio de um c6digo que execute o
gerenciamento manual da mem6ria de maneira limpa e completa 6 uma tarefa complicada e nio trivial, e embora
as estimativas variem, 6 discutivel se esse gerenciamento manual pode dobrar o esforgo de desenvolvimento de um
programa complexo.
O coletorde lixo dalinguagemJavaforneceumasolugio automhticaparaogerenciamento damem6ria. Namaioriados
casos ele o livrari de ter que adicionar alguma l6gica de gerenciamento da mem6ria em seu aplicativo. A &wantagem da
coleta de lixo autom6tica 6 que voc6 nlo poder6 controlar exatamente quando ela ser6 ou nio executada.

Vis6o geral do coletor de lixo em fava


Vamos examinar o que queremos dizer sobre coleta de lixo no universoJava. Aqui, a 30 mil p6s de altura, coleta de lixo 6 o
termo usado para descrever o gerenciamento automitico da mem6ria em Java. Sempre que o programa de um software for
executado (emJav4 C, C + + , Lisp, Ruby, e assim por diante), ele usar6 a mem6ria de v6rias maneiras diferentes. Nio
entraremos nos aspectos blsicos da ci€ncia da computaglo aqui, mas 6 normal a mem6ria ser usada para criar uma pilh4 um
heap, em pools constantes de maiusculas e minusculas da linguagemJava, e em 6reas de m6todos. Heap 6 aparte da
mem6ria onde residem os objetosJava, sendo o rtnico local da mem6ria que de alguma forma estari envolvido no
processo de colaade lixo.
Un heap i irzplesaente am he@. No exane rcni inportantu saber que uocd pode chaad-lo de be@, de heap de cokta de lixo, de
144 Copitulo 3: Atribuig6es

Johnson, pordrn ,s6 bi um beap.

Portanto, todo o assunto da coleta de lixo gira em torno de assegurar que o heap tenha tanto espago disponivel
quanto possivel. Para os fins do exame, isso se resume em excluir qualquer objeto que nAo possa mais ser
alcangado pelo programa Java que estiver sendo executado. Discutiremos melhor o que significa "poder ser
alcangado", mas antes nos aprofundaremos no assunto em questao. Quando o coletor de lixo for executado, sua
finalidade ser6 encontrar e excluir objetos que nio possam ser alcangados. Se voc6 imagina o programa Java em
um ciclo constante de criagio dos objetos que precisa (o que ocupa espago no heap) e, em seguida, descartando-os
quando nio forem mais necess6rios, criando novos objetos e descartando esses objetos, e assim por diante, a pega
perdida do enigma 6 o coletor de lixo. Quando ele for executado, procurari esses objetos descartados e os excluiri
da mem6ria para que o ciclo de uso e liberagio da mesma possa continuar. Ah, o fant6stico ciclo vital!

Quando o coletor de lixo 6 executado?


O coletor de lixo 6 controlado pelo VM. A JVM decide quando executi-lo. De dentro de seu programa Java voc6
pode solicitar )LJVM para executar o coletor de lixo, mas nio haveri garantia, em nenhuma circunstAncia, de que
ele o far|. Quando a decisio 6 s6 dele, normalmente a JVM executa o coletor de lixo ao perceber que a mem6ria
est6 ficando sem espago. A experiAncia mostra que quando um programalava f.az uma solicitagio de coleta de
lixo, a JVM geralmente a atende rapidamente, mas ado bd garuntias. Exatamente quando pensamos que poderemos
contar com ele, aJVM decide ignorar a solicitagio.

Como o coletor de lixo funciona?


VocA nio conseguir6 ter certeza. Pode ouvir que o coletor de lixo usa um algoritmo de marcaglo e eliminaglo, e
isso poderia ser verdade para alguma implementagio Java em particular, mas a especificaEio da linguagem nio
garante nenhuma implementaEio especifica. VocA pode ouvir que o coletor de lixo trs a tontagem de referdnciat;
novamente, talvez sim, talvez n6o. O conceito imponante a compreende r para o exame 6. quando un objeto re tlrna
realmente qaalifcado para a coleta de lixo. Para responder essa questeo integralmente temos que nos adiantar um pouco e
falar sobre threads consulte o Capitulo 9 para obter informag6es detalhadas sobre eles. Resumidamente, todo
-
programa Java possui de um a v6.rios threads. Cada thread tem sua pr6pria pilha de execugio. Normalmente, voc6
(o programador) fari com que pelo menos um thread seja executado em um programaJava, o que tiver o m6todo
main ( ) no final da pilha. No entanto, como aprenderemos em detalhes no Capitulo 9, hl muitas raz6es
realmente importantes para iniciar threads adicionais a paftir de seu primeiro thread. Al6m de ter sua pr6pria
pilha de execugio, cada thread possui seu pr6prio ciclo de vida. Por enquanto, tudo que precisamos saber 6 que os
threads podem estar ativos ou nio. Com essas informag6es auxiliares jf podemos dizlr cbm bastante clareza que
um objeto utui qualficado para a coleta de lixo qaando nenhum tbread atiuo pode acessd-/0. (Observagio: devido ao cariter vago do
pool de constantes Strings, o exame concentra as suas quest6es sobre coleta de lixo em objetos nio-Strings, enteo a
nossa discussXo sobre a coleta tamb6m se aplicar6 apenas a objetos que nio sejam Strings.)

Com base neisa definigio, o coletor de lixo executa algumas operag6es desconhecidas e quando descobre um
objeto que nlo pode ser alcangado por nenhum thread ativo o considera qualificado para a exclusio, e pode at6
exclui-lo em algum momento. Ou tamb6m pode nio exclui-lo nunca. Quando falamos sobre alcanparum objeto, na
verdade estamos falando sobre ter uma variivel de refer€ncia ahangiuel que aponte para o objeto em questao. Se
nosso programa Java tiver uma variivel de refer6ncia que aponte para um objeto, e se ela estiver disponivel para
um thread ativo, entio, esse objeto ser6 considerado alcanp,iuel. Discutiremos mais sobre como os objetos podem se
tornar inalcang6veis na segio seguinte.
Um aplicativo Java pode ficar sem mem6ria disponivel? Sim. O sistema de coleta de lixo tentarS.remover os objetos
da mem6ria quando eles nio forem usados. No entanto, se voc6 tiver muitos objetos ativos (objetos referenciados por
outros objetos ativos), o sistema poder6 ficar sem mem6ria disponivel. A coleta de lixo nio pode assegurar que haja
mem6ria suficiente, somente que a mem6ria disponivel ser6 gerenciada tio eficientemente quanto possivel.

Escrevendo um c6digo que torne os objetos explicitamente qualificados


Para a coleta
Na seglo anterior, aprendemos as teorias existentes por trAs da coleta de lixo Java. Nesta segio, mostraremos como tornar os
objetos qualificados para a coleta de lixo usando um c6digo real. Tamb6m discutiremos como 6 possivel tentar forgar a
coleta de lixo se ela for necessiria e como voc6 pode executar uma limpeza adicional nos objetos antes que eles sejam
removidos da mem6ria.

Anulando uma refer6ncia


Como discutimos anteriormente, um objeto se torna qualificado para a coleta de lixo quando nlo h6 mais referAncias a ele
que possam ser alcangadas. E claro que se nlo houver refer6ncias alcang6veis, nio imponari o destino do objeto. No que nos
diz respeito, ele ficar6 apenas flutuando no espago, sem ser utilizado ou acessado, nio sendo mais necessirio.
A primeira maneira de remover a refer6ncia a um objeto 6 configurar com nulf avari|vel de refer6ncia que
estiver apontando para ele. Examine o c6digo a seguir:
JAVA 5 I45
1. public class GarbageTruck {
2. public static void main(String [] args) {
3. StringBuffer sb = new StringBuffer ( "hello" ) ;
4. System.out.println(sb) ;
5. // O objetoStringBuffer nao esta qualificado para coleta
6. sb = nul1;
'7. / / Agora o objetostringBuffer est.6 qualificado para coleta
B. )
9. ]
A variivel de refer6ncia sb foi atribuida ao objeto StringBuffer de valor hell-o na terceira linha. Para torn6-lo
qualificado (ptara a coleta), configuramos a variivel de refer6ncia sb com null, o que remover| a inica
refer6ncia ao objeto StringBuf f er que existia. IJma vez executada a linha 6, nosso objeto StringBuf f er
he11o estar6 condenado, qualificado para a coleta de lixo.

Reatribuindo uma vari6vel de referGncia


Tamb6m podemos desassociar uma varilvel de referdncia de um objeto configurando-a para referenciar outro
objeto. Examine o c6digo abaixo:
class GarbageTruck {
pubLic static void main(String [] args) {
StringBuffer s1 = new StringBuffer("hel]o");
StringBuffer s2 = new StringBuffer("goodbye") ;
q\rql- am nrrf
vJ s ev.'r. nri nl- lr 1<1 \

// Neste ponto, o StringBuffer "hell-o" nao est5 qualificado


s1 = s2; // Redireciona s1 para refer6ncia ao objeto "goodbye"
/ / Agora o StringBuffer "hel1o" est5 qualificado para coleta
)

i
Os objetos criados em um m6todo tamb6m precisam ser considerados. Quando um m6todo for chamado, qualquer
vari6vel local que for criada s6 existir6 durante a execugio do m6todo. Uma vez que o m6todo tiver sido concluido, os
objetos criados nele estario qualificados para a coleta de lixo. H6 uma excegio 6bvia, no entanto. Se um objeto for retornado
do m6todo, sua refer6ncia pode ser atribuida a uma variivel do m6todo que o chamou; assim, ele nio estari
qualificado para a coleta. Examine o c6digo abaixo:
import j ava. util . Date t

nrrhl i n al :cc fl:rl-r:naE'ani-nrrz I

public static void main(String [] args) {

Date d = getDateo
doComplicatedstuff ();

System.out.println("d = " + d) ;
)
n"k] .i^ -f-f.i^ nrl6 d6l-n:f6/\ tL
PUUIIL DUaUfL uqus YeLUqre\/

Date d2 = new lateo;


StringBuffer now = new StringBuffer (d2.toStringO );
qircl- am
efrevrrr!vuu.vrflrvf nri n|- l n lnar^rl .
^11|-
return d2;
]
]
No exemplo anterior, criamos um m6todo chamado getDate (
) que retorna um objeto Date. Esse m6todo cria
dois objetos: um objeto Date e uma StringBuffer contendo as informag6es sobre a data.li que o m6todo retorna o
objeto Date, ele nio esterS, qualificado para a coleta mesmo depois que o m6todo for concluido. O objeto
StringBuffer, no entanto, estar6 qualificado, ainda que nio tenhamos configurado explicitamente a variivel now
com null-.
146 Copftulo 3: Atribuig6es
lsolando uma referencia
H6 outra maneira por meio da qual os objetos podem se tornar qualificados para a coleta de lixo, netmo rc ainda
tiaervm referincias u,ilidas! Consideramos esse cenirio como ilbat de isolamento.
Um exemplo simples seria uma classe que tivesse uma vari6vel de instAncia que fosse a variivel de refer6ncia de outra
instAncia & mesma classe. Agora imagine a exist6ncia de duas instAncias desse tipo referenciando uma a outra. Se todas as
outras referAncias a esses dois objetos forem removidas, entio, embora cada um dos objetos ainda tenha uma referdncia
v61ida, nio haveri como algum thread ativo acessar um deles. Quando o coletor de lixo for executado, ele descobrir6 esas
ilhas de objetos e as remover6. Como voc6 pode imaginar, as ilhas podem se tornar bem grandes, contendo teoricamente
centenas de objetos. Examine o c6digo a seguir:

public class lsland {


Island i;
public static void main(String [] arqs) {

fsland i2 = new Islando


Island i3 = new fslando
Island i4 = new Islando

IZ .I i3; // i2 refere-se a i3
lJ.a i4; // i3 refere-se a i4
i4.i i2; // i4 refere-se a i2

nrrl l .

:A - nrr'l I.

/ / real-iza tarefas complicadas e que exigem muita mem6ria

Quandooc6digoalcangar I / realiza tarefas. . .,ostr6sobjetoslsland(antesconhecidoscomoi2, i3 ei4)


terio variiveis de instAncia para que apontem um para o outro, mas seus vinculos com o ambiente externo (i2, i3
e i4) terio sido anulados. Esses tr6s objetos estarAo qualificados para a coleta de lixo.
Abordamos tudo que voc6 precisa saber sobre tornar objetos qualificados para a coleta de lixo. Estude aFigara3-7
para refor7ar os conceitos de objetos sem referOncias e ilbas de inlanento.

Forgando a coleta de lixo


A primeira coisa que deve ser mencionada aqui 6 que, em oposigXo ao titulo desta segio, a coleta de bxo ndo podc ser
-foryodo.No entanto, a linguagem Java fornece alguns m6todos que permitirio a voc6 solicitar i JVM que execute a
coleta de lixo. Por exemplo, se vocA estiver para executar algumas operag6es limitadas pelo tempo, provavelmente
ir6 tentar minimizar as chances de um atraso causado pela coleta de lixo. Mas deve se lembrar que os m6todos
fornecidos pelaJava sio solicitagdes e nio demandas; a miquina virtual fari o que puder para executar o que voc6
solicitar, mas nio hi garantias de que o far6.
Na verdade, s6 6 possivel sugerir ) JVM que execute a coleta de lixo. No entanto, nio haver| garantias de que todos
os objetos nXo utilizador r.iao reimente removidos da mem6ria. li essencial que voc6 compieenda esse c-onceito
para o exame.
As rotinas de coleta de lixo que a Java fornece sio membros da classe Runtime. A classe Runtime 6 uma classe
especial que possui somente um objeto (o objeto Singleton) para cada programa principal. O objeto de Runtime
fornece um mecanismo de comunicagio direta com a m6quina virtual. Para capturar a instAncia de Runtime, voc6
pode usar o m6todo Runtime. getRuntime ( ) , que retornari o objeto Singleton. Assim que tiver o Singleton,
voc6 pode chamar o coletor de lixo usando o m6todo gc ( ) .
Alternativamente, vocA pode chamar o m6todo da classe System, cujos m6todos static sio capazes de obter o
objeto Singleton para voc6. A maneira mais simples de solicitar a coleta de lixo Qembre-se: 6 apenas uma
solicitaEio) 6 atrav6s de:
Qa'cf6m n- I I
JAVA 5 I47
Teoricamente, depois de chamar System. cg ( ) , voc6 ter6 tanto espago livre na mem6ria quanto possivel.
Dissemos teoicamente porque essa rotina nem sempre funciona assim. Primeiro, a JVM que voc6 estiver usando
pode nXo tAJa implementado; a especificagio da linguagem permite que essa rotin^ nilo tenha absolutamente
nenhumafungio.

pubLic class Island (


Island n;
public static void main(St.ring [] args) {
Island i2 = new IslandO;
ls1and i3 = new IslandO:
Tsland i4 = new Island():
l-l.n = t-J
i3.n = i4
i4.n =i2
i2 = nul1;
i3 = null;
i4 = nu11;
doCourlexstuff O;
m@
, til @
ma

lndicava uma public class LosE {


public static void rnain(Strinq {} args) {
-}.@.,
referGncia ativa Lost x = new tost O:
x = nul1;
docomplexstuff ( ) :
lndica uma )
t
referCncia apagada
Figuro 3-7 Obietos guo/ificodos poro o co/efo de /ixo
Em segundo luBar, outro thread (mais uma vez, consulte o Capinrlo 9) pode executar uma alocagio de mem6ria substancial
logo depois que voce processar a coletade lixo.
(
Com isso, nio queremos dizer que Sytem. gc ) 6 um m6todo inrltil - 6 muito melhor que nada. Mas 6 que voc6 nio
pode confiar em system. gc (
) para liberar um espago suficiente na mem6ria de modo que nXo precise se preocupar
com a execugeo da coleta de lixo. O exame da certifica$o estari interessado em um comportamento garantido, neo num
prov6vel.
Agora que estamos um porlco familiarizados com a maneira como isso funciona, .f".E1"gr alguns testes para ver se
conseguimos constatar os efeitos da coleta de lixo. O programa a seguir nos permitir6 saber quanto espago total na
mem6ria a J\&I tem disponivel para ele e quanto desse espago esti livre. Em seguida, ele cria 10 mil objetos Date.
Depois disso, nos informa quanto espago sobrou na mem6ria e chama o coletor de lixo (que, se for executado,
deve interromper o programa at6 que todos os objetos nio utilizados sejam removidos). O resultado final do
espago livre na mem6ria deve indicar se ele foi executado. Examinemos o programa:
f . import java.util.Date;
2. public class Checkcc {
3. public static void main(String [] args) {
4. Runtime rt. = Runt.ime. getRuntime ) ; (

5. System. out.println ( "Tota1 JVM memory: + rt.totalMemoryO );


System.out.println( "Before Memory = " rt.freeMemoryO );
7. Date d = nul1;
8. for(int i = 0;i<10000;i++) {
q d = new Date0;
l_0. d = nul1;
11. )
1,2. System. out.println ( "After Memory = r' + rt. freeMemory ( ) ) ;
13. rt.gc(\; // uma alternativa a System.gco
L4. System.out.println("After GC Memory = " * rt.freeMemoryO );
148 Copitulo 3: AtribuiE6es
15. )

1-6. ]
Agora, executaremos o programa e verificaremos os resultados:
Total J\,rM memory: 1048568
Before Memory = 703008
Aft.er Memory = 458048
After cC Memory = 8L8212
Como podemos ver, o VM realmente decidiu coletar (isto 6, excluir) os objetos qualificados. No exemplo anterior,
sugerimos I JVM que executasse a coleta de lixo com 458.048 bytes de mem6ria restantes e ele atendeu nossa
solicitaglo. Esse programa s6 tinha o thread de um usuirio sendo executado, portanto, nio havia nada mais
acontecendo quando chamamos rt. gc ( ) . Nio se esquega de que o comportamento quando gc ( ) 6
chamado pode ser diferente em JVMs distintos, de modo que nio haver| garantias de que os objetos nXo utilizados
serlo removidos da mem6ria. A rinica coisa garantida 6 que se voce estiver ficando com muito pouco espago na
mem6ria, o coletor de lixo ser6 executado antes que uma exceglo outofMemoryException seja langada.

Exercfcio 3-2
Experimente modificar o programa CheckGC colocando as linhas 13 e 14 dentro de um loop. VocA poder6 ver que
nem toda a mem6ria 6 liberada com uma passada de GC.

Fazendo uma limpeza antes da coleta do lixo - o m6todo finalize( )


A linguagemJava fornece um mecanismo para que algum c6digo seja executado imediatamente antes que um objeto seja
excluidopelocoletordelixo.Essec6digoficar6emumm6todochamado finalize( ) quetodasasclassesherdamda
classeObject. A primeira vista parece uma grande idliutilvez reu objeto tenha abeno alguns recursos que voc6 gostaria de
fechar antes que ele fosse excluido. O problema 6 que, como vod jl deve ter deduzido, nlo 6 possivel contar com o coletor de
lixo para excluir o objeto. Portanto, nenhum c6digo que voc6 insira no m6todo f inalize ( ) sobrescrito de sua
classe teri a execugio garantida. O m6todo f inalize ( ) de um objeto especifico pode ser executado, mas nio hi
como contar com ele; enteo, neo insira nenhum c6digo essencial nesse m6todo. Na verdade, recomendamos que
voc6 nlo sobrescreva de forma alguma f inalize ( ).

Cuidados relacionados com finalize( )


Hi alguns conceitos relacionados com f inalize ( ) que voc6 precisa lembrar:
I Para qualquer objeto, f inalize ( ) seri chamado apenas umavez (no maximo) pelo coletor de lixo.
r Chamar f inalize ( ) pode resultar em salvar um objeto da exclusio.
Examinaremos essas declarag6es com mais detalhes. Em primeiro lugar, lembre-se que f inalize ( ) 6 um
m6todo e qualquer c6digo que voc6 puder inserir em um m6todo conum poderi inserir em f inalize ( ) . Por
exemplo, no m6todo f inalize ( ) voc6 poderia escrever um c6digo que retornasse uma refer6ncia ao objeto
em questio para outro objeto, duqualficando efetivamente o objeto para a coleta de lixo. Se em algum momento
posterior esse mesmo objeto se tornar novamente qualificado para a coleta de lixo, o coletor ainda poderi
processar e exclui-lo. No entanto, ele lembrar6 que f inalize ( ) jLf.oi execttado paraesse objeto, e nio processar6
o m6todo mais uma vez-

Resumo para a certificagio


Este foi um megacapitulo! NXo se preocupe se vocA perceber que precisar6 revisar alguns destes t6picos quando
chegar. em capitulos posteriores. Este aqui apresentou muitos conceitos b6sicos que lhe serio rlteis
POStenOrmente.
Comegamos o capitulo revisando a pilha e o heap; lembre-se de que as variiveis locais residem na pilha, e as vari6veis de
instAncias residem, com os seus objetos, no heap.

Revisamos os literais v6Llidos para tipos primitivos e Strings, e depois discutimos os fundamentos da atribuigio de valores a
tipos primitivos e a vari6veis de refer6ncia, al6m das regras para conversXo de primitivos.

Em seguida, discutimos o conceito de escopo, ou "por quanto tempo esta vari6vel viver6?" Lembre-se dos quatro escopos
bisicos, do maior para o menor tempo de vida: static, instance, local, block.
JAVA 5 I49
Abordamos as implicag5es de se usar variiveis nio-inicializadas, e a imponincia do fato de que as vari6veis locais
deaem receber um valor explicitamente. Falamos sobre alguns dos aspectos complicados de se atribuir uma variivel
de referAncia a outra, e alguns dos detalhes sobre a passagem de variiveis para m6todos, incluindo uma discussio
do "sombreamento".
O t6pico seguinte foi a criagio de arrays, no qual falamos sobre declarar, construir e inicializar arrays uni e multidimensionais.
Falamos sobre arrays an6nimos e sobre arrays de referOncias.

Em seguida, revisamos os blocos de inicializagio est6ticos e de instAncias, qual a apar6ncia deles e quando eles sio chamados.
Caramba!

Continuamos o capitulo com uma discussio das classes wrapper, usadas para se criar objetos imut6veis que armazenem um
tipo primitivo, e usadas tamb6m para fornecer capacidades de conversio para primitivos: memorize valueof ( ) ,
xxxValue ( ) eparsexxx () .

Falamos sobre um novo e importante recurso deJava 5, que e$a intimamente relacionado aos wrappers: o autoboxing.
Boxing 6 uma maneira de automatizar o uso de wrappers, e abordamos alguns dos seus aspectos mais complexos, tais
como a forma como wrappers trabalham com : : e com o m6todo equals ( ) .
Tendo adicionado o boxing I nossa caixa de ferramentas, passamos a dar uma olhada com mais detalhes na sobrecarga de
m6todos e como o boxing e os var-args, em conjunto com convers6es ampliadoras, tornam a sobrecarga mais complicada.

Finalmente, nos dedicamos ) coleta de lixo, o recurso de gerenciamento automitico de mem6ria deJava. Aprendemos que 6
no heap que os objetos residem, e 6 tamb6m onde toda a interessante atividade de coleta de lixo se realiza. Aprendemoi
que, no fim das contas, a JVM far| a coleta de lixo quando ele quiser. VocA (o programador) pode pedir que seja
feita uma coleta, mas nio pode forgiJa. Falamos sobre a coleta de lixo aplicar-se apenas a objetos que estio
qualificados, e que qualificados significa "inacessiveis para qualquer thread ativo". Finalmente, discutimos o
raramente rltil m6todo f inalize ( ), e o que vocA precisari saber sobre ele para o exame. No fim das contas, um
capitulo fascinante.

{ EXERCICIO RAPIDO
Eis alguns dos pontos principais deste capitulo.

Pilha e Heap
E Asvariiveis locais (vari6veis de m6todo$ residem napilha.
E Os objetos e as suas variiveis de instincias residem no heap.

Literais e Conversio de Tipos Primitivos (Objetivo 1.3)


D Osliteraisintegerpodemserdecimais,octais(p.ex.013) ouhexadecimais(p.ex.Ox3d).
D Os literais para longs terminam com L ou 1.
D Os literais float terminam com F ou f , e os literais double terminam com um digito, com D ou com d.
E Os literais booleanos sio true e f alse.
fl Os literais para chars sio um 6nico caracrer dentro de aspas simples: 'd'.

Escopo (Objetivos 1.3 e 7.6)


E O escopo refere-se ao tempo de vida de uma vari6vel.
E Existem quatro escopos bisicos:
E As variiveis estiticas vivem basicamente pelo mesmo tempo que as suas classes.

0 As vari6veis de instAncia vivem pelo mesmo tempo que os seus objetos.

fl As vari6veis locais vivem pelo mesmo tempo que os seus m6todos na pilha; entretanto, se o m6todo chamar outro
m6todo, elas ficam temporariamente indisponiveis.
D As vari6veis de bloco (p.ex. em um f or ou em um if) vivem at6 a conclusio do bloco.

Atribuig6es B6sicas (Objetivos 1.3 e 7.6)


tr Os literais de integers sio implicitamente ints.
E As express6es integer sempre geram um resultado com o tamanho de int, nunca menor.
B Os nrimeros de ponto flutuante sio implicitamente doubles (64 bit$.
150 Copftulo 3: AtribuiE6es
E Diminuir um tipo primitivo causa o corte do.s bits de ordem mais alta.
D Atribuig&s compostas (p.ex. + =) realizamumaconversio autom6tica.
El Uma vari6vel de refer6ncia armazena os bits que sio usados para se referir a um objeto.
E As varilveis de refer6ncia podem referir-se a subclasses do tipo declarado, mas nio a superclasses.

E Aosecriarumnovoobjeto,p.ex.,Button b = new ButtonO;,tr6scoisasacontecem:


E Cria-se umavari6vel de refer6ncia chamada b, do tipo Button
B Cria-seumnovo obietoButton
tr Atribui-se o objeto Button )variivel de refer6nciab

Usando uma yari6vel ou elemento de array que nao tenha sido inicializado ou atribuido
(Objetivos 1.3 e 7.6)
D Quando um array de objetos for instanciado, os objetos do array nio serio instanciados automaticamente, mas todas as
refer6ncias receberio o valor padrio nul1.

tr Quando um array de tipos primitivos for instanciado, todos os elementos receberio seus valores padrio.
tr As vari6veis de insAncia serio sempre inicializxlas com um valor padrlo.

E As vari6veis locais/autom6ticas/de m&odo nunca recebem um valor padrio. Se voc6 tentar usar uma antes de inicializ6-
la, receberiumerro do compilador.

Passando vari6veis para os m6todos (Obietivo 7.3)


D Os m6todos podem usar tipos primitivos e/ou referAncias a objetos como argumentos.

D Os argumentos dos m6todos sio sempre c6pias.

D Os argumentos dos m6todos nunca sio objetos reais (podem ser refer€ncias a objetos)

0 Um argumento primitivo 6 uma c6pia totalmente desvinculada do tipo primitivo original.


tr Um argumento de refer6ncia 6 outra c6pia de uma refer6ncia ao objeto original.
E O sombreamento ocoffe quando duas vari6veis com diferentes escopos companilham o mesmo nome. Isso leva a bugs
dificeis de encontrar, e a quest6es do exame dificeis de responder.

Declaragio, construgio e inicializagilo de arrays (Obi. 1.3)


O Os arrays podem conter tipos primitivos ou objetos, mas o array propriamente dito sempre ser|umobjeto.
D Quando vocd declarar um array, os colchetes poderio ficar i esquerda ou i direita do nome.

tr Nio 6 considerado vilido incluir o tamanho de um array na declaraSo.

E Voc6.precisa incluir o tamanho de um array quando o construir (usando new) a menos que esteja criando um array
anorumo.
E Os elementos de um array de objetos nio sio criados automaticamente, embora os elementos de arrays primitivos
recebam valores padrto.
fl Voc€ receber6 uma excegio NullPointerException se tentar usar o elemento de um array de objetos e esse elemento nio
referenciar um objao reai.

fl Os arrays sio indexados comegando pelo zero.

0 ArraylndexOutOfBoundsException ocorre se vod usar um valor de indice invilido.


B Os arrays possuem umavariivel length, cujo valor 6 a quanti&de de elementos do array.

tr O ultimo indice que voc6 poder6 acessar seri sempre uma trnida& menor do que o tamanho do array.
E Os arrays multidimensionais sio apenas arrays compostos por outros arrays.

E As dimens6es de um array multidimensional podem ter tamanhos diferentes.

E Um array de tipos prirnitivos aceitar6 qualquer valor que possa ser promovido implicitamente ao tipo declarado para o
array. Por exemplo, uma vari6vel q6e
pode ser inserida em um array int.
E Um array de objetos pode conter qualquer objeto que passe no teste E MEMBRO (ou instanceof) aplicado ao tipo
declarado para o array. Por exemplo, se Horse estender a classe Animal, entio o objeto Horse poderi ser inserido em um
arraydeanimais.
E Se vod atribuir um array a uma referAnc ia de array ji declarada, o array ter6 que estar na mesma dimensXo & refer6ncia ao
JAVA 5 'I5I

qual for atribuido.


D Voc6 pode atribuir um arruy de um tipo a uma refer|ncia de array j6 declarada de um de seus supertipos. Por
exemplo, um array Honda pode ser atribuido a um array declarado como tipo Car (supondo-se que Honda
estenda a classe Car).

Blocos de Inicializagno (Objetivos 1.3 e 7.6)


D Os blocos de inicializagio es6ticos rodam uma vez, quando a classe 6 carregada pela primdravez.
E Os blocos de inicializagXo de instAncias rodam sempre que uma nova instAncia 6 criada. Eles rodam depois de todos os
supercon$rutores e antes de ser executado o c6digo do construtor.

I Se existirem v6rios blocos init em uma classes, eles seguem as regras indicadas acima, e rodam na ordem em que
aparecem no arquivo-fonte.

Usando wrappers (Objetivo 3.1)


E As classes wrapper e$io correlacionadas aos tipos primitivos.

E Os wrappers t6m duas fung6es principais:

0 Encapsular tipos primitivos para que possam ser manipulados como objetos;

E fornecer m6todos utilit6rios para tipos primirivos (geralmente convers6es).


U Os construtores wrapper podem usar uma String ou um tipo primitivo, exceto para Character, que s6 pode
usar um tipo char.

E As tr€s familias de m6todos mais importantes seo:

E xxxValue ( ) Niousaargumentos, retornaumtipoprimitivo;


D parseXxx ( ) Usa uma String, retorna um tipo primitivo, 6 static e langa a exceEio NFE;
E valueof ( )UsaumaString, retornaumobjeto encapsulado,6 static elangaaexcegioNFE.
D O argumento do radical referencia bases (normalmente) diferentes de 10; a base biniria tem radic a72, oed,: 8e hex :
16.

Boxing (Objetivo 3.1)


tr A partir deJava 5, o recurso de boxing lhe permite converter tipos primitivos em wrappers ou convener wrappers em
uPos Prurutrvos automatrcamente.

D Usar :- com wrappers 6 complicado; v/rappers com os mesmos valores baixos (normalmente os menores
que I27) serio : :, rnzs yalores maiores nlo serio ::.

Sobrecarga Avangada (Objetivos 1.5 e 5.4)


D A ampliagio de primitivos usa o "menor" argumento de m6todo possivel.
0 Usados individualmente, o boxing e os var-args sio compativeis com a sobrecarga.
Cl Y ocl ndo pofu ampliar de um tipo wrapper para outro. @-Ulf faUra.;
D Voc6 ndo pode ampliar e depois fazer boxing. (Um int nlo pode se tornar um Long.)
O Voc6 pode fazer boingedepois ampliar. (Um int pode se tornar um Object, atrav6s de um Inreger.)
tr Vod pode combinar var-args com a ampliagio ou com o boxing.

Coleta de lixo (Objetivo 7.4)


E EmJava, a coleta de lixo fornece um nivel de gerenciamento automatico da mem6ria.

tr A finalidade da coleta de lixo 6 excluir objetos que nio possam ser alcangados.

J 56 a II'/M decide exatamente quando executar o coletor de lixo; voc6 (o programador) s6 pode recomendar que
seja feita essa operagio.

E VocA nio tem como conhecer o algoritmo da coleta de lixo.


D Os objetos devem ser co niderados qulifuaiasantes que possam ser coletados como lixo.
E Um objeto est6 qualificado para a coleta quando nenhum thread ativo consegue alcangiJo.
E Para alcangar um objeto, vod precisa ter uma refer6ncia alcanSvel e ativa a esse objeto.
0 Os aplicativos Java podem ficar sem espago na mem6ria.
tr Ilhas de objetos podem ser coletadas como lixo, ainda que refiram-se umas ls outras.
152 Copftulo 3: Atribuig6es
tr Solicite a colea de lixo com System. gc ( ) ; (recomendado).
E AclasseObjectpossuiumm6todo finalize ( ).
tr Om6todofinalize( )temsuaexecugiogarantidaumavez,esumenre,/maae1antesdeocoletordelixoexcluirum
objeto.

E J6queocoletordelixoniotemexecugiogarantida, finalize ( ) podenuncaserexecxtado.

B Voc6 pode desqualificar um objeto para a coleta usando f inal ize ( ).

Teste Individual

l. Dado:
a'laq< Qcnnn {

static int throwero throws Exception { return 42; }


public static void main(String [] args) {
try {
int x = thrower0;
) catch (Exception e) i
x++;
) finallY {
System.out.println("x = " + ++x) ;
]]]
Qual6 o resultado?
A.x=42
B.x=43
C.x = 44
D. A compilagXo fdha.
E. O c6digo roda sem nenhuma saida.

2. Dado:
class CardBoard {
Short sEory = 5,'
CardBoard go(CardBoard cb) i
cb = nul1;
r6f r!rh
^h.

)
public static void main(String11 args) {

CardBoard c1 = new CardeoardO;


CardBoard c2 = new CardBoard0;
CardBoard c3 = c1 .go(c2);
c1 = null;
/ / faz algo
]]
Quando a execugXo chegar a / / faz a1go, quantos objetos estario qualificados para a coleta de lixo?
AO
B. 1
JAVAs I53
c.2
D. A compilagio falha.
E. Nio 6 possivel saber.
*r r
F.
- E langada uma excegao no tempo de execugio.

3. Dado:
class alien {
String invade(short ships) { return ..a few,.; }
String invade(short... ships) { return ..many,'; }
i
class oefender {
public st.atic void main(String [] args) {
System. out.println (new Alien ( ) . invade (7) ) ;

Qual6oreruhadol
,{. many
B. a few
C Acompilagofalha-
D A saida nio pode ser prevista.
E. E langda uma o<cegXo no tempo de execu$o.

4. Dado:
1. class Dims {
2. public static void main(String[] args) {
3. inrtJU a= {{1,2,}, {3,4}};
4. int[] b = (inttl) atll;
5. Object 01 = a,
6. inttl tl a2 = (inrt] [] ) o1;
7. inttl b2 = (int[]) o1;
8. System.out.println(bt1l ) ;

10. ]
Qual6 o resuhado?
L2
B.4
C f langda uma exce$o em rempo de exeor$o.
D A compila$o falha devido a um erro na linha 4.
E. A compilaglo falha devido a um erro na linha 5.
E A compilagio falha devido a um erro na linha 6.
G A compilagXo falhadevido aum erro na linha 7.

5. Dado:
class Eggs {
int doX(Long x, Long y) { return 1-; }
int dox(Iong. .. x) { return 2; }
int dox(Integer x, Integer y) { return 3; }
1 54 Copitulo 3: AtribuiE6es
int doX(Number n, Number m) { return 4; }
public static void main(String[] args) {
new Eggs O .goO ;

]
void go0 {
short s ='7;
System.out.print(dox(s,s) + " ");
System. out.println (doX (1, I | ) ;
))
Qual6 o resultado?
,d11
8.21,
c31-
D.4 r-

8.2 3
833
G43
6. Dado:
class Mixer {

Mi-xer O { }
Mixer (Mi-xer m) { ml- = m; }
Mixer m1;
public static void main(string[] argrs) {

Mixer m2 = new Mixer0;


Mixer m3 = new ytixer (m2 ) ; m3 . go ( ) ;
Mixer m4 = m3 .m1; m4. go ( ) ;

Mixer m5 = m2.m1; m5.goo;


)
void go() { System.out.print("hi "); }

Qual6 o resultado?
A" hi
B. hi hi
\- nl- n]- nl_

D. Acompilaglofalha
E. hi, seguida de umaexcegio
E hi hi,seguidadeumaexcegAo

7. Dado:
1. class zippy t
2. String[] x;
3. int[] a [] = {LL,2}, {1}};
4. Object c = new long[4];
5. Objectl] d=x;
6. )
Qual6 o resultado?
JAVAs I55
A. A compilagio tem sucesso.

B. A compilagio falha devido a um erro apenas na linha 3.

C. A compilaglo falha devido a um erro apenas na linha 4.

D. A compilagio falha devido a um erro apenas na linha 5.

E. A compilagio falha devido a erros nas linhas 3 e 5.


F. A compilagio falha devido a erros nas linhas 3,4 e 5.

8. Dado:
class Fizz {
int. x = 5;
public static void main(Stri-ng[] args) {

ftnaL Ftzz f1 = new Ftzz];


Ftzz f2 = new Fizz);
ELZZ T5 = E'LZZSWIECN\TI,TZ) i
System.out.println((f1 == f3) + " " + (fl-.x == f3.x) );
)

A. t.ruetrue
B. fal-se true
C true false
D. fa]se false
E. Acompila$ofalha.
-r.: '4r | ry
E rangaoa uma excegao no tempo de execu$o.

9. Dado:
class Knowing t
static final long tooth = 343L;
L4UIU
-^F-ts.i^ f1^h^
Vrr\j Uvf u tlnnn
\ rvrry fnnfh\
uvvutl/ It
^^Tf
System.out..print(++tooth + " ");
return ++tooth;
]
public static void main(stringll args) {
System.out.print(tooth + " ");
final long tooth = 340L;
new KnowinS ( ) .dolt (tooth) ;
Qarcram
u uvrrr. hFl n I f^^th \ .
eJ vuu
^rrf ^ri rrruf
. Pr

]
)

Qual6 o resultado?
A. 343 340 340
B. 343 340 342
c 343 34L 342
D. 343 341, 340
E. 343 341, 343
E Acompilagofalha.
ari'tt.
\r E rangact:I uma excegao no tempo de execugio.
156 Copilulo 3: AtribuiE6es
|0. Quais das afirmativas abaixo s6o verdadeiras? (Marque todas as corretas)
A. A chamada ao m6todo f inalize O de um objeto 6 sempre a fltima coisa a acontecer antes de um objeto ser
coletado como lixo.
B. Quando uma variivel da pilha sai de escopo, ela se torna qualificadapara coleta de lixo.
C. Algumas variiveis de refer6ncia residem na pilha, e algumas residem no heap.
D. Apenas objetos que nio tenham variiveis de refer0ncia apontando para eles podem ser qualificados para coleta
de lixo.

E. E possivel requisitar a coleta de lixo atrav6s de m6todos das classes j ava . 1ang. Runtime ou
j ava. 1ang. System.

I l. Dado:
1. class Convert {
2. public static void main(String[] args) {
3. Long xL = new Long(456l);
4. long x1 = Long.valueOf("123");
5. Long x2 = Long.valueOf("L23");
6. long x3 = xl,,longValue$;
7. Long x4 = xl,.longValue0;
8. Long x5 = Long.parselong:("456");
9. long x6 = Long.parselong("123");
10. )
l_1. ]
Qual ir6 compilar usandose laval,mx ndocompilari com Javat.4? (Marquetodas as corretas)

A. Linha4
B. Linha 5

C. Linha6
D. LinhaT
E. Linha 8
F. Linha9

12. Dado:
1. class Eco {
2. public static void main(stringll args) {
3. Eco e1 = new EcoO;
4. Eco e2 = new EcoO;
5. Eco e3 = new EcoO;
6. e3.e = e2;
'7. e1 .e = e3;
8. e2 = nuI1;
9. e3 = nul1;
l-0. e2.e = e\;
l-1. e1 = nu1l;
L2. )
1-3. Eco et
t-4. )
Em que ponto hi apenas um objeto qualificado paracoletade lixo?
JAVA 5 I57
A. Ap6s a execugio da linha 8.

B. Ap6s a execugio da linha 9.

C. Ap6s a execugXo da linha 10.

D. Ap6s a execugio da linha 11.


E. A compilagio falha
F. Nunca nesse programa.
a 4t r - r i
\r. .tr rangaoa uma excegio no tempo de execugio.

| 3. Dado:
1. class Bigger {
2. public static void main(Stringl] args) {
3. // insira o c6digo aqui
4. )
q1

5. class Better {
. enum Faster {Higher, Longer};
"l

8. ]
Qual op@o, inserida independentemente na linha 3, ir6 compilar? (Marque todas as corretas)
,{.Faster f = Faster.Higher;
B. Faster f = Better.Faster.Higher;
C Better.Faster f = Bett.er.Faster.Higher,'
D. gigger.Faster f = Bigger.Faster.Higher;
E. Better.Faster f2; f2 = Better.Faster.Longer;
E BetLer b; b.Faster = f3; f3 = Better.Faster.Longer;
14. Dado:
class Bird {
{ system. out.print (,'bL " ) ; }
public BirdO { System.out.print("b2 "); }
)
class Raptor extends gird {
static { System.out.print("r1 "); }
public RaptorO { System.out.print("r2 "1, 1

{t q\rql-
vtsLe!.r. am 611l- nri hf f \\r? \\ \t I. }J

static { System.out.prj-nt("r4 "); }


]
class Hawk extends Raptor {
public staLic void main(String[] args) i
qa/cf am nri nf 1\nra ti l .
^rrf

new HawkO;
System. out.println ( *hawk tt ) ;

Qual6 o resultado?
,4.pre bL b2 13 r2 hawk
B. pre b2 b1 r2 13 hawk
C pre b2 b1 12 13 hawk 11 14
158 Copitulo 3: AtribuiE6es
D, 11- 14 pre b1 b2 13 r2 hawk
E. 11, 14 pre b2 bI 12 13 hawk
F. pre rL 14 b1 b2 13 12 hawk
G. pre r! 14 b2 bl- r2 13 hawk
H. A ordem da saida nio pode ser prevista.
I. A compilagio falha.

Respostas
I D esti correta,avari|vel x s6 est6 no escopo dentro do bloco de c6digo try, mas nXo quando est6 dentro dos blocos
catch ou f inal1y. (Para o exame, acostume-se com esses fechamentos horriveis com ) ) ) .)
A, B, C e E estio incorretas com base no exposto acima. (Objetivo 1.3)

2. C est6 correta. Apenas um ob.ieto Cardnoard ( c1 ) est6 qualificado, mas ele tem um objeto wrapper Shon que
tamb6m est6 qualifi cado.

A, B, D, E e F estio incorretas com base no exposto acima. (Objetivo 7.4)

3. C est6 correta, a compilagdo falha. A declaragio dos var-args est A correta, mas invade usa um tipo shorL, de modo que
o argumento 7 precisa ser convertido para esse tipo. Com a conversio, a resposta 6 B, 'a f el'/.

A, B, D e E estio incorretas com base no exposto acima. (Objetivo 1.3)

4. C est6 correta. Uma ClassCastExcept.ion 6langada na linha 7 porque o1 refere-se a um int [ ] [ ] , e nlo a um
int t I . Se a linha 7 fosse removida, a saida seria 4.

A, B, D, E, F e G estio incorretas com base no exposto acima. (Objectivo 1.3)

5. G esti correta. Duas regras se aplicam i primeira chamada a doX ( ) . Nio 6 possivel ampliar e depois fazer boxing de
uma s6 vez, e os var-args sio sempre escolhidos por ultimo. Portanto, vocd nio pode ampliar shorts para ints nem
longs, a fim de fazer boxing deles para Integers ou Longs depois. Mas voc6 pode fazer boxing de shons para
Shorts e depois ampli6-los para Numbers, e isso tem prioridade em relagio a usar um m6todo com var-args. A
segunda chamada usa um simples boxing de int para Integer.

A, B, C, D, E e F estio incorretas com base no exposto acima. (Objetivo 3.1)

6. F esti correta. A vari6vel de instAncia m1 do objeto m2 nunca 6inicializad4 enteo, quando m5 tentar us6-la,
seri langada uma Nu1 1 PointerExcept ion.

A, B, C, D e E estio incorretas com base no exposto acima. (Ob.ietivo7.3)

7. A estl correta, todas essas declarag6es de arrays sio v6lidas. As linha 4 e 5 demostram que arrays podem ser
convertidos.

B, C, D, E e F estio incorretas porque este c6digo compila. (Objetivo 1.3)

8. Aest6 correta. Asrefer€nciasfL,z ef3 apontamtodasparaamesmainstAncia deFizz. Omodificador


final assegura que uma vari|vel de refer6ncia nio poderi ser transferida para um objeto diferente, mas f inal
nio impede que o estado do objeto se modifique.

B, C, D, E e F estio incorretas com base no exposto acima. (Objetivo7.3)

9. D esti correta. Existem tr0s variiveis long diferentes chamadas tooth. Lembre-se de que voc6 pode aplicar
o modificador f inal a vari6veis locais, mas neste caso as duas vers6es de tooth marcadas com f inal
nXo sio modificadas. O rinico tooth cujo valor se modifica 6 o que nio est6 marcado com f ina1. Este
programa demonstra uma mA pritica conhecida como sombreamento.

A, B, C, E, F e G estio incorretas com base no exposto acima. (Objetivo 7.3)

10. C e E estio corretas. Quando um objeto tem uma vari6vel de refer6ncia, essa variivel reside dentro do objeto,
no heap.
JAVA5 159
A est4 incorreta porque se o objeto for salvo da coleta de lixo na primeira vez que o seu m6todo f inalize ( )
forexecutado,enteo,nasegundavezqueoobjetoestiverprestesasercoletado, finalizeO nlorodar6.B
esr6 incorreta
- a coleta de lixo nXo lida com variiveis de pilha. D est6 incorreta porque os objetos podem
residir em "ilhas de isolamento" e serem qualificadas para coleta de lixo. (Objetivo 7.4)

11. A, D e E estio corretas. Por causa dos tipos de retorno dos m6todos, essas chamadas requerem o autoboxing para
compilar.

B, C e F estio incorretas com base no exposto acima. (Objetivo 3.1)

12. Gest6correta. IJmerronalinhal0fazcomquesejalangadaumaNullPointerExcept.ion,porque e2 f.oi


definida como nulL na linha 8. Se a linha 10 fosse colocada entre as linha 7 e 8, entio F estaria correta, porque at6 que
a ultima refer€ncia seja anulada, nenhum dos objetos estari qualificado, e, depois de anulada a ultima referAncia, todos
os tr& estario qualificados.
A, B, C, D, E e F estlo incorretas com base no exposto acima. (Objetivo 7.4)

13. C e E apresentam sintaxe correta para se acessar um enum a paftir de outra classe.

A, B, D e F apresentam sintaxe incorreta. (Objetivo 1.3)

14. Desticorreta.Blocosinit static sloexecutadosnomomentoemqueaclasse6carregada,eosblocosinit


de instAncias rodam logo ap6s a chamada a super ( ) em um constmtor. Quando existem diversos blocos ini t de
um mesmo tipo dentro de uma classe, eles rodam ordenadamente, de cimapara baixo.

A, B, C, E, F, G, H e I estio incorretas com base no exposto acima. Observagio: voc6 provavelmente nio ter6 nenhuma
questao no exame real com tantas opg6es assim! (Objetivo 1.3)
160 Copftulo 3: Atribuiq6es
,rffi
.:,. -

:. :.
Operadores
,'

ffi,'
': Oblerlvos pqru o
.; I
cerllflco96o
I Usondo Ooerodores

t Exercicios r6pidos

P&R Teste individuol

i.i

l:ri

,"

':,,
'162 Copftulo 4: Operodores

Sevoc€tivervai6veis,k6alter6-las.Aumentariseuvalor,assomar6,deslocar6seusbits,asinverter6ecompataxdumas com
as outras. Neste capinrlo, voc6 aprender6 como fazer tudo isso emJava. Adicionalmente, voce aprender6 como fazer coisas
que provavelmente nurlca usar6 no mundo reil, mas que 6 quase certo de estafem no exame.

Obietivo poro o certificoqdo

Operadores fava (Objetivo 7.6 do exame)


7.5 Escreuer aidigo que @lique czffetamente os operadores @rEiados, inc/uindo os de atibuigdo (linitadot a =, *=, -=), os operadoret
aritmdticos (linitados i,
a -, +, /, 0k, ++, - -), os operadores de comparagdo (initadw a 1, 1=, ),
)=, ==, !=), o operador insanceoJ
n,
os operadores llgicos (linitados a &, l, !, &&, l) e o operador condicional (?) para produ{r un resuhado duelado. Esreuer cddigo que
I
detenrine a igualdade de dois oQetos oa dois tiposprinitiuos.

Os operadoresJava produzem novos valores apattt de um ou mais operandos (apenas par^ que fique rudo bem claro, os
operandos silo itens i esquerda ou direita do operador). O resultado damuonadas operag6es 6 um valor booleano ou
num6rico. E como voc6 j6szbe qweJaaa ndo d C**,ndo ftcar| suqpreso com o fato de seus operadores nio poderem ser
sobrecarregados. No entanto, h6 alguns operadores que j6 v6m sobrecarregados:
r O operador * pode ser usado para adicionar um primitivo num6rico a outro, ou para rea)tzar :uma operagdo de
concatenagio se um dos operandos for uma String.
I Os operadores &, I e ^ podem todos eles ser usados de duas maneiras diferentes, apesar de que, nesta verslo do exame,
as suas funcionalidades pa:aopengdo com bits nio sio cobradas.
Fique alerta. A parte do exame referente aos operadores e atribuig5es normalmente 6 aquela em que os candidatos
conseguem menos pontos. Al6m disso, operadotes e atribuig6es acabam entrando em muitas quest6es de outros t6picos...
Seria uma pena voc6 conseguit destrinchar uma questio realmente complexa sobre threads, s6 para ertar a resposta por causa
de uma instrugio de prd-incremento.

Operadores de Atribuigio
Abordamos a maior parte da funcionalidade do operador de atribuig6o,"=",no Capinrlo 3. Para resumir:
I Ao se atribuir um valor a um primitivo, o tamanho faz drfetenga. Certifique-se de saber quand o uma corrvetsdo implicita
ir6 ocorrer, quando a conversio explicita 6 necessiria, e quando poderao ocoffer cortes.

I Lembre-se de que uma variivel de referdncia nio 6 um obf eto; 6 uma maneira de se chegar a um obieto (Sabemos que
todos os leitotes que sZo programadores de C++ estao loucos para nos ouvir dizer "6 um ponteiro", mas nio iremos
fazer isso).
I Ao se atribuir um valor aumavai|vel de refer€ncia,o tipo faz diferenga. Lembre-se das regras para supertipos, subtipos
e arTays.

Em seguida, abordaremos mais alguns detalhes sobre os operadores de atribuigio que caem no exame e, quando
chegarmos no Capitulo 7, veremos como o operador "=" trabafhacom Strings (que s6o imut6veis).

OBSERVAQ6BS penrt O EXAME

Ndo derperdice teupo preparando-se para tuipicos que ndo utqam mais no exanel Resumindo, o exame Jaua 5 difere do exame / .4 por e
afastar dos bits e se
@roxinar da APL Muitos 1 .4 relacionados a lperadzres
tripicos da uersd.o flram remouidos do exame, de modo qile neste
capitulo uoc€ IIJAO uenl

I Operadores de mudanga de bit


I Operadores bitwise

I Complementosbindrios
I Assuntos referentes i divisio porzero
Ndo 6 que uns tdpicos ndo s/am importantes, d @enas qae e/es ndo caem mab n0 exane, e nosso objetiuo i nos concentranros no exame.

Operadores de Atribuigio Compostos


Na verdade, existem cerca de 1 1 operadores de atribuiglo compostos, mas apenas os quatro mais comumente usados (+=, -
=, *= e / =), czem no exame (nio importa o que os obf etivos digam). Os operadores de atribuigio compostos permitem
que os digitadores preguigosos economizem algum trabalho de digrtagio. Eis v6rios exemplos de atribuig5es, primeiro sem
usar um operador composto,
JAVA 5 163

Y = Y - 6;
x = x +2 * 5;
E agora com operadores compostos:

Y-=6;
x+=2*5;
As duas ultimas atribuigSes d6o o mesmo resultado que as duas primeiras.

oB SERVA9oBS pene O EXAME

Versduantigasdoexameco/ocaaamumagrandeOnfatenaprueddnciadeoperadoresQono:pualrioresultadode:x=y+++++xf
z). f
Tirando am conhecimento ba$ante bdsico nbre a preceddncia (qae + e tin prued1ncia sobre *e -, por exemplo), uocd ndo precisard
estudarapreced1ncia de operadoru, exceto ofato de qae, ao asarilm operadorcorrposto, a expreudo no lado direito do = senPre senl aualiada
prineiro. Por exempl0, uoc6 podeia esperar qae

x*=2+5;
fosse aualiada duta forna:
x = (x * 2) + 5; // preced€ncia incorreta
uma ue<que a nuhiplicapdo tdn preced€nda sobre a adigdo. Pordrz, em ueTdisso, a exprer1o ti direita senQre 6 cokcada entrc paftnleses. E
aualiada destafonna:

x = x * (2 + 5);

Operadores de comparagao
O exame aborda seis operadores de comparagio ((, <=, ), )=, == e l-) Os operadores de comparagio sempre resultam
em um valor booleano (true ou f alse). Esse valor booleano 6 usado com mais freqri6ncia em testes if , como
vemos a seguir:
int x = 8;
r_r (x<v) 1

/ / faz al-go
\)

mas o valor resultante tamb6m pode ser atribuido diretamente a um tipo bool-eano primitivo:
class CompareTest {
public static void main(String [] args) t
booleanb=100>99;
System.out.printl-n("The value of b is " + b) ;

Java tem quatro operadores de comparagio que podem ser usados para comparar qualquer combinagio de inteiros,
nrimeros de ponto fluruante ou caracteres:
I > maior que
I >= maior ou igual a
I < menor que
t <= menot ou igual a
Examinemos algumas comparag6es v6lidas:
class GuessAnimal {
public static void main(String [] args) t
String animal = "unknown",.
int weight = 7OO;
char sex = 'm' ;
doubl-e colorwavelength = 1.530;
164 Copitulo 4: Operodores
if (weight >= 500) animal = "elephant";
if (colorWavelength > 1.627) animal = \'gray " + animal ,'

if (sex <= 'f ') animal- = "female " + anj.mal-;


System.out.println("The animal is a " + animal);

No c6.ligo anteriot, usalnos um operador de comparagio entre caracteres. Tamb6m 6 v6lido comparar um tipo primitivo de
c ractere com qualquer nrimero (embora nio seia um estilo de programagio adequado). A execugio da classe anterior exibfu6
o seguinte:
The animal is a gray elephant
Mencionamos que os caracteres podem ser usados com operadores de comparagio. Quando compara um caractere com
outfo ou um caractete com um nrimerq a linguagemJava usa o valor Unicode do caractere como o valor num6rico e
compara os nrimeros.

Operadores de igualdade l

J^v^tem tamb6m dois operadores de comparagio (chamados de "operadores de igualdade') que compa:-arndois itenr
semelhantes e retofnam um valor booleano que representa o que 6 verdadeiro sobre os dois itens serem iguais. Esses
operadores sio
I == g"al (tamb6m conhecido como "igual a')
I != difetente (tamb6m conhecido como "diferente de")
Cada compatagio pode envolver dois nfmeros (incluindo o tipo char), dois valores booleanos ou duas vad6veis de
teferdncia de objeto. Voc€ nio pode comparar tipos incompativeis, no entanto. O que significaria perguntar se um tipo
booleano €igoal,aum tipo char? Ou se um objeto Button 6 igual String? (Exatamente, neo tem
^!mafiay
sentido,e6porissoquen6opodemos faz€-lo).H6guatrotiposdiferentesdeitensquepodemsertestados:
I Nrimeros
I Caractetes

I Tipos booleanos primitivos


I Vari6veis de referdncia de obleto

Por6m, o que o operador == examina realmente? O valor da vari6vel - em outras palavras, o padreo de bits.

lgualdade de tipos primitivos


A maioria dos programadotes est6 familiarizada com a compangdo de valores primitivos. O c6digo a seguir mostta alguns
testes de igualdade em vari6veis primitivas:

class ComparePrimitives {
public static void main(String, [] args) {
System.out.println("character 'a' == 'a'? " + ('a' == 'a'));
System.out.println("character'a' =='b'? " + ('a' =='b'));
system.out.println("5 != 6? 't + (5 t= 6)) ;
System. out.println ( "5. 0 == 5L? " + (5. 0 == 5L) ) ;
System.out.println("true == false? " + (true == false) );

I
Esse progtama ptoduzir6. a saida abaixo:

character 'a' == 'a'? true


character 'a' == 'b'? false
5 l= 6? true
5. 0 == 5IJ? Erue
true == false? false
Como podemos ver, se um nrimero de ponto flutuante for comparado com um inteko e os valores forem os mesmos, o
operador == tetotnard true como esperado.
JAVA 5 165

oBsERvAgOBs pene o ExAME


Ndocorfudaodnal=conooperador=--em*maexpressdobooleana.Oc6digoaseguiriuilido:

l]-.booleanb=false;
L2. if (b = Lrue) i System.out.println("b is true");
l-3. i else { System.out.println(.,b is false,,) ; }
Olhecuidadovmente! Voc6podtfcartentadoapensarqaeauidarcni'b ts faIse", matexamineote$ebooleanodatinha2.A
aari,iuel booleanab ndo eshi sendo nmparada com lcr:ue, e$d sendo confgtrada com true, portanto, prinEJ.n nri execatado e
obteremos 'b i s t rue ". O resultado de qaalquer expressdo de ahibuSdo i igaal ao aahr da uariiael apris a atribuQdo. Essa ub$ituigdo
d0 inal = Pell nperador = = sdfxndona com uaridaeisbooLeanas, jd qile 0 terte if pode vrfeito apeltar em expresrdu booleanas.
Portanto, o aldigo abaixo ndo senl conpilada:

7.intx=1;
8.if(x=o) i)
Jd qw x i um inteim (e ndo un booleano/, o resultado de (x = vr
A) ser,i 0 (o resuhado da aaibtig1o) Os inteimt ndo pod.em
trvdos onde ttm aalor booleano i esperado, portanto, o aidigo da linba 8 ndofuncionanl a menlr qile sgja aherado de una ahibuigdo (=) para
rm tette de tgualdade (= =) como uemot a segxir:

8. if (x == 0) i )

lgualdade de variiveis de refer6ncia


Como vimos anteriormente, duas vari6veis de refer6ncia podem apontar para o mesmo objeto, como o o..6o 6. g6digo
abaixo demonsffa:
JButton a = new Button("Exit") ;

'JButton b = a;
Depois que esse c6digo for executado tanto avai|vela quanto b referenciario o mesmo obieto (um obietoJButton com
o r6nrlo Exit). As vari6veis de refer6ncia podem ser testadas com o operador == para sabermos se estao referenciando um
obieto em comum. kmbre-se de que o operadot == estar6 examinando os bits da vari6vel, portantq com relagio is vari6veis
de referdncia, se os bits das duas variiveis forem id6nticos, elas estario referenciando o mesmo obieto. Examine o c6digo
abaixo:

import java. awt. Button;


class CompareReference {
1,uurru euaurc
*,,Lli^ ^r^el- void main(String IJ args) {
Button a = new Button (.,Exit" ) ;
Button b = new Button("Exit") ;
Button c = a;
System.out.println("Is reference a == b? " + (a == b));
System.out.println("Is reference a == c? " + (a == c));

I
Bt..s$digo cria tr€s vari6veis de refer€ncia. As duas primeiras, a e b, sio objetosJButton diferentes, que por acaso tem o
mesmo nome. A terceira r,zri6vel de referdncia, c, 6 inicializadapatarcferenciar o mesmo objeto que a esta referenciando.
Quando esse prograrna for executado , a seida a seguir ser6 produzida:
Is reference a == b? false
Is reference a == c? true
Ela nos mostra que a e c esteo referenciando a mesma inst6ncia de um objeto ,JButton. O operador == nio testar6 se
dois objetos sio "significativamente equivalentes", um conceito que veremos com muito mais detalhes no Capitulo 7, onde
abordaremos o m6todo equals ( ) (nio confundfu colr:;, o operadorde igualdade que examinamos aqui).

lgualdade para Enums


Depois que vocd declarou um enum, ele nio pode ser expandido. Em tempo de execugdo, nio 6 possivel criar novas
constantes enum. E claro que voc€ pode ter tantas vari6veis quanto quiser apontando para uma dada constante enum, de
forma que 6 importante que se possa comparar duas vari6veis de refer6ncia enum para ver se sio "iguais", ou seja, se elas se
referem i mesma constante enum. Voc€ pode usar ou o operador == ou o m6todo equals ( ) para determinar se duas
vari6veis est6o se referindo i mesma constante entrm:
166 Copitulo 4: Operodores
class EnumEqual 1

anrrm (-nl // ; e Opc]-ona1


F--
[r-:E.rJ, }JLUE]
^-
public static void main(StringtJ args) {
Color c1 = Color.RED; Color c2 = Color.RED,'
if (c1 == c2) { System.out.println("==") ; }
if (c1.eguals (cz) ) { system.out.println("dot equals") r }

)i
O"Oj:"r o quanto ) i e feio, mas estamos preparando voc€ pa:ir- o exame). Esse exemplo produz a saida:

dot equals

Operador de comparageo instanceof


O operador instanceof 6 usado somente com vari6veis de referdncia de objeto, e voc6 pode empregiJo para verificar se
um objeto 6 de um tipo especifico. Por tipo, queremos dizer tipo de interface ou classe - em outras palavras, se o obfeto
referenciado pela vari6vel i esquerda do operador passaria no teste E-MBMBRO do tipo de interface ou classe do lado
direto do operador (o Capinrlo 2 abordou os relacionamentos E-MEMBRO com detalhes). O exemplo abaixo:
public static void main (string IJ args) {
afrih^
9u!f11: c - nau' v9rrllY
at-rina/trf^^r'\
\ lvv / ,

4+
f! |^ : F^+-h^6^f
frrDudrrus9r Cf r.i na\
oLrrrrY,/ I
\E t

System.out.print ( "s is a String" ) ;

]
)
edbeisto:sisaString
Mesmo se o objeto testado nio for realmente uma instanciagio do tipo de classe que estiver do lado direito do operador,
instanceof ainda retornari verdadeiro se o obfeto puder ser atribuido a esse tipo.
O exemplo a seguir demonstra o teste em um obf eto com o uso de instanc eof ,p^r saber se ele 6 a instAncia de um
dos seus subtipos, antes de se tentar urna conversio "redutora":

class A i )
cl-assBextendsA{
public static void main (String IJ args) {
AmyA=newBO;
m2 (myA) ;
]
public static void m2 (A a){
if (a instanceof B)
( (B) a) . doBstuff ( ) ; / / convertendo uma refer6ncia A

/ / em ttma refer6neia B
]t
public static void doBstuff O {
SysLem.out.println(\\a' refers to a B");
]
]
O c6digo acima compila e produz esta saida:
'a' refers to a B
Emexemploscomoesse,ousodooperadorinstanceof protegeoprograrnacontraatenativadetentarumaconversio
invdlida.

Voc6 pode testar a referencia a um objeto confrontando-a com seu pr6pdo tipo de classe ou com qualquer uma de suas
superclasses. Isso significa que quaQaerreferdncia a um obieto seriavahada como verdadeira se voc6 usar o operador
instanceof junto ao tipo Obj ect, da seguinte forma,
JAVA 5 167
Bb=newBO;
if (b insranceof Object) {
System.out.print("b is definitely an Object,,) ;
i
que edbit6:

b is definitely an Object

oBSERVA9oSS pARA O EXAME


Pron'm perguntas eom instanceof que testem u um objeto i a instincia de lma interface, qaando a classe do objxo for implenentada
indiretamente. Una implenentagdo indinta ocore quando ma das superc/astes do oQeto implementa una intetface, ,^ i pnlpio classe da
institcia ndo ofaq- por exenplo,

interface roo { }
class A implements Foo { }
classBextendsAi )

Aa=newAO;
Bb=newBO;
ot rerultados a seguir rcrdo aerdadeims:

a instanceof Foo
b instanceof A
b instanceof Foo // implementado indj-retamente
Un objeto seri considerado de un tipo de inhrface especifn (igfieando que pasuni no te$e lnsEanceof) se algama de suas
wperclasnt implementar a inteface.

Al6m dissq 6 vilido testar se a refer6ncia de um objeto nu11 6a instincia de uma classe. Isso sempre resultar6 em
f aI se, € claro, Por exemplo:
class InstanceTest {
public static void main(String [1 args) t
String a = null;
boolean b = nul1 instanceof String;
boolean c = a instanceof String;
System.out.println(b + " " + c) ;
)

)
exibe isto: f al, se f al- se

Erro de Compilagio de instanceof


Nio6 possivel usar o operador instanceof para testar em duas hierarquias de classes diferentes, Por exemplo, o
seguinte c6digo ndo comptlatil:

class cat { }
class Dog {
public static void main(String tl args) {
Dogd=newDogO;
System.out.println (d inst.anceof Cat) ;
)

)
A compilagio fdha - d iamais poder6 se referir a um Cat, ou a um subtipo de Cat.
168 Copirulo 4: Operodores
oBSERVAQ6ES pene o EXAME

I-embre-v que os aralr sdo objetos, mesmo quando armaqenam tipos prinitiuos. Procure ddigot qae Po$am ter e$a @at€ncia na petganta:

int [] nums = new int [3] ''


if (nums inst.anceof object) { } tt o resultado 6 true
Um anal rcnl rcmpre uma instdncia de Object. paalquer aray

A Tabela 4-1 resume o uso de instanceof presumindo-se o seguinte:


interface face { }
class Bar implements Face{ }
class Foo extends Bar { }

Iobelo 4-1 Operondos e resultodos do uso do operodor instanceof

Primeiro opetando Opemndo de instanceoj Resultado


(refer€ncia sendo testada) (tipo que compararemos
com a tefer€ncia)

null Qualquer tipo de interface ou classe false

instincia de Foo Foo, Bar, Face, Obiect

instincia de Bar Bar, Face, Object

instincia de Bar Foo false

Foo[ ] Foo, Bar, Face false

Foo[ ] Object

Foo[1] Foq Bar, Face, Object

Operadores aritm6ticos
Temos certeza de que vocd est6 familiaizado com os operadores aritrn6ticos b6sicos.
I + adiglo
I - subtragio
I x multiplicagio
I / divisio
EIes podem ser usados da maneira padrio:
int x = 5 * 3;
intY=x-4;
system.out.println("x - 4 is " + y); // Exibir6 11

O Operador Resto (o/o)


Um operador com o qual vocd pode n6o estar familiaizado 6 o operador de rcstooh. O operador de resto divide o
operando esquerdo pelo direito com o resultado sendo o resto, como o c6digo abaixo demonsffa:
class MathTest {
public static void main (string il args) {
int x = 15;
intY=x*4;
Swstem.ouf nrint-ln/"fhe rcsuft of L5 ? 4 is the remainder of
L5 divided by 4. The remainder is " + y) ;
1

)
JAVA 5 169
A execugSo da classe MathTest exibiri a linha a seguir:
The resul-t of 15 ? 4 is the remainder of 15 divj-ded by 4. The remainder is 3

(I-embre-se: As express6es sio avaliadas da esquerda p an dlteita,por padrio. Voc6 pode modificar essa seqriencia, ou
pmceddncia, adicionando parenteses. Lembre-se tamb6m de^que os opetadores *, / e %o tdm maior preced€ncia do que os
operadores * e -.)

Operador de concatenageo de strings


O sinal de adigdo tambdm pode ser usado para concatenar duas strings, como vimos anteriormente (e com certeza veremos
de novo):

String animal = "Grey " + ..elephant,,,.


A concatenagZo de Strings se tornari interessante quando voc6 combinar nirmeros com obietos String. Vedfique o c6digo a seguit:
String a = "String";
inl- l.r - ?.

i-nt c = 7,'
System. out.println (a + b + c) ,.

O operador * atuafi, como um sinal de adigZo quando somar as vari6veis int de b + c? Ou ftatara 3 e 7 como
caracteres e os concatenard individualmente? O resultado ser6 Stringl O ou St.ring3 7? Certo, voc€ teve tempo
suficiente para pensar sobre isso. Os valores int foram simplesmente tratados como caracteres e acrescentados i direita
da string. Portanto, o resultado 6:

String3 7

De forma que poderiamos ler o c6digo anterior assrm:


"Comega com a String a, "String", e adiciona o caractere 3 (o valor de b) aela,pataproduzir uma nova string,
"String3",adicionando,ent6o,ocaractereT (ovalordec)aoresultadoparaproduziroutastri.ng,"string3?",e
exibi-la em seguida".
No entanto, se vocd inserit pardnteses envolvendo as duas vari6veis int, como vemos abaixo:
System.out.println(a + (b + c) );
obter6: String1O
O uso de parenteses fat6 com que @ + c) seja tratado primeiro, portanto, o operador 'l fancionat6 como o operador de
adigio, dado que os dois operandos sio valores int. O ponto chave aqui 6 que, dentro dos pardnteses, o operando da
esquerda nio 6 uma String. Se fosse, o operador I execttaiaaconcatenag6o de Strings. O c6digo anterior pode ser
lido da seguinte forma:
"Soma os valores de b + c, em seguida, converte a soma em uma string e corrc tena com a string da
vai|vela". ^

A regra a lembrar 6:

Se um dos operandosfor ama String, o operador I atuari c0m0 um operador de concatenagdo de SLrings, Se ot dois @erandot
forem nilrterot, o operador * funcionani como o operador de adipio.
Em algumas situag6es voc6 poderi ter problemas para descobrir se, digamos, o operador da esquerda 6 ou nio uma
String. No exame, nio espere que isso seja 6bvio. (I.{a verdade, i6 que mencionamos nisso, nunca espere que seja 6bvio).
Examine o c6digo a seguir:
System.out.println (x.foo O + 7) ;
Voc6nioter6meiosdesabercomoooperador* est6sendousadoat6quedescubraoqueom6todo foo ( ) tetotnarilt,
Se retornar uma seri concatenado a string retornada. Mas se f oo (
SLring, entio,T ) retornar um nfmero, o
operador* serdusadoparasomaro algarismo 7 comovalorretornadopor foo ( ).
Finalmente, voc€ ptecisa sabet que 6 v6lido mistutar o operador aditivo composto (*=) com Strings, desta forma:
String s = \\A23"i
s += "45";
s += 67;
System. out. printl_n (s) t
Umavez que nos dois casos o operador += foi usado, e o operando da esquerda era uma String, ambas as operagdes foram
concatenag6es, resultando em

L234567
I Z0 Copitulo 4: Operodores

oBSERVAQoTSpeneTXAME
Se aocd ndo compreendtr eomo a couatenaj1o de Stringsfunciona, principalmente dentm de ma instrufio de saida, podeni realmente ser mal
sucedido tt7 examq mesmo y soaber o retto da reposta i pergunta! Ji que tantas petglntat indagam, "pual rcni o resultado?", uoc| ptvcisa
taber tdo s6 qual a saida do ctidigo que eftiuerrcndo mas tambdm c0m0 esse resultado rcni. exibido. Mesmo bauendo pelo menot
neia di{a peryuntas que nriarAo diretamente seu conhecimento em strings, a eoncatenagdo de ftrings @ancenl em outras petguntas
d.e
de

cada objetiuo. Faga um teste! Por exenpk, uoc6 pode aer uma linha como

int b = 2;
System.out.print.ln(*\r + b + 3);
qae exibiri

z5

mas se a inshtgdo de saidafor alterada para

System.out.println(b + 3) ;
entdo, o resultado serti 5.

Acr6scimo e decr6scimo
A linguagemJava possui dois operadores que aumentario ou diminuirio uma vari6vel em exatamente uma unidade. Esses
operadores sAo compostos por dois sinais de adi96o (++) ou dois sinais de subtraglo ( -):
I ++ acr6scimo (ptefixo e sufixo)
I - - decr6scimo(prefixoesufixo)
O operador 6 inseddo antes (prefixo) ou depois (sufixo) de uma variivelpan alterar o valor. O fato de o operador vir antes
ou depois do operando pode alterar o resultado de uma expressdo. Examine o c6digo abaixo:

1. class MathTest i
2. static int PIaYers = 0;
3. public static void main (String [] args) {
4. System.out.println("players online: " + players++);
5. System.out.println("The value of players is " + players);
6. System.out.println("The value of players is now " + ++players);
7. )
8. )
Observe que na quarta linha do progtam ,o operador de incremento esta depois d^v^i6vel players. Isso significa que
estamos usando o operador p6s-fixado, o que far6 com que a variivel players seia aumentada em umavnidade, mat
sonente dEois que nu aabrfor uvdo na expresdo. Quando executarmos esse Programa, ele exibir6 o seguinte:
?java MathTest
players online: 0
The value of players is 1
The value of players is now 2
Observe que quando avai6vel6 exibida na tela, primeiro informa que o valor 6 igual a 0. J6 que usamos o operador de
incrementop/r-fxado,oacr6scimondoocouer6.at6omomento ap6savai6velplayers serusadanainstrugiodesaida.
Entendeu? A paniculapris de p6s-fixado significa depois. Allnha seguinte, a de nri.mero 5, n6o aumenta o valor de play-
ers ; apenas o exibe na tela, portanto, o valor rec6m-aumentado a ser exibido ser6 1. A linha 6 aphca o operador pre-fxado
a players, o que significa que o acr6scimo ocortetS. antesque o valor da van6velseiavsado (pMsigrtrfrcz antet). Portantq a
saida ser6igaal a2.

Espere por perguntas que combinem os operadores de incremento e diminuigio com outros operadores, como no
exemplo abaixo:
irlLx=2;
int Y = 3t
if ((Y -= x++) | (x < ++Y) ) {
System.out.println(<x = < + x + < y = < + y);
)
JAVA 5 17]
Oc6digoanteriorexibirix = 3 y =4
Voc6 pode ler o c6digo assim: "Se 3 for'rgoaIa2 OU menor do que 4..."

Aprimeiraexpresslocompar^x ey,eoresultado6false,potqueoacr6scimodex n6ooconer6antesqueotestedo


operador == seia executado. A seguir, aumentamos x e agora ele €.igad,a 3. Depois verificamos se x 6 menor do que y,
msailmentamlroualordey antesdecompari-locomxlPortanto,osegundotestel6gico6(3<4).Oresultado6t,rue,de
modo que a instrugZo de saida ser6 executada.

OBSERVAQ6ES pene O EXAME


Pmcare petgantas qlrc usen ot operadoret dc inmmento e dininligdo em uma aaridae/ f inal-,. Jd que as uaridaeis f i na I n6o podem ser
aheradas, os operadoret de inmmento e dininuQdo ndo poderdo ser asados com eks e qraQuer hntatiua defaTgr ilro wvltari em am ero do
compilador. O aidigo a nguir ndo nni co@ilada,

finalintx=5;
int y - x++,.
epmdt$ni o erm

Test.java:4: cannoL assign a value to final variable x


int y = x++i
Voc6 pode esperar uma violagio como essa camuflada em um trecho complexo de c6digo. Se identifici-la, saber6 que o
c6rligo nio seri compilado e poderi prosseguit sem percorrer o resto do c6digo.
Pode pareeer que essa qautdo uhi testando o seu conhecimento sobre um conplexo operador aitmitico, quando, na aerdade, estd testando o
sea conltecinento sobre o modificador f inal.

Operador condicional
Ooperadorcondicional 6umoperadortemirio(temtr€soperandos)usadoparaavaliarexpress6esbooleanas demodo
semelhante iinstrugio if, exceto por,emvezde executar um bloco de c6digo se o resultado do teste for true, atdbuir
um valor i vari6vel. Em outras palavras, o objetivo do operador condicional 6 decidir qual dos dois valores atribuir a uma
variivel. Ele 6 constnrfdo com os simbolos ? (ponto de interrogagio) e : (dois pontos). Os pardnteses sio opcionais. Sua
estrutura 6 a seguinte:

x = (expressdo booleana) ? valor a atribuir se true: valor a atribuir se f al se


Examinemos um operador condicional no c6digo:
class Salary i
public static void main(String IJ args) {
i-nt numOf Pets = 3;
String status = (numOfPets<4)?,,Pet limit not exceeded,,:,,too many pets,,;
System.out.println(.'This pet status is '. + status) ,.

Voc6 poderia l.r o sfdigo anteriot assim:

"Configura numOf Pets igual a 3. A seguir, atdbui uma String avati|vel starus. Se numOf Pets for menor do que
4, atibur6"Pet limit not exceeded"; do contr4rio, atibwrd"too many pets".
O operador condicional comega com uma operagdo booleana, seguida de dois valores possiveis paraavai|veld,esquerda
do opetador (=). O primeito valot (que fica i esquetda dos dois pontos) set6 atribuido se o teste condicional @ooleano)
tiver um resultado true e o segundo valor seri atribuido se o resultado do teste for f al-so. Voc6 tamb6m pode aninhar
operadotes condicionais em uma insrugio:
class AssignmentOps {
public static void main(String [] args) {
int sizeOfYard = 10;
int numofPetss = 3;
String status = (numOfPets<4) ?,,Pet count OK,,
: (sizeOfYard > 8)? ,,pet limit on the edqe,,
: "too many pets",.
172 Copfiulo 4: Operodores
System.out.printl-n("Pet status is " + status);

Nio espere muitas perguntas que usem operadores condicionais, mas lembre-se de que, is vezes, os operadores
condicionais sio confundidos com as instrugSes assertivas, portanto, certifique-se de poder diferenci6los. O Capinrlo 5
abordari as assertivas com detalhes.

Operadores L6gicos
Os objetivos para o exame especificam seis operadores "l6grcos" (&, | , ^, !, && e | | ). Alguns documentos oficiais da Sun
usam outra terminologia para esses operadores, mas,parz.os nossos prop6sitos, os "operadores l6gicos" sio os seis
listados acima e nos objetivos para o exame.

Operadores Bitwise (Nno Caem no Exame!)


Certo, isto ser6 um pouco confuso. Dos seis operadores l6gicos listados acima, tr6s deles (&, I e ^) podem tamb6m ser
usados como operadores "bitwise". Os operadores bitwise foram incluidos em vers6es anteriores do exame, mas nio caem
no exameJava 5. Eis algumas instrug6es v6lidas que usam operadores bitwise:
byte b1 = 5 & 8;
DVle Dz = t | 9;
nya" Ua = 5 ^ 4;
System.out.println(b1 + " " + b2 + * \r + b3);
Os operadores biwise comparam duas vari6veis bit por bit, e retornam urnavari|vel cujos bits foram definidos com
base em se as duas vaddveis sendo compatadas tinham bits correspondentes que estavam ou ambos "ligados" (&), ou um
ou outro "ligado" ( | ), exatamente 116 "ligado" (^). A prop6sito, se rodarmos o c6digo anterior, teremos
""
015 1

Tendo dito tudo isso sobre operadores bitwise, o principal a se lembrar 6 isto:

OS OPERADORES BITWISE NAO CEPU NO EXAME!


Entio por que falamos deles? Se cair nas suas mios um livro antigo de preparagio para o exame, ou se encontrar alguns
.*"-.i simulados que ainda nio foram devidam ente atualizados, voc€ poder6 se deparar com quest6es envolvendo
operag5es bitwise. A nio ser que se sinta tio culpado a ponto de achar que merece esse tipo de punig6o, pode ignorar esse
tipo de questeo simulada.

Operadores L6gicos de Abreviagio


Hd cinco operadores l6gicos no exarne que sio usados para avaltar instrug6es que contenham mais de uma expressio
booleana. Desses cinco, os mais comumente usados sio os dois opetadotes l6gicos de abreriagAo. Sdo eles:
r && Edeabreviagio
I | | OU de abreviagio
Eles sio usados p^t iunt?Lrpequenas express6es boOleanaS a fim de formar express6es bool-eanaS maiotes' Os
operadores && e | | ava1am somente valores booleanos. Para uma expressio E (&&) ser verdadeira, ambos os
operandos ptecisam ser true - pot exemplo,
if ((2 < 3) && (3 < 4)) { }
A expressio anterior s6 6 true, porque tanto o operando um (2 < 3) quanto o operando dois (3 < 4) slo true.
O recurso de abreviagdo do operador && consiste no fato de ele ndo perder sea tempo em aua/iapder inilteis. O operador de
abrcviagdo && avalar|o lado esquerdo da operagio primeiro (operando um) e se esse operando tiver um resultado f a}se,
ele nio examinar6 o iado direito da equagio (operando dois), ]6 que o operador saber6 que a expressio completa neo ser6
u! uc.

uI4>D lUYrUAf I
public static void main(String [] args) {

boolean b = true && fal-se,'


s\/qram nrrt-.println("bool-ean b = " + b) ;

l
)

Quando executarmos o c6digo anterior, obteremos:


JAVA 5 I73
boolean b = false
O operador | | 6 semelhante ao operador &&, exceto p or ele avaliar como t rue se qualquer tm dot operadoret for t rue. Se
o primeiro operando de uma operagio OU for true, o resultado tamb6m ser6, portanto, o operador de abreviagio | | nio
perder6 tempo examinando o lado direito da equaglo. No entanto, se o primeiro operando for f alse, o operador tera que
avaliar o segundo operando para saber se o resultado da operagio OU ser6 L rue ou f a l- s e. Pteste bastante atengao no
exemplo a seguit; voc6 veri algumas pefguntas como esta no exame:
1. class TestOR {
2. public static void main (String [] args) t
3. if ((isrrsmall(3)) ll (isrrsmall(7))) {
4. System.out.println("Rqsu1t is true");
J

6. if ((isrrsmall(6)) ll (isrrsmall(9))) t
7. System.out.println("Rsgult is true");
8. ]
e. )
10.
l-1. public static boolean isltSmall(int i) {
L2. if (i < s) t
13 . System. out .println ("i < 5" ) ,.

]-4. return true;


r_5. J erse t
l-6. System.out.printLn("i >= 5");
L7. return false;
18. )
t-e. )
20. )

Qual ser6 o resultado?


? java TestOR
1<5
Result is true
i>=5

Aqui est6 o que aconteceu quando o m6todo main ( ) foi executado:


1. Quando chegamos i linha 3, o pdmeiro operando da expressio | | (em ouuas palavras, o lado esquerdo da operagio
I l) foi avaliado.
2 O m6todo isltsmall- (3 ) foichamado, exibiu "i < 5" eretornou uerdadeiro.

3. J6queoprimeiroopetandodaexpressio ll,dalinha3,6igalatrue,ooperador llnioavaliar6osegundo


operando. Portanto, nunca veremos a frase "i >= 5", que teria sido exibida caso o segundo operando fosse avaliado
(chamando isItSmall (7 ) ).

4. A linha 6 set6,avaladaagora, comegando pelo primeito operando da expressio | |.

5. Om6todo isItSmall (6) 6chamado,eibe "i >= 5"eretorna faIse.


6. J6queoprimeiroopetandodaexpressio ll,dalinha6,6false,ooperador llnlopoder6ignorarosegundo
true, se o segundo operando for avaliado como true.
operando; ainda h6 uma chance da expressio ser
7. O mdtodo isItSmall (9 ) 6 chamado e exibe "i >= 5".
8. Om6todoisItSmall (9) retornafalse,portanto,aexpressiodalinha66false eahnirraT nuncaser6
executada.

oBSERVAQ6ES pene O EXAME

Osoperadoret &&e ll sdfuncionamcomoperandosbooleanos. Oexamepodetentarengand-lo,usandointeiroscrtltesseroperadoret;


174 Copitulo 4: Operodores
if (s && 6) t )

onde parece que estawts teutando usar am operador bit a bit E nos bits que representam os inteiros 5 e 6, mas o cfidigo lteln Tresmo
seni compilado.

Operadores l6gicos (que nio sio de abreviagio)


Existem dois operadores l6gicos que fio sdo de abreiagdo.

I &Endo-abreviado
I I OU nio-abteviado
Esses operadores s6o usados em expressdes l6gicas, assim como os operadores && e | ; por6m, j6 que ndo sdo os|
operadores de abreviagio, aualiardo os dois ladw da exprusdo, semprclBles serio ineficientes. Por exemplo, mesmo se o primeiro
operando (ado esquerdo) de uma expressio & for f al se, o segundo tamb6m seri avahado - ainda que agora tenha n
tonado impossiuel o resultado serErue/E o operador I ser6 ineficiente na mesma medida; se o primeiro operando for true,
ele a;nda dati prosseguimento e avahatS" o segundo operando, mumo quando souber q*e a expressdo seri Erue.

No exame, voc€ veri muitas perguntas usando tanto operadores l6gicos de abrciagdo quanto os que nio usam a abreviag6o.
Voc€ ter6 que saber exatamente quais opetandos sefao avaliados e quais ndo serlo, jique o resultado variar|se o segundo
opetando da expressio for ou n6o avaliado:
1nt z = 5;
if(++z r 5 (ll ++z > 6) z++i // z = 7 depois deste c6digo
contra:
int z = 5;
if (++z > 5 | ++z > 6) z++; // z -- 8 depois deste c6digo

OperadoresL6gicos ^ e!
Os dois ultimos operadores l6gicos no exame s6o
I ^ OU exclusivo (XOR)
I !inversiobooleana
O operador ^ (OU exclusivo) avalia somente valores booleanos. O operador ^ relaciona-se com os operadores de nio-
abreviagio que acabamos de revisar, no sentido de que sempre ava)ia ambot os operandos, o do lado direito e o do lado
esquerdo, em uma expressio. Pata uma expressio OU exclusivo ( ) set verdadeira, EXATAMENTE um operando precisa
ser Lrue - por exemplq
system.out.println("xor " + ( (2<3) ^ (4>3) ) );
produz asuda; xor false
A expressio actma avaJia como f al se porque TANTO o primeiro operando (2 < 3) quanto o segundo (4 > 3) avdtam
como crue.
O operador ! (inversio booleana) retorna o oposto do valor atual de um booleano:
if ( l (? == 5) ) { Sysfem.out.println("not equal") ; }

pode ser lido como "se nio for verdade que 7 == 5", e a instrugio produz esta saida:
not egual
Eis um ouuo exemplo usando booleanos:
boolean t = true;
boolean f = false;
System.out.prinLln("! " + (t & !f) + " " + f);
produz asuda:
! true false
No exemplo anterior, repare que o teste & teve sucesso (exibindo true), e que o valot da variavel booleana f n6o se
modificou, de modo que ela exibiu f alse.

Se voc6 estudou este capinrlo atentamente, deve tet obtido uma compreensio s6lida sobre os operadoresJava, e dever6
saber o que significa igualdade, quando seu conhecimento sobre o operador == for avaliado. Recapitr:lemos os Pontos
JAVA 5 I75
importantes do que voc€ aprendeu neste capitulo.
Os operadores l6gicos (&& e I l) s6 podem ser usados para avaliar duas express6es booleanas. A difetenga entre && e
& 6 que o operador && n6o se preocupari em testar o operando direito, caso o esquerdo for avaliado como f aI se, pois o
resultado da expressio && nunca pode ser true. A diferenga entre | | e | 6 que o operador | | n6o testar6 o operando
direito se o esquerdo for avaliado como true, porque o resultado i|setkrcconhecido como nesse momento. true
O operador -- pode ser usado p^r comp^rar valores de tipos primitivos, mas tamb6m pode ser empregado para
determinar se duas variiveis de refer6ncia referenciam o mesmo objeto.
Ooperadorinstanceof 6usadoparadeterminarseoobjetosendoreferidoporumavari6velderefer€nciapassano
teste E-UM para um tipo especificado.
Ooperador* 6sobrecarregadopanteahzartatefasdeconcatenaglodeStrings,epodeconcatenartamb6mStrings
com tipos primitivos, mas curdado - essa operagio pode ser complicada.
O operador condicional (tamb6m conhecido como "operador temirio') tem uma sintaxe incomum, com tres operandos -
nio a confunda com uma instrugio assert complexa.

Os operadores **s - - sereo usados em todo o exarne, e voc6 deve prcstzraatengdo a se eles s6o prefixados ou posfixados
ivaridvel que esti sendo atuaJizada.

Prepare-se para muitas perguntas no exame envolvendo os t6picos deste capihrlo. Mesmo em perguntas que testarem seu
conhecimento referente a outro obfetivo, o c6digo freqiientemente estar6 usando operadores, atribuig6es, passagem de
objetos e tipos primitivos, e assim por diante.

,/ Exercfcios r6pidos
Aqui estlo alguns pontos-chave de cada segio deste capitulo.

Operadores de comparageo (Objetivo 7.6)


E Os operadores de compangdo sempre resultam em um valor booleano (t.rue ou f alse).
El H6 seis operadores de comparagao: ), )=, (, (=, == s l=. Os dois ultimos (-- .l-) sio, is vezes, chamados de
operadores de igualdade.

Q Quando compata car cteres, a linguagemJava usa o valot Unicode do caractet como o valor num6rico.

fl Operadores de igualdade

E Quatro tipos de itens podem ser testados: nirmeros, caracteres, booleanos, vari6veis de referdncia.
E Hi dois operadores de igualdade: == s l=.
Q Ao comparar vai|veis de refer€ncia, == retotna true somente se ambas as refer€ncias apontatemparao mesmo
objeto.

Operador instanceof (Objetivo 7.6)


E instanceof s6 6 usado com variiveis de refer6ncia e verifica se o obieto 6 de um tipo especifico.
EI O operador instanceof s6 pode ser usado par^testr objetos (ou valores nuI1) confrontando-os com tipos de
classe que esteiam na mesma hieratquia da classe.

E Para intedaces, um obieto passa no teste instanceof se alguma de suas superclasses implementar a interface do
lado direito do operador instanceof .

Operadores aritm6ticos (Objetivo 7.6)


Cl H6 quatro operadores principais: adigio, subtragio, multiplicaglo e divislo.

E O operadot de testo (o/o) rctotnao resto de uma divis6o.


El As express6es sio avaliadas da esquerda p ata a dtreita,a n6o ser que voc€ adicione par6nteses, ou que alguns operadores
na expressio tenham maior preceddncia do que outros.

f,l Os operadores *, / e %o t6m maior preceddncia do que * e -.

Operador de concatenageo de strings (Objetivo 7.6)


f,l Se um dos operandos fot uma String, o operador * concatenat6" os operandos.
B Se os dois operandos forem num6ricos, o operador * somatl os operandos.
176 Copitulo 4: Operodores

Operadores de acr6scimo/decr6scimo (Objetivo 7.6)


D O opetador pr€-fixado 1+ + e -_) seri executado antes do valor ser usado na expressio.
E O operador p6s-fixado 1++ e --) ser6 executado depois que o valor for usado na expressio.
E Em qualquer expressiq os dois operandos sio avaliados integralmente antes que o operador se ia aphcado.
O O valor das variiveis f inal nio pode ser aumentado ou diminuido.

Ternirio (operador condicional) (Objetivo 7.6)


D Retorna um entre dois valotes baseando-se nos casos de uma expressi.o booleana ser true ou f alse.
E Retotna o valor depois de ? se a expressio for t rue
E Retorna o valor depois de : se a expressio for f a1se.

Operadores l6gicos (Objetivo7.6)


E O exame aborda seis operadores l6gicos: &, l, ^, !, && e | | .

D Os operadores l6gicos trabalham com duas expressSes (exceto ! ) que devem resultar em valores booleanos.
fl Os operadores && e & retornario Erue somente se os dois operandos forem uerdadeiros.
E Os operadores | | e I retornario true se um ou os dois operandos forem uerdadeims.
Q Os operadores && e | | sio conhecidos como operadores de abreviagio.
D O operador && ndo avahard o operando direito se o esquerdo for f a 1 se.
E O operador | | ndo avahat6ooperando direito se o esquerdo for true.
fl Os operadores & e I sempre avallamos dois operandos.
Q O operador ^ (chamado de "XOR l6gico') retorna t rue se exatamente um operando for verdadeiro.
E O operador I (chamado de operador de "inversio'), retorna o valor contr6rio do operando booleano que o precede.

Teste individual
l. Dado:
class uexy {

-,,L1
I ^ ^!-+i ^
"roi-d main
- (Srring [] args) {
Integer i = 42;
String s = (i<40) ?"1ife": (i>50) ?"universe" t"everything";
System. out.prinLln (s) ;
i
)

Qual 6 o resultado?
A. null
B. life
C. universe
D. everything
E. Acompilagio falha.
E E langada uma excegio no tempo de execugio.

2. Dado:
1. class Example {
2. public static void main(StringlJ args) {
3. Short s = 15;
JAVA 5 I77
4. Boolean b;
5. // insira o c6digo aqui
o. l
7. \
Qual opgio, inserida indepentemente na linha 5, ir6 compilar? (I\zlarque todas as corretas)
A.b = (Number instanceof s) ;
B. b = (s instanceof Short);
C. b = s. instanceof (Short) ;
D. b = (s instanceof Number);
E. b = s. instanceof (Object) ;
E b = (s instanceof String);
3. Dado:
1. cl-ass Comp2 i
2. public st.atic void main(Stringtl args) t
3. fl-oat f1 = 2.3f ;
4. floar n il f2 = {{.42.0f1 , {t.tt, 2.3tll , {2.6f., 2.tf}} ;

s. float tl t: = {z.tt} ;
6. Long x = 42Li
7. // insira o c6digo aqui
8. System.out.println("true");
ol )

10. i
E os cinco seguintes fragmentos de c6digo:
F1. if (fr == 121
EZ. :tlC.
r!\!r <^r^I r.l\
== LZLZJLLJ)
F3. if (x == f2 iol tol )
F4 . if (f1 == f2 lr,rl )
Fs. if (f3 == f2 L2) )

O que 6 verdadeiro?

,{. Um deles compilari, apenas um ser6 true.


B. Dois deles compilario, true.
apenas um ser6

C. Dois deles compilario, dois serio true.


D. Tr€s deles compilardo, apenas um ser6 true.
E. Tt6s deles compilario, exatamente dois serio true.
F. Tr€s deles compilareo, exatamente tres sereo true.

4. Dado:
crass lorK t
public static void main(stringlJ args) t
if(args.length == 1 I args[1J.equals("test")) t
System. out.println ( "test case" ) ;
) else {
System.out.pri-ntln("production " + args [0J ) ;
)

)
178 Copftulo 4: Operodores
E a chamada de linha de comando:
java Fork 1ive2
Qual 6 o tesultado?
A- test case
B. production
C. tesE case live2
D. Acompilaglofalha.
E 6 hngada uma excegio no tempo de execugio.

5. Dado:
class Foozit {
public static void main(String[] args)
fnt.eger x = 0;
Integer y = 0;
for(Short z = 0; z < 5i z++)
if( (++x > 2) I | (++y > 2) )
x++ r.

System.out.println(x + s \ + y) ;
)

Qual 6 o resultado?
A-51
8,5 2
c.s3
D.81
882
883
G.102
rL10 3
6. Dado:
class Titanic {
public static void main(StringlJ args) {
Boolean b1 = true;
boolean b2 = false;
boolean b3 = true;
if ((br- & b2) | (bz e b3) & b3)
System. out .print (..alpha ., ) ,-

if ((b1 = false) | (b1 & b3) (b1 | b2))


|

System.out.print ("beta *) ;
)

Qual 6 o resultado?
,{.. bet,a
B. alpha
C. alpha beta
JAVA 5 I79
D. Acompilagdofalha.
E Nio 6 produzida nenhuma saida.

E E langada uma excegao em tempo de execug6o.

7. Dado:
class Feline {
public static void main(StringlJ args) {
Long x = 42L;
Long Y = 44Li
System.out.prlnt(\\ \\ + 7 + 2 +.. ..),'
System.out.print(fooO + x + 5 + ,' .,);
System.out.println(x + y + fooO);
]
static String foo O { return "foo"; }
)

Qual 6 o resultado?
A" 9 foo47 86foo
8.9 foo47 4244foo
C. 9 foo425 86foo
D.9 foo425 4244foo
E 72 foo47 86foo
n 72 foo47 4244foo
G. 72 foo425 86foo
I+ 72 foo425 4244foo
I. Acompilagdofalha.

8. Coloque os fragmentos no c6digo para produzar a saida 33. Obseryagio: voc6 deve
usar cada fragmento exatamente uma vez.
class Incr i
public static void main(StringlJ args) {
Integer x = 7;
i-ntY=2;

System. out.println (x) ;

)
FRAGMENTOS:

Y v Y v
Y x x
*= *=
I80 Copitulo 4: Operodores

9. Dado:
1. class Maybe {
2. public static void main(Stringtl args) {
3. boolean b1 = t.rue;
4. boolean b2 = false;
5. system.out.print(!fatse ^ fatse) ;
6. system.out.print(* $ + (!b1 & 1bz = true)));
7. system.out.println(' " + (b2 ^ b1)) ;
8. )
q]
'. )

O que 6 verdadeiro?

,d true.
A linha 5 produz
B. A linha 5 produz false.
C. A linha 6 produz true.
D. A linha 6 produz false.
E A linha 7 ptodtz true.
E AlinhaTproduzfalse.
10. Dado:
class Sixties {
pubtic static void main(StringtJ args) {

int x = 5; int y = 7;
System.out.print(( (y * 2) Z x)) ;
System.out.print(" " + (y ? x) );
i
)

Qual 6 o resultado?
A-11
B.L2
c.21,
D.2 2
E.41
F.42
G. Acompilagdofilha.
H. E langada uma excegao em tempo de execugio.

Respostas
1. D est6 correta. Este 6 um ternirio aninhado dentro de um ternario com um pouco de unboxing funto. Ambas as
express5es tern6rias slo falsas.

A5 B, C, E e F estio incortetas com base no exposto acima. (Objetivo 7.6)

2. B e D usam cottetamente boxing e instanceof juntos.

A estd incorreta porque os operandos est6o invertidos. C e E usam sintaxe instanceof incorreta. F estl errada
porque Short nio est6 na mesma 6rvore de heranga que String. (Obietivo 7.6)

3. D est6 correta. Os fragmentos F2, F3 e F5 compilario, e apenas F3 6 true.


JAVA 5 I8I
4 B' C, E e F estio incorretas. F1 esti incorreta porque nio 6 possivel comparar um tipo primitivo com um anay.F4
usa sintaxe incoffet^Par^^cessar um elemento de um array bidimensional. (Obietivo 7.6)

4. E est6 correta. Pelo falo


{e
a abteiragdo ( | | ) neo ter sido usada, ambos os operandos sio avaliados. Uma vez que
args[1] esta^l6mdoslimitesdoanayargs,6,langadaumaArraylndexQutOfBoundsExr':ention
A B, C e D estio incorretas com base no exposto acima. (Objetivo 7.6)

5. vezes em que o teste i f 6 execuadq tanto x como y sio incementadas uma vez (s6
E esti correta. Nas duas primeiras se
alcangax++ natercekaitetagno).Apartirdatercaraiteragdodoloop,y nuncamais6usadqporcausadooperadorde
abrevia$o

4 B, C, D, F, G e H est6o incorretas com base no exposto acima. (Objetivo 7.6)

6. E est6 cotteta. No segrrndo teste i f , a expressio mais i esquerda 6 uma aribuigio, e nio uma comparagio. Depois que
b1 foi definido como f al-se. os demais testes sdo todos f al-se.
A B, C, D e F estio incorretas com base no exposto acima . (Objetivo 7.6 )

7. G est6 correta. A concatenagio roda da esqu erdz pata z dtreita e, se algum dos operandos for uma S t r i ng, os
opetandos s6o concatenados. Se ambos forem nrimeros, eles sdo adicionados um ao outro. O unboxing funciona em
coni unto com a concatenagdo.

A B, C, D, E, F, H e I estio incorretas com base no exposto acima . (Objetivo 7.6)

8.

class Incr {

1,ularg ELdLru -void main(String[] args)


--,,h1 l^ ^r-rl^ t
Integer x = 7;
int Y = 2,
x*=x;
rr *-
r - rr.
r,
Y*=Yi
x_=y;
System. out . println (x) ,'

Sim, sabemos que isso 6 complicadq mas voc€ poder6 encontrar algo parecido no exame real. (Obietivo 7.6)

9. ADeFestiocorretas.O^(xor) tetorn true seexatamenteumoperandofortrue.O !inverteovalor


booleano do operando. Na linha 6,b2 = true 6 uma atribuigio, e nio uma comparagdo, e n6o 6 avaliada potque
& nlo serve d e abrcizgdo para ela.

B, C e E estao incorretas com base no exposto acima. (Obf etivo 7.6)

10. F est6 correta. O opendoroh (resto, tamb6m conhecido como m6dulo) retorna o resto de uma operagio de divis6o.

A B, C, D, E, G e H estAo incorretas com base no exposto zcin,:'a . (Objetivo 7.6)


182 Copftulo 4: Operodores
Controle de fluxo,
excesoes e
assertivas

Obierivos pqrq q
certificqe6o
I Usor InstruE6es if e switch

I Desenvolver Loops {or, do e while.


Usor Instruq6es breok e continue

I Desenvolver C6digo com Assertivos

I Usor lnstruq6es try cotch e {inolly

I Descrever o Efeiio dos ExceE6es

I Reconheceros Excec6es mqis


Comuns

( Exercicios r6pidos

P&R Teste individuol


.|84
Copitulo 5: Controle de fluxo, exceg6es e ossedivos
VocA consegr.re imaginartentando escreverum c6digo com umalinguagem que.n|g fornepauma maneira de executar
se
insru96es clondicionimente? O controle de fluxo 6 uira parte chave de quase ioda linguagem de programaXg qil , e alava
oferecl virias maneiras de execut4-lo. Algumas, como asinstrug6es i f i loops f or, iio comuns i maioria das linguagens.
Mas aJava tamb6m introduz algon, ,e.rriror de controle de fluxo que voc6 pode nlo ter usado antes - exceg6es e assenivas'

As instrug6es i f
e swi tch sio tipos de controles condicionais/de decisio.que permitirio aseu pro gramaagt de
ma.reira em uma "bifurcaglo do caminho", dependendo do resultado de um teste l6gico. A linguagemJava
iif..enre
fornece tr|s estruturas de loop difeientes - f or, whi Ie e do - portanto,
-As
voc6 poderi executar o mesmo c6digo
repetidamente ar6 que o res"hrao ae Agu-a condigio seja true. exceg6es the proporcionario,uma maneira simples e
limpa de organizarts c6digos e de lidar com ot proble*as que poss-am surgir no tempo de execugio. Para concluir, o
*"i*ir*o"d" asserrivas, aJicionado a linguagem na versXo 1 .4, lhe fornecer6 um meio de executar verificag6es de depura$o
-o
em condig6es que vod queira expor durante desenvolvimento, quando nio quiser ou precisar gerar a sobrecarga no temPo
de execugXo associada i manipulagio de exceg6es.

Com essas ferramentas, vocA poder6 desenvolver um programa robuso, capaz de manipular qualquer.situaglo l6gica com
sofisticaglo. Espere virias pergunras no exame que incluam o controle de fltrxo como pane de seu c6digo' at6 mesmo
aquelas que nio estiverem avaliando especificamente seu conhecimento sobre esse asstrnto.

Obietivo poro o certificoc6o

Escrevendo o c6digo usando instrus6es if e switch


(Objetivo 2. I do exame)
2./ Escreuer cfidigo qae inplenente ama instrugdo f ou switch; identifcar os tipos de atgunentr uti/idos para essas in.rtrapda.

As instrug6es i f e swi tch geralmente sio conhecida s como inshwpdes d.e decisd.o. Quando voc6 usar instrug6es de decisio
em seu programa, estar6 solicitando a ele que avalie uma expresslo especifica a fim de determinar que curso de a$o tomar.
Examinaremos primeiro a instrugio i f .

Ramificagio if-else
O formato bisico de uma instrugio if 6o seguinte:
if (expressdoBooleana) {
System.out.println( "conte\ido da instruqdo if" ) ;

A expresslo entre par6ntes es deaeter corrro resultado um valor booleano true


ou f alse. Normalmente voc6 testari
algo para sabe r se 6, uerdadeiro e, em seguida, executar6 um bloco de c6digo (uma ou mais instrug6es) se o resultado for
mesmo uerdadeim e (opcionalmente) outro bloco de c6digo se nio o for. O c6digo a seguir demonstra uma instrugio i f
vAlida:

if (x>3) {
System.out.println("x is greater than 3");
) else {
System.out.println("x is not gfreater than 3");
]
O bloco e1 se 6 opcio nal, portanto, vocA tamb6m poderia usar o seguinte:
if (x>3) {

]
z L- a.

a=y+X;
Oc6digoanterioratribuir|ovalor2ay seotesteforbemsucedido(isto6,sex forrealmentemaiorque3),masas
outras duas linhas tamb6m serio executadas independente disso. At6 mesmo as chaves serio opcionais se voc6 s6 tiver uma
instrugio a executar dentro do corpo do bloco condicional. O c6digo do exemplo abaixo 6 vilido (embora nio seja
recomendado por raz6es de legibilidade):

if (x > 3l / / n6o recomendado, mas poder6 aparecer no exame


JAVA 5 I85
Y=2i
z += 8;
a-y+x,.
A Sun considera como boa pr6tica colocar blocos dentro
de chaves, mesmo que s6 haia uma instrugio no bloco. Seja
cuidadoso com c6digos como esse, porque voc6 pode pensar que ele deve sei lido assim:

"Se xfor maior qrc 3, mtdo nnfgurc-1t eoa 2, qcom !8 e a comJlx".


Contudo, as duas riltimas linhas serio executadas de qualquer forma! Elas nio {azempane dofltxo condicional. VocA o
acharia ainda mais confirso se estivesse recuado como vemos abaixo:
if (x>3)
Y=2;
z += 8;
a=y+x;
Podesernecessirioaninhar_insrug6es if-else(emboratamb6mnXosejarecomendadoporraz6esdelegibilidade,
poftanto' testes i f aninhados devem ser mantidos em uma quantidade minima). Voc6 poder6 configurar uma instrugio
fehe p.ara que teste v6rias condig6es. O exemplo abaixo usa duas condig6es de modo que r o primeiro teste for bem
sucedido, executaremos um segundo teste antes de decidir o que fazer:

if (price < 300) {


hl11tDr^.11r^t a \ .

] else {
if (price < 400) {
getApproval ();

]
a'l co f

dontBuyProduct ( ) ;
J

)
Issonostrazaooutroconstrutorif-else,oif,e1se if,else.Oc6digoanteriorpoderia(edeveria)serreescrito
como:
if (price < 300) {
l.urrrDrnArra+
vsjrrvvseu\/, / \ .

] else if (price < 400) {


getApproval ();

) else {

dontBuyProduct ();

]
Existem algumas regras para o uso de eI se e de el s e i f :
I Voc6podeterumounenhumelse paraumdadoif,eeledevevirdepoisdequaisquerinstrug6eselse if.
r Vocdpodeterdemuitosounenhumelse if paraumdadoif,eelesdevemvirantesdoelse (opcional).
I Depois que um else tem sucesso, nenhum dos demais else i f ou else ser6 testado.

O segqnte glemplo mostra um c6digo horrivelmente formatado para o mundo real. Como vocA provavelmente j6
adivinhou,_6bastante prov6vel que encontre ese tipo de formatagio no exame. De qualque r f.orma,o codigo dernonstra o
uso de mriltiplos e lse i f :

int x = 1;
if(x==3){}
el-se if (x < 4) {System.out.println("<4"); }
else if (x < 2) {System.out.println("<2"); }
else { System.out.println("e1se") ; }
186 Copitulo 5: Controle de fluxo, exceE6es e qssertivos

O exemplo produz estasaida:


<4

(R.epareque,mesmoqueosegundoelse sejaverdadeiro,aexecugionuncachegaaele.)

Emalgunscasos,voc6podeterdificuldadesemdescobrircomqualif oseuefse deveserpareado,comoneste


exemplo:
if (exam.doneO )

if (exam.getScoreO < 0.61)


q1/ctam
ujeevlrL.vsu.y!rrru+nrrt- nrin1- lnlt\Tr\/ aa:in "):

/ / A qoa\ if isto pertence?


el-se System.out.println("Java master! ") ;

Intencionalmente neo usamos o recuo nesse trecho de c6digo, portanto, ele nXo fornece pistas sobre a que instrugio i f a
cliusula else perrence. VocA conseguiu descobrir? As normas da linguagemJava determinam que uma cl6usula else
pertencerl ) initrugXo i f mais pr6ima a qual ela possivelmente pertenga (em outras palavras, i instrugio i f anterior
mais pr6xima que nio tenha uma cl6usula Llse). No caso do eximplo anterior, a cl6usula else pertencei segudn
instruglo i f da listagem. Com o recuo apropriado, a instrugio teria e$e formato:
if lavam Aana/\\

if (exam.getscoreO < 0.61)


System. out.println ( "Try again. ");
// A gual if isto pertence?
el-se
System. out.println ( ".fava master! ");

Seguindo nossas conveng6es de codificaglo que faz uso de chaves, ela ficaria ainda mais f6cil de ser lida:
if (exam.doneO ) {
if (exam.getscoreO < 0.61) {
System. out.prj-ntln ( "Try again. ");

/ / A qoa1- if isto pertence?


)e1se {
System. out.println ( ",Java master I " ) ;
)

No entanto, nio comece a ficar esperangoso pensando que os c6digos das perguntas do exame e$areo todos
apropriadamente recuados. Alguns candidatos t€m at6 uma frase de efeito para a maneira como as perguntas sio
apresentadas: tudo que puder ser feito de maneira mais confusa, assim seri.

Esteja preparado para perguntas que al6m de nio recuarem os c6digos apropriadamente, o fario intencionalmente de
maneira confusa: preste bastante atengio em distragSes como a do exemplo a seguir:

if (exam.done O )

if (exam.getscoreO < 0.61)


System. out.println ( "Try again. ");
else
System.out.println("rTava master!"); / / Hmmmmm.'. e isLo aqui vai para onde?
E claro que o c6digo anterior 6 exatamente o mesmo dos dois rlltimos exemplos, exceto pelo seu formato.

Express6es v6lidas para instrug6es if


As instrug6es i f s6 podem avaliar valores booleanos. Qualquer expressio que tenha como resultado um valor
booleano seriadequada,masalgumasdelaspodemsercomplexas.SuponhamosquedoStuff ( )retornetrue,
int Y = 5,'
int x = 2;
if (((x > 3) && (y < 2)) | aostuttt)) i
q\rql-om nrrf nrinf lnl"rrrra/1.
JAVA5 187
)

queodbiri

anterior assim: "Se tanto (x > 3) quanto (y < 2) forem t rr-re ou se o resultado de dostuf f ( )
VocO pode ler o c6digo
tor true, entio 'true" seri exibido. Portanto, basicamente, se apenas d.oStuf ( ) for true, ainda obteremos true.
!or6ln,sedoStuff ( ) forfalso,(x>3)e(y<2)terloquesertrue paraquetruesejaexibido".Oc6digoanterior
ficariundamais complexo se voc6 nio inserir um conjunto de par6ntese, .orrro lr.rrro,
"t"i*o,
int y = 5'
int x = 2;
if ((x > 3) && (y . 2) I aostutro ) {
System. out.println ( "true,, ) ;
]
Agora ele exibir6... Nada! Porque o c6digo anterior (com um conjunto de par6nteses a menos) far6 a avaliagio como se
estivesse dizendo, "Se (x > 3) for true, e (y < 2) ou o resultado de oostuf f ( ) tamb6m o for, true ser6 exibido.
Portanto, se (x > 3) nlo for true, nio haveri por que verificar o resto da expressio". Por causa do operador && de
abreviagio, a expressio ser6 avaliada como se houvesse par€nreses enfeixando ( lv.z I dostuf f ( )). Em outras
palavras, 6 avaliada como uma rinica expressio antes do Er& e como uma 6nica expressio depois do Ec&.

Lembre-se de que o rinico argumento v6lido para um teste if 6 um valor booleano. Em algumas linguagens, O ==
false,e1== t.rue.MasnioemJava! Oseguintec6digomostrainstrug6esif quepodemparecerv6lidas,masnio
sio, seguidas de substitutos v6lidos.
int- irrraTnf - 1.
'i nl- f: l qoTnf = O.
if (truelnt) // inv6lido
if (truelnt == true) // inv5aido
if (1) // inv6lido
if (falseInt == fal-se) // inv6Tido
if (truelnt == 1) // v6lido
if (falselnt == 0) // v6Lido

oBSERVAQ6ESpeneOE)(AME
Um ero clmtlm qtle os programadoru cometea (e que pode ser dficil de identfimr) i atribair ama uari,iael booleana quando a intenpdo seria
teshl-la. Cuidado com aldigot como o seguinte:

boolean boo = false:


if (boo = true) { }
Vocd pode achar ama enlre trds coitas:

1., pae o aidigo rcni nnpikdo e executado adeqaadamente, mdr qae o teste if falhar,i porque boo 6 f also.
2, pue o aidigo ndo senl nmpilado porque uoci est,l asando uma atibuigdo (: ), t, ueTde um teste de igualdade (: : ).
3. pae o aldigo senl conpilado e executado adzquadamente, e o teste if seni bem sandidn porque boo foi confgurado com Lrue (em
ueTde estar sendo aualiado se d uerdadeiro) n0 argunentl da insrap1o if!
E inilrtl, mas rctr?ta. Dado que o resultado de qualquer atibaQdo i igual ao ualor da aai,iuel incluido @rir essa
Bem, a oppdo 3 estti correta.
atibuigdo, a expressdo (boo = Lr:ue) turA como resaltado Erue. Portantz, 0 teste iffoi ben ncedido. Mas a ilnica uariduel que pode
ser atribaida (en ueqde aaaliada com relagdo a algo) d um ualorbooleano; todas as outrar atibuipdes resultardo erzt algum ualor ndo
booleano de modo qae ndo serdo udlidas, rcmo nas linhas a seguir:

{ } // Ndo compila, porqtue x ndo 6 um booleano!


J,i que os testes f requeren expressdu boo/eanas, uocd precisa ter um conhecimento srilido tanto sobre os operadoret ldgicos qaanto sobre a
intaxe e remdntica do teste if .
188 Copftulo 5: Controle de fluxo, exceq6es e ossertivos

Instrug6es svvitch
lJma maneira de simular o uso de virias instrug6es if 6 com a instrugXo switch. Observe o c6digo do bloco else-
if e veja como pode ser confuso ter testes if aninhados, mesmo com apenas alguns niveis:
int x = 3;
if (x == 1) {
System.out.println( "x equals 1" ) ;
]
else if(x == 2) {
System. out.println ( "x equals 2" ) ;
)
else if 1x == 3) {
System.out.println( "x equals 3" ) ;
)
el-se {
system.out.println("No idea what x is");
)

Agora vejamos a mesma funcionalidade representada na estrutura de uma instrugio swi tch:
int x = 3;
switch (x) {
case 1:
System. out.println ( "x is equal to 1," \;
break;
case 2:
System. out . println ( "x is equal to 2" ) ;
break;
case 3:
Q\rc|-
rJ 6m r vuu
p uelr nrrF nrinr'ln
. y! fIIurrr /\
"x is equal to 3");
break;
default:
System. out.println ( "Still no idea what x is" ) ;

ObservagXo: arazXo pelaqual essa instrugio switch emula os i f s aninhados listados anteriormente 6 devido )s
instrug6es break que foram colocadas dentro do switch. Em geral, as instrug6es break sio opcionais e, como veremos
daqui a algumas piginas, a inclusio ou excluslo delas causa grandes mudangas na forma como a instrugio swi tch seri
er<ecutada

Express6es vilidas para switch e case


A forma geral da instrugio switch 6

switch (express6o) {
case constantel: bloco de c6digo
case constante2: bloco de c6digo
default: bloco de c6diqo
i
A expressio de um switch deve avaliar um char, byte, short, int ou, a panir do Java 5, um enum. Isso significa
que, se voce nio estiver usando um enurg s6 vari6veis e valores que puderem ser promovidos automaticamente (em
a um tipo int
outras palavras, implicitamente convertidos) serio aceitos. VocA nio conseguiri compilar se usar algum tipo
diferente, incluindo os tipos num6ricos 1ong, f loat e double.
O rinico argumento que uma instrugXo case poder6 avaliar seri aquele que apresentar o mesmo tipo que a instruSo
JAVA 5 I89
swi tch pode u.ar, com uma restrigio adicional - e re/euante: o argumento de case tem que wr uma constante tlc tenpo de conpikgdo!
Ele precisa ser resolvido no tempo de compilagio, portanto, isso quEr dizer q,r. vo.6 ipode usar uma variivi f inai
constante com um valor literal. Nio 6 o suficiente ser f ina1, ela deve ser uma constante no tempo de compila$o. Por
e><emplo:

f i-a] ihf . - 1.

final int b;

intx=0;
switch (x) {
case a: // ok
case b: / / erro de compilagdo
Al6mdisso,ainstrugdoswiLgh sdpodeuerifcaraigualdade.Oquesignificaqueosoutrosoperadoresrelacionaiscomomaior
qae sio.considerados nio utiliz6veis em uma instruEio case. A seguir temos o exemplo de uma expressS.o vilida que usa
uma chamada de m6todo na instrugio swi t.ch. Observe que para esse c6digo ser v6fido, o m6todo que esti sendo
chamado na referdncia ao objeto deve rerornar um valor compitivel com umiipo int.
String s = "xyz";
switch (s.lengthO ) {
case 1:
System.out.println( "length is one,') ;
break;
case 2:
System. out.println ( "length is two" ) ;
break;
case 3:
Syst.em. out.println ( "length is three" ) ;

break;
default:
System.out.println( "no match" ) ;
l

Oura regra que voc6 poderia nio esperar envolve a pergunta: "O que aconteceria se uma variivel menor do que um tipo
int fosseusadanainstrugloswitch?"Examineoexemplodeinstrugioswitch aseguir:
bYte g = 2'
switch(g) {
case 23:
case 128:
)

Esse c6digo nXo seri compilado. Embora o argumento da instruglo swi tch seja v6lido - um tipo bpe 6 convertido
implicitamente em um tipo int. - o segundo argumento de case (128) 6 muito grande para um tipo byte e o
compilador sabe disso! Se vod tentar compilar