313

uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis
Page 2: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis
Page 3: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

EstaapostiladaCaelumvisaensinardeumamaneiraelegante,mostrandoapenasoqueénecessárioequandoénecessário,nomomentocerto,poupandoo leitordeassuntosquenãocostumamserde seuinteresseemdeterminadasfasesdoaprendizado.

ACaelumesperaquevocêaproveiteessematerial.Todososcomentários,críticasesugestõesserãomuitobem-vindos.

EssaapostilaéconstantementeatualizadaedisponibilizadanositedaCaelum.Sempreconsulteositeparanovasversõese,aoinvésdeanexaroPDFparaenviaraumamigo,indiqueositeparaqueelepossasemprebaixarasúltimasversões.Vocêpodeconferirocódigodeversãodaapostilalogono naldoíndice.

Baixesempreaversãomaisnovaem:www.caelum.com.br/apostilas

Esse material é parte integrante do treinamento Java e Orientação a Objetos e distribuídogratuitamente exclusivamente pelo site da Caelum. Todos os direitos são reservados à Caelum. Adistribuição, cópia, revenda e utilização paraministrar treinamentos são absolutamente vedadas. Parausocomercialdestematerial,porfavor,consulteaCaelumpreviamente.

SOBREESTAAPOSTILA

Page 4: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

1

4

19

Sumário

1ComoAprenderJava1.1Oqueérealmenteimportante? 1

1.2Sobreosexercícios 2

1.3Tirandodúvidaseindoalém 2

2OqueéJava2.1Java 4

2.2UmabrevehistóriadoJava 5

2.3MáquinaVirtual 6

2.4Javalento?HotspoteJIT 8

2.5VersõesdoJavaeaconfusãodoJava2 9

2.6JVM?JRE?JDK?Oquedevobaixar? 9

2.7OndeusareosobjetivosdoJava 10

2.8Especificaçãoversusimplementação 11

2.9ComooFJ-11estáorganizado 11

2.10Compilandooprimeiroprograma 12

2.11Executandoseuprimeiroprograma 14

2.12Oqueaconteceu? 14

2.13Parasabermais:comoéobytecode? 15

2.14Exercícios:ModificandooHelloWorld 16

2.15Oquepodedarerrado? 16

2.16Umpoucomais... 17

2.17Exercíciosopcionais 18

3VariáveisprimitivaseControledefluxo3.1Declarandoeusandovariáveis 19

3.2Tiposprimitivosevalores 22

3.3Exercícios:Variáveisetiposprimitivos 22

3.4Discussãoemaula:convençõesdecódigoecódigolegível 23

3.5Castingepromoção 24

SumárioCaelum

Page 5: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

35

60

76

3.6Oifeoelse 26

3.7OWhile 28

3.8OFor 28

3.9Controlandoloops 29

3.10Escopodasvariáveis 30

3.11Umblocodentrodooutro 32

3.12Parasabermais 32

3.13Exercícios:Fixaçãodesintaxe 32

3.14Desafios:Fibonacci 34

4Orientaçãoaobjetosbásica4.1Motivação:problemasdoparadigmaprocedural 35

4.2Criandoumtipo 37

4.3UmaclasseemJava 39

4.4Criandoeusandoumobjeto 39

4.5Métodos 41

4.6Métodoscomretorno 42

4.7Objetossãoacessadosporreferências 44

4.8Ométodotransfere() 47

4.9Continuandocomatributos 49

4.10Parasabermais:UmaFábricadeCarros 51

4.11Umpoucomais... 53

4.12Exercícios:OrientaçãoaObjetos 53

4.13Desafios 58

4.14Fixandooconhecimento 58

5Modificadoresdeacessoeatributosdeclasse5.1Controlandooacesso 60

5.2Encapsulamento 63

5.3GetterseSetters 65

5.4Construtores 68

5.5Anecessidadedeumconstrutor 69

5.6Atributosdeclasse 71

5.7Umpoucomais... 73

5.8Exercícios:Encapsulamento,construtoresestatic 73

5.9Desafios 75

6EclipseIDE6.1OEclipse 76

CaelumSumário

Page 6: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

92

101

122

138

6.2ApresentandooEclipse 77

6.3ViewsePerspective 78

6.4Criandoumprojetonovo 80

6.5Criandoomain 84

6.6Executandoomain 86

6.7Pequenostruques 87

6.8Exercícios:Eclipse 88

6.9Discussãoemaula:Refactoring 91

7Pacotes-Organizandosuasclassesebibliotecas7.1Organização 92

7.2Diretórios 93

7.3Import 94

7.4Acessoaosatributos,construtoresemétodos 96

7.5UsandooEclipsecompacotes 97

7.6Exercícios:Pacotes 99

8Ferramentas:jarejavadoc8.1Arquivos,bibliotecaseversões 101

8.2GerandooJARpeloEclipse 103

8.3Javadoc 105

8.4GerandooJavadoc 106

8.5Exercícios:JareJavadoc 109

8.6Importandoumjarexterno 110

8.7Exercícios:Importandoumjar 110

8.8Manipulandoacontapelainterfacegráfica 112

8.9Exercícios:Mostrandoosdadosdacontanatela 119

9Herança,reescritaepolimorfismo9.1Repetindocódigo? 122

9.2Reescritademétodo 126

9.3Invocandoométodoreescrito 127

9.4Polimorfismo 128

9.5Umoutroexemplo 130

9.6Umpoucomais... 132

9.7Exercícios:HerançaePolimorfismo 132

9.8Discussõesemaula:Alternativasaoatributoprotected 137

10ClassesAbstratas10.1Repetindomaiscódigo? 138

SumárioCaelum

Page 7: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

147

163

183

10.2Classeabstrata 139

10.3Métodosabstratos 141

10.4Aumentandooexemplo 142

10.5Parasabermais... 145

10.6Exercícios:ClassesAbstratas 145

11Interfaces11.1Aumentandonossoexemplo 147

11.2Interfaces 151

11.3Dificuldadenoaprendizadodeinterfaces 155

11.4Exemplointeressante:conexõescomobancodedados 156

11.5Exercícios:Interfaces 157

11.6Exercíciosopcionais 160

11.7Discussão:favoreçacomposiçãoemrelaçãoàherança 161

12Exceçõesecontroledeerros12.1Motivação 163

12.2Exercícioparacomeçarcomosconceitos 165

12.3ExceçõesdeRuntimemaiscomuns 169

12.4Outrotipodeexceção:CheckedExceptions 170

12.5UmpoucodagrandefamíliaThrowable 173

12.6Maisdeumerro 174

12.7Lançandoexceções 174

12.8Oquecolocardentrodotry? 176

12.9Criandoseuprópriotipodeexceção 177

12.10Parasabermais:finally 178

12.11Exercícios:Exceções 179

12.12Desafios 181

12.13Discussãoemaula:catchethrowsemException 181

13Opacotejava.lang13.1Pacotejava.lang 183

13.2UmpoucosobreaclasseSystem 183

13.3java.lang.Object 184

13.4Métodosdojava.lang.Object:equalsetoString 185

13.5Exercícios:java.lang.Object 189

13.6java.lang.String 190

13.7Exercícios:java.lang.String 193

13.8Desafio 194

CaelumSumário

Page 8: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

196

206

236

13.9Discussãoemaula:OquevocêprecisafazeremJava? 194

14Umpoucodearrays14.1Oproblema 196

14.2Arraysdereferências 197

14.3Percorrendoumaarray 198

14.4PercorrendoumaarraynoJava5.0 199

14.5Exercícios:Arrays 200

14.6Umpoucomais... 203

14.7DesafiosOpcionais 205

15Collectionsframework15.1Arrayssãotrabalhosos,utilizarestruturadedados 206

15.2Listas:java.util.List 207

15.3ListasnoJava5eJava7comGenerics 211

15.4Aimportânciadasinterfacesnascoleções 212

15.5Ordenação:Collections.sort 213

15.6Exercícios:Ordenação 216

15.7Conjunto:java.util.Set 218

15.8Principaisinterfaces:java.util.Collection 220

15.9PercorrendocoleçõesnoJava5 221

15.10Parasabermais:Iterandosobrecoleçõescomjava.util.Iterator 222

15.11Mapas-java.util.Map 224

15.12Parasabermais:Properties 226

15.13Parasabermais:EqualseHashCode 227

15.14Parasabermais:Boaspráticas 228

15.15Exercícios:Collections 228

15.16Desafios 232

15.17Parasabermais:Comparators,classesanônimas,Java8eolambda 233

16Pacotejava.io16.1ConhecendoumaAPI 236

16.2Orientaçãoaobjetosnojava.io 237

16.3InputStream,InputStreamReadereBufferedReader 237

16.4LendoStringsdoteclado 239

16.5Aanalogiaparaaescrita:OutputStream 241

16.6Umamaneiramaisfácil:ScannerePrintStream 242

16.7Umpoucomais... 243

16.8Integereclasseswrappers(box) 244

SumárioCaelum

Page 9: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

251

254

263

276

283

16.9AutoboxingnoJava5.0 245

16.10Parasabermais:java.lang.Math 245

16.11Exercícios:JavaI/O 246

16.12Discussãoemaula:DesignPatternseoTemplateMethod 248

17Eagora?17.1Web 251

17.2PraticandoJavaeusandobibliotecas 251

17.3GruposdeUsuários 252

17.4Próximoscursos 252

18Apêndice-ProgramaçãoConcorrenteeThreads18.1Threads 254

18.2Escalonadoretrocasdecontexto 257

18.3GarbageCollector 258

18.4Exercícios 260

18.5Easclassesanônimas? 261

19Apêndice-Sockets19.1Motivação:umaAPIqueusaosconceitosaprendidos 263

19.2Protocolo 263

19.3Porta 264

19.4Socket 265

19.5Servidor 266

19.6Cliente 267

19.7Imagemgeral 268

19.8Exercícios:Sockets 269

19.9Desafio:MúltiplosClientes 271

19.10Desafio:broadcastdasmensagens 271

19.11Soluçãodosistemadechat 273

20Apêndice-Problemascomconcorrência20.1Threadsacessandodadoscompartilhados 276

20.2Controlandooacessoconcorrente 278

20.3VectoreHashtable 280

20.4Umpoucomais... 280

20.5Exercíciosavançadosdeprogramaçãoconcorrenteelocks 280

21Apêndice-InstalaçãodoJava21.1InstalandonoUbuntueemoutrosLinux 283

21.2NoMacOSX 284

CaelumSumário

Page 10: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

289

21.3InstalaçãodoJDKemambienteWindows 284

22Apêndice-Debugging22.1Oqueédebugar 289

22.2DebugandonoEclipse 289

22.3Perspectivadedebug 291

22.4Debugavançado 294

22.5Profiling 300

22.6ProfilingnoEclipseTPTP 301

Versão:24.8.4

SumárioCaelum

Page 11: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO1

"Buscouminstantefelizquejustifiqueminhaexistência"--FiodórDostoiévski

Muitoslivros,aopassardoscapítulos,mencionamtodososdetalhesdalinguagemjuntamentecomseus princípios básicos. Isso acaba criando muita confusão, em especial porque o estudante nãoconseguedistinguirexatamenteoqueéprimordial aprenderno início,daquiloquepodeserestudadomaisadiante.

Seumaclasseabstratadeveounãoteraomenosummétodoabstrato,seoifsóaceitaargumentosbooleanosetodososdetalhessobreclassesinternas,realmentenãodevemsetornarpreocupaçõesparaaquelecujoobjetivoprimárioéaprenderJava.Essetipodeinformaçãoseráadquiridacomotempo,enãoénecessárionoinício.

Nestecurso,separamosessasinformaçõesemquadrosespeciais,jáquesãoinformaçõesextras.Ouentão, apenas citamos num exercício e deixamos para o leitor procurar informações se for de seuinteresse.

Porfim,faltamencionaralgosobreaprática,quedeveser tratadaseriamente: todososexercíciossãomuito importantes e os desafios podem ser feitos quando o curso terminar.De qualquermaneirarecomendamosaosalunosestudarememcasa,epraticarembastantecódigoevariações.

OCURSO

ParaaquelesqueestãofazendoocursoJavaeOrientaçãoaObjetos,recomendamosestudarememcasaaquiloquefoivistoduranteaaula,tentandoresolverosexercíciosopcionaiseosdesafiosapresentados.

COMOAPRENDERJAVA

1.1OQUEÉREALMENTEIMPORTANTE?

1COMOAPRENDERJAVA 1

Page 12: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Os exercícios do curso variam de práticos até pesquisas na Internet, ou mesmo consultas sobreassuntosavançadosemdeterminadostópicosparaincitaracuriosidadedoaprendiznatecnologia.

Existemtambém,emdeterminadoscapítulos,umasériededesafios.Elesfocammaisnoproblemacomputacionalquenalinguagem,porémsãoumaexcelenteformadetreinarasintaxee,principalmente,familiarizar o aluno coma biblioteca padrão Java, alémde proporcionar umganhona velocidade dedesenvolvimento.

Para tirar dúvidas dos exercícios, ou de Java em geral, recomendamos o fórum do GUJ(http://www.guj.com.br/), onde sua dúvida será respondida prontamente. O GUJ foi fundado pordesenvolvedoresdaCaelum,ehojecontacommaisdeummilhãodemensagens.

Foraisso,sinta-seàvontadeparaentraremcontatocomseuinstrutorparatirartodasasdúvidasquesurgiremduranteocurso.

Seoquevocêestábuscandosãolivrosdeapoio,sugerimosconheceraeditoraCasadoCódigo:

http://www.casadocodigo.com.br

ACaelum fornecemuitosoutros cursos Java, comdestaqueparaoFJ-21que traz a aplicaçãodoJavanaweb.

http://www.caelum.com.br/

Há tambémcursos online que vão te ajudar a ir além, commuita interação comos instrutores, a

JáconheceoscursosonlineAlura?

1.2SOBREOSEXERCÍCIOS

1.3TIRANDODÚVIDASEINDOALÉM

2 1.2SOBREOSEXERCÍCIOS

Page 13: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Alura:

http://www.alura.com.br/

1.3TIRANDODÚVIDASEINDOALÉM 3

Page 14: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO2

"Computadoressãoinúteis,elesapenasdãorespostas"--Picasso

ChegouahoraderesponderasperguntasmaisbásicassobreJava.Aotérminodessecapítulo,vocêserácapazde:

responderoqueéJava;mostrarasvantagensedesvantagensdoJava;entenderbemoconceitodemáquinavirtual;compilareexecutarumprogramasimples.

Entender um pouco da história da plataforma Java é essencial para enxergar os motivos que alevaramaosucesso.

Quaiseramosseusmaioresproblemasquandoprogramavanadécadade1990?

ponteiros?gerenciamentodememória?organização?faltadebibliotecas?terdereescreverpartedocódigoaomudardesistemaoperacional?custofinanceirodeusaratecnologia?

AlinguagemJavaresolvebemessesproblemas,queatéentãoapareciamcomfrequêncianasoutraslinguagens. Alguns desses problemas foram particularmente atacados porque uma das grandesmotivações para a criação da plataforma Java era de que essa linguagem fosse usada em pequenosdispositivos,comotvs,videocassetes,aspiradores, liquidificadoreseoutros.Apesardissoa linguagemteve seu lançamento focado no uso em clientes web (browsers) para rodar pequenas aplicações(applets).Hoje em dia esse não é o grandemercado do Java: apesar de ter sido idealizado comumpropósitoelançadocomoutro,oJavaganhoudestaquenoladodoservidor.

O Java foi criado pela antiga Sun Microsystems e mantida através de um comitê(http://www.jcp.org). Seu site principal era o java.sun.com, e java.com um site mais institucional,voltadoaoconsumidordeprodutoseusuáriosleigos,nãodesenvolvedores.ComacompradaSunpelaOracle em 2009,muitasURLs e nomes tem sido trocados para refletir amarca daOracle.A páginaprincipaldoJavaé:http://www.oracle.com/technetwork/java/

No Brasil, diversos grupos de usuários se formaram para tentar disseminar o conhecimento da

OQUEÉJAVA

2.1JAVA

4 2OQUEÉJAVA

Page 15: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

linguagem.UmdeleséoGUJ(http://www.guj.com.br),umacomunidadevirtualcomartigos,tutoriaisefórumpara tirardúvidas,omaioremlínguaportuguesacommaisdecemmilusuáriose1milhãodemensagens.

Encorajamostodososalunosausarmuitoosfórunsdomesmo,poiséumadasmelhoresmaneirasparaacharsoluçõesparapequenosproblemasqueacontecemcomgrandefrequência.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

ASuncriouum time (conhecidocomoGreenTeam)paradesenvolver inovações tecnológicasem1992.EssetimefoilideradoporJamesGosling,consideradoopaidoJava.Otimevoltoucomaideiadecriaruminterpretador(jáeraumamáquinavirtual,veremosoqueéissomaisafrente)parapequenosdispositivos,facilitandoareescritadesoftwareparaaparelhoseletrônicos,comovídeocassete,televisãoeaparelhosdeTVacabo.

A ideianãodeucerto.Tentaramfechardiversoscontratoscomgrandes fabricantesdeeletrônicos,comoPanasonic,masnãohouveêxitodevidoaoconflitode interessesecustos.Hoje,sabemosqueoJava domina o mercado de aplicações para celulares com mais de 2.5 bilhões de dispositivoscompatíveis,porémem1994aindaeramuitocedoparaisso.

Com o advento da web, a Sun percebeu que poderia utilizar a ideia criada em 1992 para rodarpequenasaplicaçõesdentrodobrowser.Asemelhançaeraquenainternethaviaumagrandequantidadede sistemasoperacionais ebrowsers, e com isso seriagrandevantagempoderprogramarnumaúnicalinguagem, independente da plataforma. Foi aí que o Java 1.0 foi lançado: focado em transformar obrowserdeapenasumclientemagro(thinclientouterminalburro)emumaaplicaçãoquepossatambémrealizaroperaçõesavançadas,enãoapenasrenderizarhtml.

OsappletsdeixaramdeserofocodaSun,enemaOraclenuncateveinteresse.Écuriosonotarquea

JáconheceoscursosonlineAlura?

2.2UMABREVEHISTÓRIADOJAVA

2.2UMABREVEHISTÓRIADOJAVA 5

Page 16: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

tecnologia Java nasceu com um objetivo em mente, foi lançado com outro, mas, no final, decoloumesmonodesenvolvimentodeaplicaçõesdoladodoservidor.Sorte?HáhojeoJavaFX,tentandodarforçaparaoJavanãosónodesktopmascomoaplicaçõesricasnaweb,masmuitosnãoacreditamquehajaespaçoparatal,considerandoodestinodetecnologiascomoAdobeFlexeMicrosoftSilverlight.

VocêpodelerahistóriadalinguagemJavaem:http://www.java.com/en/javahistory/

Eumvídeointeressante:http://tinyurl.com/histjava

Em2009aOraclecomprouaSun, fortalecendoamarca.AOracle sempre foi, juntocoma IBM,umadasempresasquemaisinvestiramefizeramnegóciosatravésdousodaplataformaJava.Em2014surgeaversãoJava8commudançasinteressantesnalinguagem.

Em uma linguagem de programação como C e Pascal, temos a seguinte situação quando vamoscompilarumprograma:

O código fonte é compilado para código de máquina específico de uma plataforma e sistemaoperacional.Muitasvezesoprópriocódigofonteédesenvolvidovisandoumaúnicaplataforma!

Esse código executável (binário) resultante será executado pelo sistema operacional e, por essemotivo,eledevesaberconversarcomosistemaoperacionalemquestão.

Istoé, temosumcódigoexecutávelparacadasistemaoperacional.ÉnecessáriocompilarumavezparaWindows,outraparaoLinux,eassimpordiante,casoagentequeiraqueessenossosoftwarepossaserutilizadoemváriasplataformas.EsseéocasodeaplicativoscomooOpenOffice,Firefoxeoutros.

2.3MÁQUINAVIRTUAL

6 2.3MÁQUINAVIRTUAL

Page 17: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Como foi dito anteriormente, namaioria das vezes, a sua aplicação se utiliza das bibliotecas dosistemaoperacional,como,porexemplo,adeinterfacegráficaparadesenharas"telas".AbibliotecadeinterfacegráficadoWindowsébemdiferentedasdoLinux:comocriarentãoumaaplicaçãoquerodedeformaparecidanosdoissistemasoperacionais?

Precisamosreescreverummesmopedaçodaaplicaçãoparadiferentessistemasoperacionais,jáqueelesnãosãocompatíveis.

Já o Java utiliza do conceito demáquina virtual, onde existe, entre o sistema operacional e aaplicação, uma camada extra responsável por "traduzir" -mas não apenas isso - o que sua aplicaçãodesejafazerparaasrespectivaschamadasdosistemaoperacionalondeelaestárodandonomomento:

Dessaforma,amaneiracomaqualvocêabreumajanelanoLinuxounoWindowséamesma:vocêganhaindependênciadesistemaoperacional.Ou,melhorainda,independênciadeplataformaemgeral:nãoéprecisosepreocuparemqualsistemaoperacionalsuaaplicaçãoestárodando,nememquetipodemáquina,configurações,etc.

Reparequeumamáquinavirtualéumconceitobemmaisamploqueodeuminterpretador.Comoopróprio nome diz, uma máquina virtual é como um "computador de mentira": tem tudo que umcomputador tem. Em outras palavras, ela é responsável por gerenciar memória, threads, a pilha deexecução,etc.

Sua aplicação roda sem nenhum envolvimento com o sistema operacional! Sempre conversandoapenascomaJavaVirtualMachine(JVM).

Essacaracterísticaéinteressante:comotudopassapelaJVM,elapodetirarmétricas,decidirondeémelhoralocaramemória,entreoutros.UmaJVMisolatotalmenteaaplicaçãodosistemaoperacional.SeumaJVMterminaabruptamente,sóasaplicaçõesqueestavamrodandonelairãoterminar:issonãoafetaráoutrasJVMsqueestejamrodandonomesmocomputador,nemafetaráosistemaoperacional.

Essacamadadeisolamentotambéméinteressantequandopensamosemumservidorquenãopodesesujeitararodarcódigoquepossainterferirnaboaexecuçãodeoutrasaplicações.

2.3MÁQUINAVIRTUAL 7

Page 18: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Essa camada, a máquina virtual, não entende código java, ela entende um código de máquinaespecífico.Essecódigodemáquinaégeradoporumcompiladorjava,comoojavac,eéconhecidopor"bytecode",poisexistemmenosde256códigosdeoperaçãodessa linguagem,ecada"opcode"gastaumbyte.OcompiladorJavageraessebytecodeque,diferentedaslinguagenssemmáquinavirtual,vaiservirparadiferentessistemasoperacionais,jáqueelevaiser"traduzido"pelaJVM.

WRITEONCE,RUNANYWHERE

EsseeraumsloganqueaSunusavaparaoJava,jáquevocênãoprecisareescreverpartesdasuaaplicaçãotodavezquequisermudardesistemaoperacional.

HotspotéatecnologiaqueaJVMutilizaparadetectarpontosquentesdasuaaplicação:códigoqueéexecutadomuito,provavelmentedentrodeumoumaisloops.QuandoaJVMjulgarnecessário,elavaicompilar estes códigos para instruções realmente nativas da plataforma, tendo emvista que isso vaiprovavelmente melhorar a performance da sua aplicação. Esse compilador é o JIT: Just inTimeCompiler,ocompiladorqueaparece"bemnahora"quevocêprecisa.

Você pode pensar então: porque a JVM não compila tudo antes de executar a aplicação? É queteoricamentecompilardinamicamente,amedidadonecessário,podegerarumaperformancemelhor.Omotivoésimples:imagineum.exegeradopeloVisualBasic,pelogccoupeloDelphi;eleéestático.Elejáfoiotimizadobaseadoemheurísticas,ocompiladorpodetertomadoumadecisãonãotãoboa.

Já a JVM, por estar compilando dinamicamente durante a execução, pode perceber que umdeterminadocódigonãoestácomperformanceadequadaeotimizarmaisumpoucoaquele trecho,ouaindamudaraestratégiadeotimização.ÉporessemotivoqueasJVMsmaisrecentesemalgunscasoschegamaganhardecódigosCcompiladoscomoGCC3.x.

2.4JAVALENTO?HOTSPOTEJIT

8 2.4JAVALENTO?HOTSPOTEJIT

Page 19: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Java1.0e1.1sãoasversõesmuitoantigasdoJava,masjátraziambibliotecasimportantescomooJDBCeojava.io.

Com o Java 1.2 houve um aumento grande no tamanho da API, e foi nesse momento em quetrocaramanomenclatura de Javapara Java2, comoobjetivodediminuir a confusãoquehavia entreJavaeJavascript.Maslembre-se,nãoháversão"Java2.0",o2foiincorporadoaonome,tornando-seJava21.2.

DepoisvieramoJava21.3e1.4,eoJava1.5passouasechamarJava5,tantoporumaquestãodemarketingeporquemudançassignificativasnalinguagemforamincluídas.Énessemomentoqueo"2"donomeJavadesaparece.Reparequeparafinsdedesenvolvimento,oJava5aindaéreferidocomoJava1.5.

HojeaúltimaversãodisponíveldoJavaéa8.

OquegostaríamosdebaixarnositedaOracle?

JVM=apenasavirtualmachine,essedownloadnãoexiste,elasemprevemacompanhada.JRE=JavaRuntimeEnvironment,ambientedeexecuçãoJava,formadopelaJVMebibliotecas,tudoquevocêprecisaparaexecutarumaaplicaçãoJava.Masnósprecisamosdemais.JDK=JavaDevelopmentKit:Nós,desenvolvedores, faremosodownloaddo JDKdo JavaSE(StandardEdition).EleéformadopelaJREsomadoaferramentas,comoocompilador.

Tanto o JRE e o JDK podem ser baixados do site http://www.oracle.com/technetwork/java/.Paraencontrá-los,acesseolinkJavaSEdentrodostopdownloads.ConsulteoapêndicedeinstalaçãodoJDK

VocêpodetambémfazerocursodatadessaapostilanaCaelum

2.5VERSÕESDOJAVAEACONFUSÃODOJAVA2

2.6JVM?JRE?JDK?OQUEDEVOBAIXAR?

2.5VERSÕESDOJAVAEACONFUSÃODOJAVA2 9

Page 20: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

paramaioresdetalhes.

Nodecorrerdocurso,vocêpodeacharqueoJavatemmenorprodutividadequandocomparadacomalinguagemquevocêestáacostumado.

ÉprecisoficarclaroqueapremissadoJavanãoéadecriarsistemaspequenos,ondetemosumoudoisdesenvolvedores,maisrapidamentequelinguagenscomophp,perl,eoutras.

Ofocodaplataformaéoutro:aplicaçõesdemédioagrandeporte,ondeotimededesenvolvedorestemváriaspessoasesemprepodeviramudarecrescer.NãotenhadúvidasquecriaraprimeiraversãodeumaaplicaçãousandoJava,mesmoutilizando IDEse ferramentaspoderosas, serámais trabalhosoquemuitaslinguagensscriptoudealtaprodutividade.Porém,comumalinguagemorientadaaobjetosemaduracomooJava,seráextremamentemaisfácilerápidofazeralteraçõesnosistema,desdequevocêsigaasboaspráticaserecomendaçõessobredesignorientadoaobjetos.

Alémdisso, a quantidade enormedebibliotecas gratuitas para realizar osmais diversos trabalhos(taiscomo relatórios,gráficos, sistemasdebusca,geraçãodecódigodebarra,manipulaçãodeXML,tocadores de vídeo, manipuladores de texto, persistência transparente, impressão, etc) é um pontofortíssimopara adoçãodo Java:vocêpode criarumaaplicação sofisticada, usandodiversos recursos,sem precisar comprar um componente específico, que costuma ser caro. O ecossistema do Java éenorme.

Cadalinguagemtemseuespaçoeseumelhoruso.OusodoJavaéinteressanteemaplicaçõesquevirãoacrescer,emquealegibilidadedocódigoéimportante,ondetemosmuitaconectividadeesehámuitas plataformas (ambientes e sistemas operacionais) heterogêneas (Linux,Unix,OSX eWindowsmisturados).

VocêpodeverissopelaquantidadeenormedeofertasdeempregoprocurandodesenvolvedoresJavaparatrabalharcomsistemaswebeaplicaçõesdeintegraçãonoservidor.

Apesar disto, a Sun empenhou-se em tentar popularizar o uso do Java em aplicações desktop,mesmo com o fraco marketshare do Swing/AWT/SWT em relação às tecnologias concorrentes (emespecialMicrosoft.NET).AatualtentativaéoJavaFX,ondeaOracleteminvestidobastante.

2.7ONDEUSAREOSOBJETIVOSDOJAVA

10 2.7ONDEUSAREOSOBJETIVOSDOJAVA

Page 21: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Outro ponto importante: quando falamos de Java Virtual Machine, estamos falando de umaespecificação.EladizcomoobytecodedeveserinterpretadopelaJVM.Quandofazemosodownloadno site da Oracle, o que vem junto é a Oracle JVM. Em outras palavras, existem outras JVMsdisponíveis,comoaJRockitdaBEA(tambémadquiridapelaOracle),aJ9daIBM,entreoutras.

Esseéoutropontointeressanteparaasempresas.CasonãoestejamgostandodealgumdetalhedaJVMdaOracleouprefiram trabalhar comoutra empresa,pagandopor suporte, elaspodem trocardeJVMcomagarantiaabsolutadequetodoosistemacontinuaráfuncionando.IssoporquetodaJVMdeveser certificada pela Oracle, provando a sua compatibilidade. Não há nem necessidade de recompilarnenhumadesuasclasses.

Além de independência de hardware e sistema operacional, você tem a independência de vendor(fabricante):graçasaideiadaJVMserumaespecificaçãoenãoumsoftware.

Javaéumalinguagemsimples:existempoucasregras,muitobemdefinidas.

Porém quebrar o paradigma procedural para mergulhar na orientação a objetos não é simples.QuebraroparadigmaeganharfluênciacomalinguagemeAPIsãoosobjetivosdoFJ-11.

Ocomeçopodeserumpoucofrustrante:exemplossimples,controlede fluxocomoif,for,

whileecriaçãodepequenosprogramasquenemaomenoscaptamdadosdoteclado.Apesardeisso

tudosernecessário,ésónos20%finaisdocursoqueutilizaremosbibliotecaspara,nofinal,criarmosum chat entre duas máquinas que transferem Strings por TCP/IP. Neste ponto, teremos tudo que énecessárioparaentendercompletamentecomoaAPIfunciona,quemestendequem,eoporquê.

Seuslivrosdetecnologiaparecemdoséculopassado?

2.8ESPECIFICAÇÃOVERSUSIMPLEMENTAÇÃO

2.9COMOOFJ-11ESTÁORGANIZADO

2.8ESPECIFICAÇÃOVERSUSIMPLEMENTAÇÃO 11

Page 22: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Depois desse capítulo no qual o Java, a JVM e primeiros conceitos são passados, veremos oscomandosbásicosdojavaparacontroledefluxoeutilizaçãodevariáveisdotipoprimitivo.Criaremosclassespara testaressepequenoaprendizado,semsaberexatamenteoqueéumaclasse.Issodificultaaindamaisacurvadeaprendizado,porémcadaconceitoseráintroduzidonomomentoconsideradomaisapropriadopelosinstrutores.

Passamos para o capítulo de orientação a objetos básico, mostrando os problemas do paradigmaprocedural e a necessidade de algo diferente para resolvê-los. Atributos, métodos, variáveis do tiporeferênciaeoutros.

Os capítulos de modificadores de acesso, herança, classes abstratas e interfaces demonstram oconceitofundamentalqueocursoquerpassar:encapsule,exponhaomínimodesuasclasses,foquenoque elas fazem, no relacionamento entre elas. Com um bom design, a codificação fica fácil e amodificaçãoeexpansãodosistematambém.

No decorrer desses capítulos, o Eclipse é introduzido de forma natural, evitando-se ao máximowizardsemenus,priorizandomostraroschamadoscodeassistsequickfixes.IssofazcomqueoEclipsetrabalhedeformasimbióticacomodesenvolvedor,semseintrometer,semfazermágica.

Pacotes,javadoc,jarsejava.langapresentamosúltimosconceitosfundamentaisdoJava,dando

todaafundaçãopara,então,passarmosaestudarasprincipaisemaisutilizadasAPIsdoJavaSE.

AsAPIsestudadasserãojava.utilejava.io.Todaselasusameabusamdosconceitosvistos

no decorrer do curso, ajudando a sedimentá-los. Juntamente, temos os conceitos básicos do uso deThreads,eosproblemaseperigosdaprogramaçãoconcorrentequandodadossãocompartilhados.

Resumindo: o objetivo do curso é apresentar o Java ao mesmo tempo que os fundamentos daorientaçãoaobjetossãointroduzidos.Bateremosmuitonopontodedizerqueoimportanteécomoasclassesserelacionamequaléopapeldecadauma,enãoemcomoelasrealizamassuasobrigações.Programevoltadoàinterface,enãoàimplementação.

Vamosparaonossoprimeirocódigo!Oprogramaqueimprimeumalinhasimples.

Paramostrarumalinha,podemosfazer:

System.out.println("MinhaprimeiraaplicaçãoJava!");

Masessecódigonãoseráaceitopelocompiladorjava.OJavaéumalinguagembastanteburocrática,eprecisademaisdoqueissoparainiciarumaexecução.Veremososdetalheseosporquêsduranteospróximoscapítulos.Omínimoqueprecisaríamosescreveréalgocomo:

classMeuPrograma{publicstaticvoidmain(String[]args){

2.10COMPILANDOOPRIMEIROPROGRAMA

12 2.10COMPILANDOOPRIMEIROPROGRAMA

Page 23: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out.println("MinhaprimeiraaplicaçãoJava!");}}

NOTAÇÃO

Todososcódigosapresentadosnaapostilaestãoformatadoscomrecursosvisuaisparaauxiliara leitura e compreensão dos mesmos. Quando for digitar os códigos no computador, trate oscódigoscomotextosimples.

Anumeraçãodaslinhasnãofazpartedocódigoenãodeveserdigitada;éapenasumrecursodidático.OJavaécasesensitive:tomecuidadocommaiúsculaseminúsculas.

Apósdigitarocódigoacima,grave-ocomoMeuPrograma.javaemalgumdiretório.Paracompilar,você deve pedir para que o compilador de Java da Oracle, chamado javac , gere o bytecode

correspondenteaoseucódigoJava.

Depoisdecompilar,obytecodefoigerado.Quandoosistemaoperacionallistarosarquivoscontidosnodiretórioatual,vocêpoderáverqueumarquivo.classfoigerado,comomesmonomedasuaclasseJava.

ASSUSTADOCOMOCÓDIGO?

ParaquemjátemumaexperiênciacomJava,esseprimeirocódigoémuitosimples.Mas,seéseu primeiro código em Java, pode ser umpouco traumatizante.Nãodeixe de ler o prefácio docurso, que deixará você mais tranquilo em relação a curva de aprendizado da linguagem,conhecendocomoocursoestáorganizado.

2.10COMPILANDOOPRIMEIROPROGRAMA 13

Page 24: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

PRECISOSEMPREPROGRAMARUSANDOONOTEPADOUSIMILAR?

NãoénecessáriodigitarsempreseuprogramaemumsimplesaplicativocomooNotepad.Vocêpodeusarumeditorquetenhasyntaxhighlightingeoutrosbenefícios.

Mas,nocomeço,éinteressantevocêusaralgoquenãopossuaferramentas,paraquevocêpossaseacostumarcomoserrosdecompilação,sintaxeeoutros.Depoisdocapítulodepolimorfismoeherança sugerimos a utilização do Eclipse (http://www.eclipse.org), a IDE líder no mercado, egratuita.ExisteumcapítuloaparteparaousodoEclipsenestaapostila.

NoLinux,recomendamosousodogedit,kateevi.NoWindows,vocêpodeusaroNotepad++ouoTextPad.NoMac,TextMate,Sublimeoumesmoovi.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Osprocedimentosparaexecutarseuprogramasãomuitosimples.OjavacéocompiladorJava,eojavaéoresponsávelporinvocaramáquinavirtualparainterpretaroseuprograma.

Aoexecutar,podeserqueaacentuaçãoresultantesaiaerradadevidoaalgumasconfiguraçõesquedeixamosdefazer.Semproblemas.

Agoraéamelhorhoradeaprenderalgonovo

2.11EXECUTANDOSEUPRIMEIROPROGRAMA

2.12OQUEACONTECEU?

14 2.11EXECUTANDOSEUPRIMEIROPROGRAMA

Page 25: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classMeuPrograma{publicstaticvoidmain(String[]args){

//miolodoprogramacomeçaaqui!System.out.println("MinhaprimeiraaplicaçãoJava!!");//fimdomiolodoprograma

}}

Omiolodoprogramaéoqueseráexecutadoquandochamamosamáquinavirtual.Porenquanto,todasaslinhasanteriores,ondeháadeclaraçãodeumaclasseeadeummétodo,nãoimportamparanósnessemomento.Masdevemossaberque todaaplicaçãoJavacomeçaporumpontodeentrada,eestepontodeentradaéométodomain.

Aindanãosabemosoqueémétodo,masveremosnocapítulo4.Atélá,nãosepreocupecomessasdeclarações.Semprequeumexercícioforfeito,ocódigoquenosimportasempreestaránessemiolo.

Nocasodonossocódigo,alinhadoSystem.out.printlnfazcomqueoconteúdoentreaspasseja

colocadonatela.

OMeuPrograma.classgeradonãoélegívelporsereshumanos(nãoquesejaimpossível).Eleestá

escritonoformatoqueavirtualmachinesabeentenderequefoiespecificadoqueelaentendesse.

É como um assembly, escrito para esta máquina em específico. Podemos ler os mnemônicosutilizandoaferramentajavapqueacompanhaoJDK:

javap-cMeuPrograma

Easaída:

MeuPrograma();Code:0:aload_01:invokespecial#1;//Methodjava/lang/Object."<init>":()V4:return

publicstaticvoidmain(java.lang.String[]);Code:0:getstatic#2;//Fieldjava/lang/System.out:Ljava/io/PrintStream;3:ldc#3;//StringMinhaprimeiraaplicaçãoJava!!5:invokevirtual#4;//Methodjava/io/PrintStream.println:(Ljava/lang/String;)V8:return

}

Éocódigoacima,queaJVMsabeler.Éo"códigodemáquina",damáquinavirtual.

Um bytecode pode ser revertido para o .java original (com perda de comentários e nomes de

2.13PARASABERMAIS:COMOÉOBYTECODE?

2.13PARASABERMAIS:COMOÉOBYTECODE? 15

Page 26: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

variáveislocais).Casoseusoftwarevávirarumprodutodeprateleira,éfundamentalusarumofuscadorno seu código, que vai embaralhar classes, métodos e um monte de outros recursos (indicamos ohttp://proguard.sf.net).

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. Altereseuprogramaparaimprimirumamensagemdiferente.2. AltereseuprogramaparaimprimirduaslinhasdetextousandoduaslinhasdecódigoSystem.out.3. Sabendoqueos caracteres\n representamumaquebra de linhas, imprimaduas linhas de texto

usandoumaúnicalinhadecódigoSystem.out.

Muitos erros podemocorrer nomomento que você rodar seu primeiro código.Vamos ver algunsdeles:

Código:

classX{publicstaticvoidmain(String[]args){System.out.println("Faltapontoevírgula")}}

Erro:

X.java:4:';'expected}^1error

Esseéoerrodecompilaçãomaiscomum:aqueleondeumpontoevírgulaforaesquecido.Repare

EditoraCasadoCódigocomlivrosdeumaformadiferente

2.14EXERCÍCIOS:MODIFICANDOOHELLOWORLD

2.15OQUEPODEDARERRADO?

16 2.14EXERCÍCIOS:MODIFICANDOOHELLOWORLD

Page 27: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

queocompiladoréexplícitoemdizerquealinha4éacomproblemas.Outroserrosdecompilação

podem ocorrer se você escreveu palavras chaves (as que colocamos em negrito) em maiúsculas,esqueceudeabrirefecharas{},etc.

Duranteaexecução,outroserrospodemaparecer:

SevocêdeclararaclassecomoX,compilá-laedepoistentarusá-lacomoxminúsculo(javax),oJavateavisa:

Exceptioninthread"main"java.lang.NoClassDefFoundError:X(wrongname:x)

Setentaracessarumaclassenodiretórioouclasspatherrado,ouseonomeestivererrado,ocorreráoseguinteerro:

Exceptioninthread"main"java.lang.NoClassDefFoundError:X

SeesquecerdecolocarstaticouoargumentoString[]argsnométodomain:

Exceptioninthread"main"java.lang.NoSuchMethodError:main

Porexemplo:

classX{publicvoidmain(String[]args){System.out.println("Faltouostatic,tenteexecutar!");}}

Senãocolocarométodomaincomopublic:

Mainmethodnotpublic.

Porexemplo:

classX{staticvoidmain(String[]args){System.out.println("Faltouopublic");}}

Procureumcolega,oualgumconhecido,queestejaemumprojetoJava.DescubraporqueJavafoiescolhidocomotecnologia.OqueéimportanteparaesseprojetoeoqueacaboufazendodoJavaamelhorescolha?

2.16UMPOUCOMAIS...

2.16UMPOUCOMAIS... 17

Page 28: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. UmarquivofonteJavadevesempreteraextensão.java,ouocompiladororejeitará.Alémdisso,

existemalgumasoutras regrasnahoradedaronomedeumarquivo Java.ExperimentegravarocódigodestecapítulocomOutroNome.javaoualgosimilar.

Compileeverifiqueonomedoarquivogerado.Comoexecutarasuaaplicação?

JáconheceoscursosonlineAlura?

2.17EXERCÍCIOSOPCIONAIS

18 2.17EXERCÍCIOSOPCIONAIS

Page 29: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO3

"Péssimaideia,adequenãosepodemudar"--Montaigne

AprenderemosatrabalharcomosseguintesrecursosdalinguagemJava:

declaração,atribuiçãodevalores,castingecomparaçãodevariáveis;controledefluxoatravésdeifeelse;

instruçõesdelaçoforewhile,controledefluxocombreakecontinue.

Dentrodeumbloco,podemosdeclararvariáveiseusá-las.EmJava,todavariáveltemumtipoquenãopodesermudado,umavezquedeclarado:

tipoDaVariavelnomeDaVariavel;

Porexemplo,épossívelterumaidadequeguardaumnúmerointeiro:

intidade;

Comisso,vocêdeclaraavariávelidade,quepassaaexistirapartirdaquelalinha.Elaédotipo

int,queguardaumnúmerointeiro.Apartirdaí,vocêpodeusá-la,primeiramenteatribuindovalores.

Alinhaaseguiréatraduçãode:"idadedevevalerquinze".

idade=15;

VARIÁVEISPRIMITIVASECONTROLEDEFLUXO

3.1DECLARANDOEUSANDOVARIÁVEIS

3VARIÁVEISPRIMITIVASECONTROLEDEFLUXO 19

Page 30: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

COMENTÁRIOSEMJAVA

Parafazerumcomentárioemjava,vocêpodeusaro//paracomentaratéofinaldalinha,ou

entãousaro/**/paracomentaroqueestiverentreeles.

/*comentáriodaqui,ateaqui*/

//umalinhadecomentáriosobreaidadeintidade;

Além de atribuir, você pode utilizar esse valor. O código a seguir declara novamente a variável idade com valor 15 e imprime seu valor na saída padrão através da chamada a

System.out.println.

//declaraaidadeintidade;idade=15;

//imprimeaidadeSystem.out.println(idade);

Por fim, podemos utilizar o valor de uma variável para algum outro propósito, como alterar oudefinirumasegundavariável.OcódigoaseguircriaumavariávelchamadaidadeNoAnoQueVem com

valordeidademaisum.

//calculaaidadenoanoseguinteintidadeNoAnoQueVem;idadeNoAnoQueVem=idade+1;

Nomesmomomentoquevocêdeclaraumavariável,tambémépossívelinicializá-laporpraticidade:

intidade=15;

Você pode usar os operadores +, -, / e * para operar comnúmeros, sendo eles responsáveis pelaadição, subtração, divisão e multiplicação, respectivamente. Além desses operadores básicos, há ooperador%(módulo)quenadamaiséqueorestodeumadivisãointeira.Vejaalgunsexemplos:

intquatro=2+2;inttres=5-2;

intoito=4*2;intdezesseis=64/4;

intum=5%2;//5divididopor2dá2etemresto1;//ooperador%pegaorestodadivisãointeira

20 3.1DECLARANDOEUSANDOVARIÁVEIS

Page 31: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

COMORODARESSESCÓDIGOS?

Vocêdevecolocaressestrechosdecódigodentrodoblocomainquevimosnocapítuloanterior.Istoé, issodeve ficarnomiolodoprograma.UsebastanteSystem.out.println, dessa forma

vocêpodeveralgumresultado,casocontrário,aoexecutaraaplicação,nadaaparecerá.

Porexemplo,paraimprimiraidadeeaidadeNoAnoQueVem podemos escrever o seguinte

programadeexemplo:

classTestaIdade{

publicstaticvoidmain(String[]args){//imprimeaidadeintidade=20;System.out.println(idade);

//geraumaidadenoanoseguinteintidadeNoAnoQueVem;idadeNoAnoQueVem=idade+1;

//imprimeaidadeSystem.out.println(idadeNoAnoQueVem);}}

Representarnúmerosinteiroséfácil,mascomoguardarvaloresreais,taiscomofraçõesdenúmerosinteiroseoutros?Outrotipodevariávelmuitoutilizadoéodouble,quearmazenaumnúmerocom

pontoflutuante(equetambémpodearmazenarumnúmerointeiro).

doublepi=3.14;doublex=5*10;

O tipo boolean armazena um valor verdadeiro ou falso, e só: nada de números, palavras ouendereços,comoemalgumasoutraslinguagens.

booleanverdade=true;

trueefalse sãopalavras reservadasdoJava.Écomumqueumboolean seja determinado

através de uma expressãobooleana, isto é, um trecho de código que retorna um booleano, como oexemplo:

intidade=30;booleanmenorDeIdade=idade<18;

Otipocharguardaum,eapenasum,caractere.Essecaracteredeveestarentreaspassimples.Nãoseesqueçadessasduascaracterísticasdeumavariáveldotipochar!Porexemplo,elanãopodeguardarumcódigocomo''poisovazionãoéumcaractere!

charletra='a';

3.1DECLARANDOEUSANDOVARIÁVEIS 21

Page 32: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out.println(letra);

Variáveisdotipocharsãopoucousadasnodiaadia.VeremosmaisafrenteousodasStrings,

queusamosconstantemente,porémestasnãosãodefinidasporumtipoprimitivo.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

EssestiposdevariáveissãotiposprimitivosdoJava:ovalorqueelasguardamsãoorealconteúdodavariável.Quandovocêutilizarooperadordeatribuição=ovalorserácopiado.

inti=5;//irecebeumacópiadovalor5intj=i;//jrecebeumacópiadovalordeii=i+1;//ivira6,jcontinua5

Aqui,ificacomovalorde6.Masej?Nasegundalinha,jestávalendo5.Quandoipassaa

valer6,seráquejtambémmudadevalor?Não,poisovalordeumtipoprimitivosempreécopiado.

Apesardalinha2fazerj=i,apartirdessemomentoessasvariáveisnãotemrelaçãonenhuma:o

queacontececomuma,nãorefleteemnadacomaoutra.

OUTROSTIPOSPRIMITIVOS

Vimos aqui os tipos primitivos que mais aparecem. O Java tem outros, que são o byte,

short,longefloat.

Cada tipo possui características especiais que, para um programador avançado, podem fazermuitadiferença.

Agoraéamelhorhoradeaprenderalgonovo

3.2TIPOSPRIMITIVOSEVALORES

3.3EXERCÍCIOS:VARIÁVEISETIPOSPRIMITIVOS

22 3.2TIPOSPRIMITIVOSEVALORES

Page 33: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

1. Na empresa onde trabalhamos, há tabelas com o quanto foi gasto em cada mês. Para fechar obalanço do primeiro trimestre, precisamos somar o gasto total. Sabendo que, em Janeiro, foramgastos 15000 reais, em Fevereiro, 23000 reais e emMarço, 17000 reais, faça um programa quecalculeeimprimaogastototalnotrimestre.Sigaessespassos:

Crie uma classe chamada BalancoTrimestral com um bloco main, como nos exemplos

anteriores;Dentrodomain(omiolodoprograma),declareumavariávelinteirachamadagastosJaneiro

einicialize-acom15000;Crie tambémas variáveisgastosFevereiro egastosMarco, inicializando-as com 23000 e

17000,respectivamente,utilizeumalinhaparacadadeclaração;

CrieumavariávelchamadagastosTrimestreeinicialize-acomasomadasoutras3variáveis:

intgastosTrimestre=gastosJaneiro+gastosFevereiro+gastosMarco;

ImprimaavariávelgastosTrimestre.

2. Adicione código (sem alterar as linhas que já existem) na classe anterior para imprimir amédiamensal de gasto, criando uma variável mediaMensal junto com uma mensagem. Para isso,

concateneaStringcomovalor,usando"Valordamédiamensal="+mediaMensal.

DiscutacomoinstrutoreseuscolegassobreconvençõesdecódigoJava.Porqueexistem?Porquesãoimportantes?

Discutatambémasvantagensdeseescrevercódigofácildelereseevitarcomentáriosemexcesso.(Dica:procureporjavacodeconventions).

3.4 DISCUSSÃO EM AULA: CONVENÇÕES DE CÓDIGO E CÓDIGOLEGÍVEL

3.4DISCUSSÃOEMAULA:CONVENÇÕESDECÓDIGOECÓDIGOLEGÍVEL 23

Page 34: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Algunsvaloressãoincompatíveissevocêtentarfazerumaatribuiçãodireta.Enquantoumnúmerorealcostumaserrepresentadoemumavariáveldotipodouble,tentaratribuireleaumavariávelint

nãofuncionaporqueéumcódigoquediz:"idevevalerd",masnãosesabesed realmente é umnúmerointeiroounão.

doubled=3.1415;inti=d;//nãocompila

Omesmoocorrenoseguintetrecho:

inti=3.14;

Omaisinteressante,équenemmesmooseguintecódigocompila:

doubled=5;//ok,odoublepodeconterumnúmerointeirointi=d;//nãocompila

Apesarde5serumbomvalorparaumint,ocompiladornão temcomosaberquevalorestará

dentro desse double no momento da execução. Esse valor pode ter sido digitado pelo usuário, e

ninguémvaigarantirqueessaconversãoocorrasemperdadevalores.

Jánocasoaseguir,éocontrário:

inti=5;doubled2=i;

Ocódigoacimacompilasemproblemas,jáqueumdoublepodeguardarumnúmerocomousem

pontoflutuante.Todososinteirosrepresentadosporumavariáveldotipointpodemserguardadosem

umavariáveldouble,entãonãoexistemproblemasnocódigoacima.

Àsvezes,precisamosqueumnúmeroquebradosejaarredondadoearmazenadonumnúmerointeiro.

EditoraCasadoCódigocomlivrosdeumaformadiferente

3.5CASTINGEPROMOÇÃO

24 3.5CASTINGEPROMOÇÃO

Page 35: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Para fazer isso sem que haja o erro de compilação, é preciso ordenar que o número quebrado sejamoldado(casted)comoumnúmerointeiro.Esseprocessorecebeonomedecasting.

doubled3=3.14;inti=(int)d3;

Ocastingfoifeitoparamoldaravariáveld3comoumint.Ovalordeiagoraé3.

Omesmoocorreentrevaloresintelong.

longx=10000;inti=x;//nãocompila,poispodeestarperdendoinformação

E,sequisermosrealmentefazerisso,fazemosocasting:

longx=10000;inti=(int)x;

CASOSNÃOTÃOCOMUNSDECASTINGEATRIBUIÇÃO

Algunscastingsaparecemtambém:

floatx=0.0;

O código acima não compila pois todos os literais com ponto flutuante são consideradosdoublepeloJava.Efloatnãopodereceberumdoublesemperdadeinformação,parafazer

issofuncionarpodemosescreveroseguinte:

floatx=0.0f;

Aletraf,quepodesermaiúsculaouminúscula,indicaqueaqueleliteraldevesertratadocomofloat.

Outrocaso,queémaiscomum:

doubled=5;floatf=3;

floatx=f+(float)d;

VocêprecisadocastingporqueoJavafazascontasevaiarmazenandosemprenomaiortipoqueapareceuduranteasoperações,nocasoodouble.

E,umaobservação:nomínimo,oJavaarmazenaoresultadoemumint,nahoradefazeras

contas.

Atécastingcomvariáveisdotipocharpodemocorrer.Oúnicotipoprimitivoquenãopode

seratribuídoanenhumoutrotipoéoboolean.

3.5CASTINGEPROMOÇÃO 25

Page 36: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CASTINGSPOSSÍVEIS

AbaixoestãorelacionadostodososcastspossíveisnalinguagemJava,mostrandoaconversãodeumvalorparaoutro.AindicaçãoImpl.querdizerqueaquelecastéimplícitoeautomático,ouseja,vocênãoprecisa indicarocast explicitamente (lembrandoqueo tipobooleannãopode serconvertidoparanenhumoutrotipo).

TAMANHODOSTIPOS

Natabelaabaixo,estãoostamanhosdecadatipoprimitivodoJava.

AsintaxedoifnoJavaéaseguinte:

if(condicaoBooleana){codigo;}

3.6OIFEOELSE

26 3.6OIFEOELSE

Page 37: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Umacondiçãobooleanaéqualquerexpressãoqueretornetrueoufalse.Paraisso,vocêpodeusarosoperadores<,>,<=,>=eoutros.Umexemplo:

intidade=15;if(idade<18){System.out.println("Nãopodeentrar");}

Alémdisso,vocêpodeusaracláusulaelseparaindicarocomportamentoquedeveserexecutado

nocasodaexpressãobooleanaserfalsa:

intidade=15;if(idade<18){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Vocêpodeconcatenarexpressõesbooleanasatravésdosoperadoreslógicos"E"e"OU".O"E"érepresentadopelo&&eo"OU"érepresentadopelo||.

Umexemploseriaverificarseeletemmenosde18anoseseelenãoéamigododono:

intidade=15;booleanamigoDoDono=true;if(idade<18&&amigoDoDono==false){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Esse código poderia ficar ainda mais legível, utilizando-se o operador de negação, o !. Esse

operadortransformaoresultadodeumaexpressãobooleanadefalseparatrueeviceversa.

intidade=15;booleanamigoDoDono=true;if(idade<18&&!amigoDoDono){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Reparenalinha3queotrechoamigoDoDono==falsevirou!amigoDoDono.Elestêmomesmovalor.

Para comparar se uma variável tem o mesmo valor que outra variável ou valor, utilizamos ooperador==.Reparequeutilizarooperador=dentrodeumifvairetornarumerrodecompilação,

jáqueooperador=éodeatribuição.

intmes=1;if(mes==1){System.out.println("Vocêdeveriaestardeférias");}

3.6OIFEOELSE 27

Page 38: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Owhile é um comando usado para fazer um laço (loop), isto é, repetir um trecho de códigoalgumasvezes.Aideiaéqueessetrechodecódigosejarepetidoenquantoumadeterminadacondiçãopermanecerverdadeira.

intidade=15;while(idade<18){System.out.println(idade);idade=idade+1;}

Otrechodentrodoblocodowhileseráexecutadoatéomomentoemqueacondiçãoidade<18

passe a ser falsa.E issoocorrerá exatamentenomomentoemqueidade==18, o quenãoo fará

imprimir18.

inti=0;while(i<10){System.out.println(i);i=i+1;}

Jáowhileacimaimprimede0a9.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Outrocomandodeloopextremamenteutilizadoéofor.Aideiaéamesmadowhile:fazerumtrecho de código ser repetido enquanto uma condição continuar verdadeira.Mas alémdisso, ofor

isolatambémumespaçoparainicializaçãodevariáveiseomodificadordessasvariáveis.Issofazcomquefiquemmaislegíveis,asvariáveisquesãorelacionadasaoloop:

for(inicializacao;condicao;incremento){codigo;

3.7OWHILE

JáconheceoscursosonlineAlura?

3.8OFOR

28 3.7OWHILE

Page 39: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

Umexemploéoaseguir:

for(inti=0;i<10;i=i+1){System.out.println("olá!");}

Reparequeesseforpoderiasertrocadopor:

inti=0;while(i<10){System.out.println("olá!");i=i+1;}

Porém,ocódigodoforindicaclaramentequeavariáveliserve,emespecial,paracontrolara

quantidadedelaçosexecutados.Quandousarofor?Quandousarowhile?Dependedogostoeda

ocasião.

PÓSINCREMENTO++

i=i+1poderealmentesersubstituídopori++quandoisolado,porém,emalgunscasos,

temosessainstruçãoenvolvidaem,porexemplo,umaatribuição:

inti=5;intx=i++;

Qualéovalordex?Odei,apósessalinha,é6.

O operador ++, quando vem após a variável, retorna o valor antigo, e incrementa (pós

incremento),fazendoxvaler5.

Sevocêtivesseusadoo++antesdavariável(préincremento),oresultadoseria6:

inti=5;intx=++i;//aquixvalera6

Apesardetermoscondiçõesbooleanasnosnossoslaços,emalgummomento,podemosdecidirpararoloopporalgummotivoespecialsemqueorestodolaçosejaexecutado.

for(inti=x;i<y;i++){if(i%19==0){System.out.println("Acheiumnúmerodivisívelpor19entrexey");break;}}

3.9CONTROLANDOLOOPS

3.9CONTROLANDOLOOPS 29

Page 40: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Ocódigoacimavaipercorrerosnúmerosdexayepararquandoencontrarumnúmerodivisívelpor19,umavezquefoiutilizadaapalavrachavebreak.

Damesmamaneira,épossívelobrigaroloopaexecutaropróximolaço.Paraissousamosapalavrachavecontinue.

for(inti=0;i<100;i++){if(i>50&&i<60){continue;}System.out.println(i);}

Ocódigoacimanãovaiimprimiralgunsnúmeros.(Quaisexatamente?)

No Java, podemos declarar variáveis a qualquer momento. Porém, dependendo de onde você asdeclarou,elavaivalerdeumdeterminadopontoaoutro.

//aquiavariávelinãoexisteinti=5;//apartirdaquielaexiste

Oescopodavariáveléonomedadoaotrechodecódigoemqueaquelavariávelexisteeondeépossívelacessá-la.

Quandoabrimosumnovoblococomaschaves,asvariáveisdeclaradasalidentrosóvalematéofimdaquelebloco.

//aquiavariávelinãoexisteinti=5;//apartirdaquielaexistewhile(condicao){//oiaindavaleaquiintj=7;//ojpassaaexistir}//aquiojnãoexistemais,masoicontinuadentrodoescopo

Noblocoacima,avariáveljpáradeexistirquandoterminaoblocoondeelafoideclarada.Sevocê

tentaracessarumavariávelforadeseuescopo,ocorreráumerrodecompilação.

Omesmovaleparaumif:

3.10ESCOPODASVARIÁVEIS

30 3.10ESCOPODASVARIÁVEIS

Page 41: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

if(algumBooleano){inti=5;}else{inti=10;}System.out.println(i);//cuidado!

Aquiavariávelinãoexisteforadoifedoelse!Sevocêdeclararavariávelantesdoif,vai

haveroutroerrodecompilação:dentrodoifedoelseavariávelestásendoredeclarada!Entãoo

códigoparacompilarefazersentidofica:

inti;if(algumBooleano){i=5;}else{i=10;}System.out.println(i);

Umasituaçãoparecidapodeocorrercomofor:

for(inti=0;i<10;i++){System.out.println("olá!");}System.out.println(i);//cuidado!

Nestefor,avariávelimorreaoseutérmino,nãopodendoseracessadadeforadofor,gerando

umerrodecompilação.Sevocêrealmentequeracessarocontadordepoisdoloopterminar,precisadealgocomo:

inti;for(i=0;i<10;i++){System.out.println("olá!");}System.out.println(i);

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

3.10ESCOPODASVARIÁVEIS 31

Page 42: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Umblocotambémpodeserdeclaradodentrodeoutro.Istoé,umifdentrodeumfor,ouum

fordentrodeumfor,algocomo:

while(condicao){for(inti=0;i<10;i++){//código}}

Vimosapenasoscomandosmaisusadosparacontroledefluxo.OJavaaindapossuiodo..while

eoswitch.Pesquisesobreelesedigaquandoéinteressanteusarcadaumdeles.

Algumasvezes, temosvários laços encadeados.Podemosutilizarobreak para quebrar o laço

maisinterno.Mas,sequisermosquebrarumlaçomaisexterno,teremosdeencadeardiversosifseseucódigoficaráumabagunça.OJavapossuiumartifíciochamadolabeledloops;pesquisesobreeles.

Oqueacontecesevocêtentardividirumnúmerointeiropor0?Epor0.0?

Existeumcaminhoentreos tiposprimitivosque indicamseháanecessidadeounãodecastingentreos tipos.Porexemplo,int ->long ->double (umint pode ser tratado comoum

double,masnãoocontrário).Pesquise (ou teste), eposicioneosoutros tiposprimitivosnesse

fluxo.

Alémdosoperadoresdeincremento,existemosdedecremento,como--iei--.Alémdesses,

vocêpodeusarinstruçõesdotipoi+=xei-=x,oqueessasinstruçõesfazem?Teste.

Mais exercícios de fixação de sintaxe. Para quem já conhece um pouco de Java, pode sermuitosimples;mas recomendamos fortemente que você faça os exercícios para se acostumar comerros decompilação,mensagensdojavac,convençãodecódigo,etc...

Apesardeextremamentesimples,precisamospraticarasintaxequeestamosaprendendo.Paracadaexercício,crieumnovoarquivocomextensão.java,edeclareaqueleestranhocabeçalho,dandonomeaumaclasseecomumblocomaindentrodele:

classExercicioX{publicstaticvoidmain(String[]args){//seuexercíciovaiaqui}}

3.11UMBLOCODENTRODOOUTRO

3.12PARASABERMAIS

3.13EXERCÍCIOS:FIXAÇÃODESINTAXE

32 3.11UMBLOCODENTRODOOUTRO

Page 43: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Nãocopieecoledeumexercíciojáexistente!Aproveiteparapraticar.

1. Imprimatodososnúmerosde150a300.

2. Imprimaasomade1até1000.

3. Imprimatodososmúltiplosde3,entre1e100.

4. Imprimaosfatoriaisde1a10.

Ofatorialdeumnúmeronén*(n-1)*(n-2)*...*1.Lembre-sedeutilizarosparênteses.

Ofatorialde0é1

Ofatorialde1é(0!)*1=1

Ofatorialde2é(1!)*2=2

Ofatorialde3é(2!)*3=6

Ofatorialde4é(3!)*4=24

Façaumforqueinicieumavariáveln(número)como1efatorial(resultado)como1evariande1até10:

intfatorial=1;for(intn=1;n<=10;n++){

}

5. Nocódigodoexercícioanterior,aumenteaquantidadedenúmerosqueterãoosfatoriaisimpressos,até20,30,40.Emumdeterminadomomento,alémdessecálculodemorar,vaicomeçaramostrarrespostascompletamenteerradas.Porquê?

Mudedeintparalongparaveralgumamudança.

6. (opcional) Imprima os primeiros números da série de Fibonacci até passar de 100. A série deFibonacciéaseguinte:0,1,1,2,3,5,8,13,21,etc...Paracalculá-la,oprimeiroelementovale0,osegundovale1,daípordiante,on-ésimoelementovaleo(n-1)-ésimoelementosomadoao(n-2)-ésimoelemento(ex:8=5+3).

7. (opcional)Escrevaumprogramaque, dadaumavariávelx com algum valor inteiro, temosum

novoxdeacordocomaseguinteregra:

sexépar,x=x/2

sexéimpar,x=3*x+1

imprimex

3.13EXERCÍCIOS:FIXAÇÃODESINTAXE 33

Page 44: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Oprogramadevepararquandoxtiverovalorfinalde1.Porexemplo,parax=13,asaída

será:

40->20->10->5->16->8->4->2->1

IMPRIMINDOSEMPULARLINHA

Umdetalhe importante équeumaquebrade linhaé impressa todavezquechamamosprintln.Paranãopularumalinha,usamosocódigoaseguir:

System.out.print(variavel);

8. (opcional)Imprimaaseguintetabela,usandoforsencadeados:

124369481216nn*2n*3....n*n

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

1. FaçaoexercíciodasériedeFibonacciusandoapenasduasvariáveis.

Seuslivrosdetecnologiaparecemdoséculopassado?

3.14DESAFIOS:FIBONACCI

34 3.14DESAFIOS:FIBONACCI

Page 45: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO4

"Programaçãoorientadaaobjetoséumapéssimaideia,quesópoderiaternascidonaCalifórnia."--EdsgerDijkstra

Aotérminodestecapítulo,vocêserácapazde:

dizeroqueéeparaqueserveorientaçãoaobjetos;conceituarclasses,atributosecomportamentos;entenderosignificadodevariáveiseobjetosnamemória.

Orientação a objetos é uma maneira de programar que ajuda na organização e resolve muitosproblemasenfrentadospelaprogramaçãoprocedural.

ConsideremosoclássicoproblemadavalidaçãodeumCPF.Normalmente,temosumformulário,noqualrecebemosessa informação,edepois temosqueenviaressescaracteresparaumafunçãoquevaivalidá-lo,comonopseudocódigoabaixo:

cpf=formulario->campo_cpfvalida(cpf)

AlguémteobrigaasemprevalidaresseCPF?Vocêpode,inúmerasvezes,esquecerdechamaressevalidador.Mais:considerequevocêtem50formulárioseprecisevalidaremtodoselesoCPF.Sesuaequipetem3programadorestrabalhandonessesformulários,quemficaresponsávelporessavalidação?Todos!

Asituaçãopodepiorar:naentradadeumnovodesenvolvedor,precisaríamosavisá-loquesempredevemosvalidarocpfdeumformulário.Énessemomentoquenascemaquelesguiasdeprogramaçãopara o desenvolvedor que for entrar nesse projeto - às vezes, é um documento enorme. Em outraspalavras,tododesenvolvedorprecisaficarsabendodeumaquantidadeenormedeinformações,que,namaioriadasvezes,nãoestárealmenterelacionadoàsuapartenosistema,maseleprecisalertudoisso,resultandoumentravemuitogrande!

Outra situação onde ficam claros os problemas da programação procedural, é quando nosencontramosnanecessidadedelerocódigoquefoiescritoporoutrodesenvolvedoredescobrircomoele funciona internamente.Umsistemabemencapsuladonãodeveriagerar essanecessidade.Emum

ORIENTAÇÃOAOBJETOSBÁSICA

4.1MOTIVAÇÃO:PROBLEMASDOPARADIGMAPROCEDURAL

4ORIENTAÇÃOAOBJETOSBÁSICA 35

Page 46: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

sistemagrande,simplesmentenãotemostempodelertodoocódigoexistente.

Considerandoquevocênãoerrenessepontoequesuaequipe tenhaumacomunicaçãomuitoboa(percebaquecomunicaçãoexcessivapodeserprejudicialeatrapalharoandamento),aindatemosoutroproblema:imagineque,emtodoformulário,vocêtambémquerqueaidadedoclientesejavalidada-oclienteprecisatermaisde18anos.Vamosterdecolocarumif...masonde?Espalhadoportodoseu

código... Mesmo que se crie outra função para validar, precisaremos incluir isso nos nossos 50formuláriosjáexistentes.Qualéachancedeesquecermosemumdeles?Émuitogrande.

Aresponsabilidadedeverificarseoclientetemounãotem18anosficouespalhadaportodooseucódigo.Seriainteressantepoderconcentraressaresponsabilidadeemumlugarsó,paranãoterchancesdeesquecerisso.

Melhor ainda seria se conseguíssemos mudar essa validação e os outros programadores nemprecisassemficarsabendodisso.Emoutraspalavras,elescriariamformulárioseumúnicoprogramadorseriaresponsávelpelavalidação:osoutrosnemsabemdaexistênciadessetrechodecódigo.Impossível?Não,oparadigmadaorientaçãoaobjetosfacilitatudoisso.

Oproblemadoparadigmaprocedural é quenão existe uma forma simples de criar conexão forteentredadosefuncionalidades.Noparadigmaorientadoaobjetosémuitofácilteressaconexãoatravésdosrecursosdapróprialinguagem.

QUAISASVANTAGENS?

Orientação a objetos vai te ajudar em muito em se organizar e escrever menos, além deconcentrar as responsabilidades nos pontos certos, flexibilizando sua aplicação, encapsulando alógicadenegócios.

Outra enorme vantagem, onde você realmente vai economizar montanhas de código, é opolimorfismodasreferências,queveremosemumposteriorcapítulo.

Nos próximos capítulos, conseguiremos enxergar toda essa vantagem, mas, primeiramente énecessárioconhecerumpoucomaisdasintaxeedacriaçãodetiposereferênciasemJava.

36 4.1MOTIVAÇÃO:PROBLEMASDOPARADIGMAPROCEDURAL

Page 47: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Considere um programa para um banco, é bem fácil perceber que uma entidade extremamenteimportante para o nosso sistema é a conta. Nossa ideia aqui é generalizarmos alguma informação,juntamentecomfuncionalidadesquetodacontadeveter.

Oquetodacontatemeéimportanteparanós?

númerodacontanomedotitulardacontasaldo

Oquetodacontafazeéimportanteparanós?Istoé,oquegostaríamosde"pediràconta"?

sacaumaquantidadexdepositaumaquantidadeximprimeonomedotitulardacontadevolveosaldoatualtransfereumaquantidadexparaumaoutracontaydevolveotipodeconta

Comisso,temosoprojetodeumacontabancária.Podemospegaresseprojetoeacessarseusaldo?Não.Oquetemosaindaéoprojeto.Antes,precisamosconstruirumaconta,parapoderacessaroqueelatem,epediraelaquefaçaalgo.

Agoraéamelhorhoradeaprenderalgonovo

4.2CRIANDOUMTIPO

4.2CRIANDOUMTIPO 37

Page 48: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Reparenafigura:apesardopapeldoladoesquerdoespecificarumaConta,essaespecificaçãoéumaConta?Nós depositamos e sacamos dinheiro desse papel?Não.Utilizamos a especificação daContaparapodercriarinstânciasquerealmentesãocontas,ondepodemosrealizarasoperaçõesquecriamos.

Apesardedeclararmosquetodacontatemumsaldo,umnúmeroeumaagêncianopedaçodepapel(comoàesquerdanafigura),sãonasinstânciasdesseprojetoquerealmenteháespaçoparaarmazenaressesvalores.

Aoprojetodaconta,istoé,adefiniçãodaconta,damosonomedeclasse.Aoquepodemosconstruirapartirdesseprojeto,ascontasdeverdade,damosonomedeobjetos.

A palavra classe vem da taxonomia da biologia. Todos os seres vivos de uma mesma classebiológicatêmumasériedeatributosecomportamentosemcomum,masnãosãoiguais,podemvariarnosvaloresdessesatributosecomorealizamessescomportamentos.

HomoSapiensdefineumgrupodeseresquepossuemcaracterísticasemcomum,porémadefinição(a ideia,oconceito)deumHomoSapiens éumserhumano?Não.Tudoestá especificadonaclasseHomoSapiens,massequisermosmandaralguémcorrer,comer,pular,precisaremosdeumainstânciadeHomoSapiens,ouentãodeumobjetodotipoHomoSapiens.

Umoutroexemplo:umareceitadebolo.Aperguntaécerteira:vocêcomeumareceitadebolo?Não.

38 4.2CRIANDOUMTIPO

Page 49: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Precisamos instanciá-la, criar um objeto bolo a partir dessa especificação (a classe) para utilizá-la.Podemos criar centenas de bolos a partir dessa classe (a receita, no caso), eles podem ser bemsemelhantes,algunsatéidênticos,massãoobjetosdiferentes.

Podemos fazer milhares de analogias semelhantes. A planta de uma casa é uma casa?Definitivamentenão.Nãopodemosmorardentrodaplantadeumacasa,nempodemosabrirsuaportaou pintar suas paredes. Precisamos, antes, construir instâncias a partir dessa planta. Essas instâncias,sim,podemospintar,decoraroumorardentro.

Pode parecer óbvio,mas a dificuldade inicial do paradigmada orientação a objetos é justo saberdistinguiroqueéclasseeoqueéobjeto.Écomumo inicianteutilizar,obviamentede formaerrada,essasduaspalavrascomosinônimos.

VamoscomeçarapenascomoqueumaConta tem, enãocomoqueela faz (veremos logoem

seguida).

Umtipodesses,comooespecificadodeContaacima,podeserfacilmentetraduzidoparaJava:

classConta{intnumero;Stringtitular;doublesaldo;

//..}

STRING

StringéumaclasseemJava.Elaguardaumacadeiadecaracteres,umafrasecompleta.Comoestamos ainda aprendendo o que é uma classe, entenderemos com detalhes a classe String

apenasemcapítulosposteriores.

Porenquanto,declaramosoquetodacontadeveter.Estessãoosatributosquetodaconta,quandocriada,vaiter.Reparequeessasvariáveisforamdeclaradasforadeumbloco,diferentedoquefazíamosquandotinhaaquelemain.Quandoumavariávelédeclaradadiretamentedentrodoescopodaclasse,échamadadevariáveldeobjeto,ouatributo.

JátemosumaclasseemJavaqueespecificaoquetodoobjetodessaclassedeveter.Mascomousá-

4.3UMACLASSEEMJAVA

4.4CRIANDOEUSANDOUMOBJETO

4.3UMACLASSEEMJAVA 39

Page 50: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

la?Alémdessa classe, ainda teremos oPrograma.java e a partir dele é que vamos utilizar a classeConta.

Paracriar (construir, instanciar)umaConta, bastausar apalavrachavenew.Devemosutilizar

tambémosparênteses,quedescobriremosoquefazemexatamenteemumcapítuloposterior:

classPrograma{publicstaticvoidmain(String[]args){newConta();}}

Bem,ocódigoacimacriaumobjetodotipoConta,mascomoacessaresseobjetoquefoicriado?

Precisamosteralgumaformadenosreferenciarmosaesseobjeto.Precisamosdeumavariável:

classPrograma{publicstaticvoidmain(String[]args){ContaminhaConta;minhaConta=newConta();}}

PodeparecerestranhoescrevermosduasvezesConta:umaveznadeclaraçãodavariáveleoutra

veznousodonew.Masháummotivo,queembreveentenderemos.

Através da variável minhaConta , podemos acessar o objeto recém criado para alterar seu

titular,seusaldo,etc:

classPrograma{publicstaticvoidmain(String[]args){ContaminhaConta;minhaConta=newConta();

minhaConta.titular="Duke";minhaConta.saldo=1000.0;

System.out.println("Saldoatual:"+minhaConta.saldo);}}

Éimportante fixarqueoponto foiutilizadoparaacessaralgoemminhaConta.AminhaConta

pertenceaoDuke,etemsaldodemilreais.

40 4.4CRIANDOEUSANDOUMOBJETO

Page 51: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Dentro da classe, também declararemos o que cada conta faz e como isto é feito - oscomportamentosquecadaclassetem,istoé,oqueelafaz.Porexemplo,dequemaneiraqueumaContasacadinheiro?EspecificaremosissodentrodaprópriaclasseConta,enãoemumlocaldesatreladodas

informações da própria Conta. É por isso que essas "funções" são chamadas demétodos. Pois é amaneiradefazerumaoperaçãocomumobjeto.

Queremos criar um método que saca uma determinada quantidade e não devolve nenhumainformaçãoparaquemacionaressemétodo:

classConta{doublesalario;//...outrosatributos...

voidsaca(doublequantidade){doublenovoSaldo=this.saldo-quantidade;this.saldo=novoSaldo;}}

A palavra chave void diz que, quando você pedir para a conta sacar uma quantia, nenhuma

informaçãoseráenviadadevoltaaquempediu.

Quando alguém pedir para sacar, ele também vai dizer quanto quer sacar. Por isso precisamosdeclararométodocomalgodentrodosparênteses-oquevaiaídentroéchamadodeargumentodométodo(ouparâmetro).Essavariáveléumavariávelcomum,chamadatambémdetemporáriaoulocal,pois,aofinaldaexecuçãodessemétodo,eladeixadeexistir.

Dentrodométodo,estamosdeclarandoumanovavariável.Essavariável,assimcomooargumento,vaimorrernofimdométodo,poisesteéseuescopo.Nomomentoquevamosacessarnossoatributo,

EditoraCasadoCódigocomlivrosdeumaformadiferente

4.5MÉTODOS

4.5MÉTODOS 41

Page 52: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

usamos a palavra chave this para mostrar que esse é um atributo, e não uma simples variável.

(veremosdepoisqueéopcional)

Repare que, nesse caso, a conta poderia estourar um limite fixado pelo banco.Mais para frente,evitaremosessasituação,edeumamaneiramuitoelegante.

Damesmaforma,temosométodoparadepositaralgumaquantia:

classConta{//...outrosatributosemétodos...

voiddeposita(doublequantidade){this.saldo+=quantidade;}}

Observequenãousamosumavariávelauxiliare,alémdisso,usamosaabreviação+=paradeixaro

métodobemsimples.O+= somaquantidade aovalor antigodo saldo e guardanopróprio saldo, o

valorresultante.

Paramandarumamensagemaoobjetoepedirqueeleexecuteummétodo,tambémusamosoponto.Otermousadoparaissoéinvocaçãodemétodo.

Ocódigoaseguirsacadinheiroedepoisdepositaoutraquantiananossaconta:

classTestaAlgunsMetodos{publicstaticvoidmain(String[]args){//criandoacontaContaminhaConta;minhaConta=newConta();

//alterandoosvaloresdeminhaContaminhaConta.titular="Duke";minhaConta.saldo=1000;

//saca200reaisminhaConta.saca(200);

//deposita500reaisminhaConta.deposita(500);System.out.println(minhaConta.saldo);}}

Uma vez que seu saldo inicial é 1000 reais, se sacarmos 200 reais, depositarmos 500 reais eimprimirmosovalordosaldo,oqueseráimpresso?

Ummétodo sempre temquedefiniroque retorna,nemquedefinaquenãohá retorno, comonosexemplosanterioresondeestávamosusandoovoid.

4.6MÉTODOSCOMRETORNO

42 4.6MÉTODOSCOMRETORNO

Page 53: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Ummétodopoderetornarumvalorparaocódigoqueochamou.Nocasodonossométodosaca,

podemosdevolverumvalorbooleanoindicandoseaoperaçãofoibemsucedida.

classConta{//...outrosmétodoseatributos...

booleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo=this.saldo-valor;returntrue;}}}

Adeclaraçãodométodomudou!Ométodosacanão temvoid na frente. Isto quer dizer que,

quandoé acessado, eledevolve algum tipode informação.Nocaso,umboolean.Apalavra chave

returnindicaqueométodovaiterminarali,retornandotalinformação.

Exemplodeuso:

minhaConta.saldo=1000;booleanconsegui=minhaConta.saca(2000);if(consegui){System.out.println("Conseguisacar");}else{System.out.println("Nãoconseguisacar");}

Ouentão,possoeliminaravariáveltemporária,sedesejado:

minhaConta.saldo=1000;if(minhaConta.saca(2000)){System.out.println("Conseguisacar");}else{System.out.println("Nãoconseguisacar");}

Maisadiante,veremosquealgumasvezesémaisinteressantelançarumaexceção(exception)nessescasos.

Meuprogramapodemanternamemórianãoapenasumaconta,comomaisdeuma:

4.6MÉTODOSCOMRETORNO 43

Page 54: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classTestaDuasContas{publicstaticvoidmain(String[]args){

ContaminhaConta;minhaConta=newConta();minhaConta.saldo=1000;

ContameuSonho;meuSonho=newConta();meuSonho.saldo=1500000;}}

Quandodeclaramosumavariávelparaassociaraumobjeto,naverdade,essavariávelnãoguardaoobjeto,esimumamaneiradeacessá-lo,chamadadereferência.

Époressemotivoque,diferentedos tiposprimitivoscomoint elong, precisamosdarnew

depoisdedeclaradaavariável:

publicstaticvoidmain(String[]args){Contac1;c1=newConta();

Contac2;c2=newConta();}

Ocorretoaqui,édizerquec1serefereaumobjeto.Nãoécorretodizerquec1éumobjeto,poisc1éumavariávelreferência,apesarde,depoisdeumtempo,osprogramadoresJavafalarem"Tenho

umobjetocdotipoConta",masapenasparaencurtarafrase"TenhoumareferênciacaumobjetodotipoConta".

Bastalembrarque,emJava,umavariávelnuncaéumobjeto.Nãohá,noJava,umamaneiradecriarmos o que é conhecido como "objeto pilha" ou "objeto local", pois todo objeto em Java, semexceção,éacessadoporumavariávelreferência.

Essecódigonosdeixanaseguintesituação:

Contac1;c1=newConta();

Contac2;c2=newConta();

4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS

44 4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS

Page 55: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Internamente,c1ec2vãoguardarumnúmeroqueidentificaemqueposiçãodamemóriaaquela

Contaseencontra.Dessamaneira,aoutilizarmoso"."paranavegar,oJavavaiacessaraContaque

seencontranaquelaposiçãodememória,enãoumaoutra.

Para quem conhece, é parecido com um ponteiro, porém você não pode manipulá-lo como umnúmeroenemutilizá-loparaaritmética,elaétipada.

Umoutroexemplo:

classTestaReferencias{publicstaticvoidmain(String[]args){Contac1=newConta();c1.deposita(100);

Contac2=c1;//linhaimportante!c2.deposita(200);

System.out.println(c1.saldo);System.out.println(c2.saldo);}}

Qualéoresultadodocódigoacima?Oqueapareceaorodar?

Oqueaconteceaqui?Ooperador=copiaovalordeumavariável.Masqualéovalordavariável

c1?Éoobjeto?Não.Naverdade, o valor guardado é a referência (endereço) deondeoobjeto seencontranamemóriaprincipal.

Namemória,oqueacontecenessecaso:

Contac1=newConta();Contac2=c1;

4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS 45

Page 56: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Quandofizemosc2=c1,c2passaafazerreferênciaparaomesmoobjetoquec1referencia

nesseinstante.

Então,nessecódigoemespecífico,quandoutilizamosc1ouc2estamosnosreferindoexatamente

aomesmoobjeto!Elassãoduasreferênciasdistintas,porémapontamparaomesmoobjeto!Compará-lascom"=="vainosretornartrue,poisovalorqueelascarregaméomesmo!

Outraformadeperceber,équedemosapenasumnew,entãosópodehaverumobjetoContana

memória.

Atenção:nãoestamosdiscutindoaquiautilidadedefazerumareferênciaapontarpromesmoobjetoque outra. Essa utilidade ficará mais clara quando passarmos variáveis do tipo referência comoargumentoparamétodos.

NEW

Oqueexatamentefazonew?

Onewexecutaumasériedetarefas,queveremosmaisadiante.

Mas, para melhor entender as referências no Java, saiba que o new, depois de alocar a

memória para esse objeto, devolve uma "flecha", isto é, um valor de referência. Quando vocêatribuiissoaumavariável,essavariávelpassaasereferirparaessemesmoobjeto.

Podemosentãoveroutrasituação:

publicstaticvoidmain(String[]args){Contac1=newConta();c1.titular="Duke";c1.saldo=227;

Contac2=newConta();c2.titular="Duke";c2.saldo=227;

if(c1==c2){System.out.println("Contasiguais");}}

Ooperador==comparaoconteúdodasvariáveis,masessasvariáveisnãoguardamoobjeto,esim

oendereçoemqueeleseencontra.Comoemcadaumadessasvariáveisguardamosduascontascriadasdiferentemente,elasestãoemespaçosdiferentesdamemória,oquefazotestenoifvalerfalse.As

contas podem ser equivalentes no nosso critério de igualdade, porém elas não são omesmo objeto.Quandosetratadeobjetos,podeficarmaisfácilpensarqueo==comparaseosobjetos(referências,na

46 4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS

Page 57: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

verdade)sãoomesmo,enãosesãoiguais.

Para saber se dois objetos têm o mesmo conteúdo, você precisa comparar atributo por atributo.Veremosumasoluçãomaiseleganteparaissotambém.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Esequisermos terummétodoque transferedinheiroentreduascontas?Podemosficar tentadosacriarummétodoquerecebedoisparâmetros:conta1econta2dotipoConta.Mascuidado:assim

estamospensandodemaneiraprocedural.

Aideiaéque,quandochamarmosométodotransfere,játeremosumobjetodotipoConta(o

this), portantoométodo recebe apenasum parâmetrodo tipoConta, a Conta destino (além do

valor):

classConta{

//atributosemétodos...

voidtransfere(Contadestino,doublevalor){

JáconheceoscursosonlineAlura?

4.8OMÉTODOTRANSFERE()

4.8OMÉTODOTRANSFERE() 47

Page 58: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

this.saldo=this.saldo-valor;destino.saldo=destino.saldo+valor;}}

Para deixar o código mais robusto, poderíamos verificar se a conta possui a quantidade a sertransferidadisponível.Paraficaraindamaisinteressante,vocêpodechamarosmétodosdeposita e

sacajáexistentesparafazeressatarefa:

classConta{

//atributosemétodos...

booleantransfere(Contadestino,doublevalor){booleanretirou=this.saca(valor);if(retirou==false){//nãodeuprasacar!returnfalse;}else{destino.deposita(valor);returntrue;}}}

QuandopassamosumaContacomoargumento,oqueseráqueacontecenamemória?Seráqueo

objetoéclonado?

No Java, a passagem de parâmetro funciona como uma simples atribuição como no uso do "=".Então,esseparâmetrovaicopiarovalordavariáveldotipoContaqueforpassadocomoargumento.E

qualéovalordeumavariáveldessas?Seuvaloréumendereço,umareferência,nuncaumobjeto.Por

48 4.8OMÉTODOTRANSFERE()

Page 59: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

issonãohácópiadeobjetosaqui.

Esseúltimocódigopoderiaserescritocomumasintaxemuitomaissucinta.Como?

TRANSFEREPARA

PercebaqueonomedestemétodopoderiasertransfereParaaoinvésdesótransfere.A

chamadadométodoficamuitomaisnatural,épossível lera fraseemportuguêsqueela temumsentido:

conta1.transferePara(conta2,50);

Aleituradestecódigoseria"Conta1transfereparaconta250reais".

As variáveis do tipo atributo, diferentemente das variáveis temporárias (declaradas dentro de ummétodo),recebemumvalorpadrão.Nocasonumérico,valem0,nocasodeboolean,valemfalse.

Vocêtambémpodedarvaloresdefault,comosegue:

classConta{intnumero=1234;Stringtitular="Duke";doublesaldo=1000.0;}

Nesse caso, quando você criar uma conta, seus atributos já estão "populados" com esses valorescolocados.

ImaginequecomecemosaaumentarnossaclasseContaeadicionarnome,sobrenomeecpfdo

titulardaconta.Começaríamosatermuitosatributos...e,sevocêpensardireito,umaContanãotem

nome,nemsobrenomenemcpf,quemtemessesatributoséumCliente.Entãopodemoscriar

umanovaclasseefazerumacomposição

Seus atributos também podem ser referências para outras classes. Suponha a seguinte classeCliente:

classCliente{Stringnome;Stringsobrenome;Stringcpf;}

classConta{intnumero;doublesaldo;

4.9CONTINUANDOCOMATRIBUTOS

4.9CONTINUANDOCOMATRIBUTOS 49

Page 60: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Clientetitular;//..}

Edentrodomaindaclassedeteste:

classTeste{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();Clientec=newCliente();minhaConta.titular=c;//...}}

Aqui,simplesmentehouveumaatribuição.Ovalordavariávelcécopiadoparaoatributotitular

doobjeto aoqualminhaConta se refere.Emoutras palavras,minhaConta temuma referência ao

mesmoClientequecserefere,epodeseracessadoatravésdeminhaConta.titular.

Vocêpoderealmentenavegarsobretodaessaestruturadeinformação,sempreusandooponto:

ClienteclienteDaMinhaConta=minhaConta.titular;clienteDaMinhaConta.nome="Duke";

Ouainda,podefazerissodeumaformamaisdiretaeatémaiselegante:

minhaConta.titular.nome="Duke";

Umsistemaorientadoaobjetoséumgrandeconjuntodeclassesquevaisecomunicar,delegandoresponsabilidadesparaquemformaisaptoarealizardeterminadatarefa.AclasseBancousaaclasse

ContaqueusaaclasseCliente,queusaaclasseEndereco.Dizemosqueessesobjetoscolaboram,

trocandomensagensentresi.Porissoacabamostendomuitasclassesemnossosistema,eelascostumamterumtamanhorelativamentecurto.

Mas,esedentrodomeucódigoeunãodessenewemClienteetentasseacessá-lodiretamente?

classTeste{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();

minhaConta.titular.nome="Manoel";//...}}

Quando damos new em um objeto, ele o inicializa com seus valores default, 0 para números,

falseparabooleanenullparareferências.nulléumapalavrachaveemjava,queindicauma

referênciaparanenhumobjeto.

50 4.9CONTINUANDOCOMATRIBUTOS

Page 61: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Se,emalgumcaso,vocêtentaracessarumatributooumétododealguémqueestásereferenciandoparanull,vocêreceberáumerroduranteaexecução(NullPointerException,queveremosmaisà

frente).Daparaperceber,então,queonewnãotrazumefeitocascata,amenosquevocêdêumvalor

default(ouuseconstrutores,quetambémveremosmaisafrente):

classConta{intnumero;doublesaldo;Clientetitular=newCliente();//quandochamaremnewConta,//haveraumnewClienteparaele.}

Comessecódigo,todanovaContacriadajáteráumnovoClienteassociado,semnecessidade

de instanciá-lo logo em seguida da instanciação de uma Conta. Qual alternativa você deve usar?

Dependedocaso:paratodanovaContavocêprecisadeumnovoCliente?Éessaperguntaquedeve

serrespondida.Nessenossocasoarespostaénão,masdependedonossoproblema.

Atenção:paraquemnãoestáacostumadocomreferências,podeserbastanteconfusopensarsempreem como os objetos estão namemória para poder tirar as conclusões de o que ocorrerá ao executardeterminado código, por mais simples que ele seja. Com tempo, você adquire a habilidade derapidamente saber o efeito de atrelar as referências, sem ter de gastar muito tempo para isso. Éimportante,nessecomeço,vocêestarsemprepensandonoestadodamemória.Erealmentelembrarque,noJava"umavariávelnuncacarregaumobjeto,esimumareferênciaparaele"facilitamuito.

AlémdoBancoqueestamoscriando,vamosvercomoficariamcertasclassesrelacionadasauma

fábrica de carros. Vamos criar uma classe Carro , com certos atributos, que descrevem suas

características,ecomcertosmétodos,quedescrevemseucomportamento.

classCarro{Stringcor;Stringmodelo;doublevelocidadeAtual;doublevelocidadeMaxima;

//ligaocarrovoidliga(){System.out.println("Ocarroestáligado");}

//aceleraumacertaquantidadevoidacelera(doublequantidade){doublevelocidadeNova=this.velocidadeAtual+quantidade;this.velocidadeAtual=velocidadeNova;}

//devolveamarchadocarrointpegaMarcha(){if(this.velocidadeAtual<0){return-1;

4.10PARASABERMAIS:UMAFÁBRICADECARROS

4.10PARASABERMAIS:UMAFÁBRICADECARROS 51

Page 62: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}if(this.velocidadeAtual>=0&&this.velocidadeAtual<40){return1;}if(this.velocidadeAtual>=40&&this.velocidadeAtual<80){return2;}return3;}}

VamostestarnossoCarroemumnovoprograma:

classTestaCarro{publicstaticvoidmain(String[]args){CarromeuCarro;meuCarro=newCarro();meuCarro.cor="Verde";meuCarro.modelo="Fusca";meuCarro.velocidadeAtual=0;meuCarro.velocidadeMaxima=80;

//ligaocarromeuCarro.liga();

//aceleraocarromeuCarro.acelera(20);System.out.println(meuCarro.velocidadeAtual);}}

NossocarropodecontertambémumMotor:

classMotor{intpotencia;Stringtipo;}

classCarro{Stringcor;Stringmodelo;doublevelocidadeAtual;doublevelocidadeMaxima;Motormotor;

//..}

Podemos, criar diversos Carros e mexer com seus atributos e métodos, assim como fizemos noexemplodoBanco.

52 4.10PARASABERMAIS:UMAFÁBRICADECARROS

Page 63: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Quandodeclaramosumaclasse,ummétodoouumatributo,podemosdaronomequequisermos,seguindo uma regra. Por exemplo, o nome de ummétodo não pode começar com um número.Pesquisesobreessasregras.

Como você pode ter reparado, sempre damos nomes às variáveis com letrasminúsculas. É queexistemconvenções de código, dadas pela Oracle, para facilitar a legibilidade do código entreprogramadores. Essa convenção é muito seguida. Leia sobre ela pesquisando por "java codeconventions".

Énecessáriousarapalavrachavethisquandoforacessarumatributo?Paraque,então,utilizá-

la?

Existe um padrão para representar suas classes em diagramas, que é amplamente utilizado,chamadoUML.Pesquisesobreele.

Omodelodacontaaseguirseráutilizadoparaosexercíciosdospróximoscapítulos.

Oobjetivo aqui é criar um sistemapara gerenciar as contas deumBanco.Osexercíciosdessecapítulosãoextremamenteimportantes.

1. Modele uma conta. A ideia aqui é apenas modelar, isto é, só identifique que informações sãoimportantes.DesenhenopapeltudooqueumaContatemetudooqueelafaz.Eladeveteronome

dotitular(String),onúmero (int), a agência (String), o saldo (double) e umadata de

abertura(String).Alémdisso, eladeve fazer as seguintes ações: saca,para retirarumvalordo

saldo;deposita,paraadicionarumvaloraosaldo;calculaRendimento,paradevolverorendimento

VocêpodetambémfazerocursodatadessaapostilanaCaelum

4.11UMPOUCOMAIS...

4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS

4.11UMPOUCOMAIS... 53

Page 64: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

mensaldessaconta.

2. Transforme o modelo acima em uma classe Java. Teste-a, usando uma outra classe que tenha omain.VocêdevecriaraclassedacontacomonomeConta,maspodenomear comoquiser a

classedetestes,contudo,eladevepossuirométodomain.

AclasseContadeveconterpelomenososseguintesmétodos:

sacaquerecebeumvalorcomoparâmetroeretiraessevalordosaldodaconta

depositaquerecebeumvalorcomoparâmetroeadicionaessevaloraosaldodaconta

calculaRendimentoquenãorecebeparâmetroalgumedevolveovalordosaldomultiplicado

por0.1

Umesboçodaclasse:

classConta{

doublesaldo;//seusoutrosatributosemétodos

voidsaca(doublevalor){//oquefazeraquidentro?}

voiddeposita(doublevalor){//oquefazeraquidentro?}

doublecalculaRendimento(){//oquefazeraquidentro?}}

Você pode (e deve) compilar seu arquivo java sem que você ainda tenha terminado sua classeConta.Issoevitaráquevocêrecebadezenasdeerrosdecompilaçãodeumavezsó.Crieaclasse

Conta,coloqueseusatributose,antesdecolocarqualquermétodo,compileoarquivojava.O

arquivoConta.classserágerado,masnãopodemos"executá-lo"jáqueessaclassenãotemum

main.Dequalquerforma,avantageméqueassimverificamosquenossaclasseContajáestá

tomandoformaeestáescritaemsintaxecorreta.

Esseéumprocessoincremental.Procuredesenvolverassimseusexercícios,paranãodescobrirsónofimdocaminhoquealgoestavamuitoerrado.

Umesboçodaclassequepossuiomain:

classTestaConta{

publicstaticvoidmain(String[]args){Contac1=newConta();

54 4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS

Page 65: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

c1.titular="Hugo";c1.numero=123;c1.agencia="45678-9";c1.saldo=50.0;c1.dataDeAbertura="04/06/2015";

c1.deposita(100.0);System.out.println("saldoatual:"+c1.saldo);System.out.println("rendimentomensal:"+c1.calculaRendimento());}}

Incremente essa classe. Faça outros testes, imprima outros atributos e invoque osmétodos quevocêcriouamais.

Lembre-se de seguir a convenção java, isso é importantíssimo. Isto é, preste atenção nasmaiúsculas e minúsculas, seguindo o seguinte exemplo: nomeDeAtributo, nomeDeMetodo,

nomeDeVariavel,NomeDeClasse,etc...

TODASASCLASSESNOMESMOARQUIVO?

Vocêatépodecolocartodasasclassesnomesmoarquivoeapenascompilaressearquivo.Elevaigerarum.classparacadaclassepresentenele.

Porém,porumaquestãodeorganização,éboapráticacriarumarquivo.javaparacada

classe.Emcapítulosposteriores,veremos tambémdeterminadoscasosnosquaisvocê seráobrigadoadeclararcadaclasseemumarquivoseparado.

Essa separação não é importante nesse momento do aprendizado, mas se quiser irpraticandosemterquecompilarclasseporclasse,vocêpodedizerparaojavaccompilar

todososarquivosjavadeumavez:

javac*.java

3. CrieummétodorecuperaDadosParaImpressao(),quenãorecebeparâmetromasdevolveotexto

comtodasasinformaçõesdanossacontaparaefetuarmosaimpressão.

Dessamaneira,vocênãoprecisaficarcopiandoecolandoummontedeSystem.out.println()

paracadamudançaetestequefizercomcadaumdeseusfuncionários,vocêsimplesmentevaifazer:

Contac1=newConta();//brincadeirascomc1....System.out.println(c1.recuperaDadosParaImpressao());

VeremosmaisafrenteométodotoString,queéumasoluçãomuitomaiseleganteparamostrara

representaçãodeumobjetocomoString,alémdenãojogartudoproSystem.out (sósevocê

4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS 55

Page 66: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

desejar).

Oesqueletodométodoficariaassim:

classConta{

//seusoutrosatributosemétodos

StringrecuperaDadosParaImpressao(){Stringdados="Titular:"+this.titular;dados+="\nNúmero:"+this.numero;//imprimiraquiosoutrosatributos...//tambémpodeimprimirthis.calculaRendimento()returndados;}}

4. Construaduascontascomonewecompare-oscomo==.Eseelestiveremosmesmosatributos?

Paraissovocêvaiprecisarcriaroutrareferência:

Contac1=newConta();c1.titular="Danilo";c1.saldo=100;

Contac2=newConta();c2.titular="Danilo";c2.saldo=100;

if(c1==c2){System.out.println("iguais");}else{System.out.println("diferentes");}

5. Crieduasreferênciasparaamesmaconta,compare-oscomo==.Tiresuasconclusões.Paracriarduasreferênciaspramesmaconta:

Contac1=newConta():c1.titular="Hugo";c1.saldo=100;

c2=c1;

Oqueacontececomoifdoexercícioanterior?

6. (opcional)EmvezdeutilizarumaStringpararepresentaradata,crieumaoutraclasse,chamada

Data.Elapossui3camposint,paradia,mêseano.Façacomquesuacontapasseausá-la.(é

parecidocomoúltimoexemplodaexplicação,emqueaConta passoua ter referênciaparaum

Cliente).

classConta{DatadataDeAbertura;//qualéovalordefaultaqui?//seusoutrosatributosemétodos}

classData{

56 4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS

Page 67: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

intdia;intmes;intano;}

ModifiquesuaclasseTestaContaparaquevocêcrieumaDataeatribuaelaaConta:

Contac1=newConta();//...Datadata=newData();//ligação!c1.dataDeAbertura=data;

FaçaodesenhodoestadodamemóriaquandocriarmosumConta.

7. (opcional)ModifiqueseumétodorecuperaDadosParaImpressaoparaqueeledevolvaovalorda

dataDeAberturadaquelaConta:

classConta{

//seusoutrosatributosemétodosDatadataDeAbertura;

StringrecuperaDadosParaImpressao(){Stringdados="\nTitular:"+this.titular;//imprimiraquiosoutrosatributos...

dados+="\nDia:"+this.dataDeAbertura.dia;dados+="\nMês:"+this.dataDeAbertura.mes;dados+="\nAno:"+this.dataDeAbertura.ano;returndados;}}

Teste-o. O que acontece se chamarmos o método recuperaDadosParaImpressao antes de

atribuirmosumadataparaestaConta?

8. (opcional) O que acontece se você tentar acessar um atributo diretamente na classe? Como, porexemplo:

Conta.saldo=1234;

Essecódigofazsentido?Eeste:

Conta.calculaRendimento();

FazsentidoperguntarparaoesquemadaContaseuvaloranual?

9. (opcional-avançado)CrieummétodonaclasseDataquedevolvaovalorformatadodadata,istoé,

devolvaumaStringcom"dia/mes/ano".IssoparaqueométodorecuperaDadosParaImpressaoda

classeContapossaficarassim:

classConta{//atributosemetodos

StringrecuperaDadosParaImpressao(){//imprimeoutrosatributos...

4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS 57

Page 68: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

dados+="\nDatadeabertura:"+this.dataDeAbertura.formatada();returndados;}}

1. Ummétodopodechamarelemesmo.Chamamos issoderecursão.Vocêpode resolver a série deFibonacciusandoummétodoquechamaelemesmo.Oobjetivoévocêcriarumaclasse,quepossaserusadadaseguintemaneira:

Fibonaccifibonacci=newFibonacci();for(inti=1;i<=6;i++){intresultado=fibonacci.calculaFibonacci(i);System.out.println(resultado);}

AquiimprimiráasequênciadeFibonacciatéasextaposição,istoé:1,1,2,3,5,8.

Estemétodo calculaFibonacci não pode ter nenhum laço, só pode chamar elemesmo como

método.Pensenelecomoumafunção,queusaaprópriafunçãoparacalcularoresultado.

2. Porqueomodoacimaéextremamentemaislentoparacalcularasériedoqueomodoiterativo(queseusaumlaço)?

3. Escreva o método recursivo novamente, usando apenas uma linha. Para isso, pesquise sobre ooperadorcondicionalternário.(ternaryoperator)

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Oobjetivodosexercíciosaseguiréfixaroconceitodeclasseseobjetos,métodoseatributos.Dadaaestruturadeumaclasse,bastatraduzi-laparaalinguagemJavaefazerusodeumobjetodamesmaem

4.13DESAFIOS

Seuslivrosdetecnologiaparecemdoséculopassado?

4.14FIXANDOOCONHECIMENTO

58 4.13DESAFIOS

Page 69: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

umprogramasimples.

Sevocêestácomdificuldadeemalgumapartedessecapítulo,aproveiteetreinetudooquevimosnospequenosprogramasabaixo:

Programa1

Classe:PessoaAtributos:nome,idade.Método:voidfazAniversario()

Crieumapessoa,coloqueseunomeeidadeiniciais,façaalgunsaniversários(aumentandoaidade)eimprimaseunomeesuaidade.

Programa2

Classe:PortaAtributos:aberta,cor,dimensaoX,dimensaoY,dimensaoZMétodos:voidabre()voidfecha()voidpinta(Strings)booleanestaAberta()

Crie uma porta, abra e feche amesma, pinte-a de diversas cores, altere suas dimensões e use ométodoestaAbertaparaverificarseelaestáaberta.

Programa3

Classe:CasaAtributos:cor,porta1,porta2,porta3Método:voidpinta(Strings),intquantasPortasEstaoAbertas()

Crie uma casa e pinte-a. Crie três portas e coloque-as na casa; abra e feche as mesmas comodesejar. Utilize o método quantasPortasEstaoAbertas para imprimir o número de portas

abertas.

4.14FIXANDOOCONHECIMENTO 59

Page 70: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO5

"Amarcadohomemimaturoéqueelequermorrernobrementeporumacausa,enquantoamarcadohomemmaduroéquerervivermodestamenteporuma."--J.D.Salinger

Aotérminodessecapítulo,vocêserácapazde:

controlaroacessoaosseusmétodos,atributoseconstrutoresatravésdosmodificadoresprivateepublic;escrevermétodosdeacessoaatributosdotipogettersesetters;escreverconstrutoresparasuasclasses;utilizarvariáveisemétodosestáticos.

Um dos problemasmais simples que temos no nosso sistema de contas é que o método saca

permite sacar mesmo que o saldo seja insuficiente. A seguir você pode lembrar como está a classeConta:

classConta{Stringtitular;intnumero;doublesaldo;

//..

voidsaca(doublevalor){this.saldo=this.saldo-valor;}}

Aclasseaseguirmostracomoépossívelultrapassarolimitedesaqueusandoométodosaca:

classTestaContaEstouro1{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.saldo=1000.0;minhaConta.saca(50000);//saldoésó1000!!}}

MODIFICADORESDEACESSOEATRIBUTOSDECLASSE

5.1CONTROLANDOOACESSO

60 5MODIFICADORESDEACESSOEATRIBUTOSDECLASSE

Page 71: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Podemosincluirumifdentrodonossométodosaca()paraevitarasituaçãoqueresultariaem

umacontaemestadoinconsistente,comseusaldoabaixode0.Fizemosissonocapítulodeorientaçãoaobjetosbásica.

Apesardemelhorarbastante,aindatemosumproblemamaisgrave:ninguémgarantequeousuárioda classe vai sempre utilizar o método para alterar o saldo da conta. O código a seguir faz issodiretamente:

classTestaContaEstouro2{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.saldo=-200;//saldoestáabaixode0}}

Comoevitarisso?Umaideiasimplesseriatestarsenãoestamossacandoumvalormaiorqueosaldotodavezqueformosalterá-lo:

classTestaContaEstouro3{

publicstaticvoidmain(String[]args){//aContaContaminhaConta=newConta();minhaConta.saldo=100;

//queromudarosaldopara-200doublenovoSaldo=-200;

//testaseonovoSaldoéválidoif(novoSaldo<0){//System.out.println("Nãopossomudarparaessesaldo");}else{minhaConta.saldo=novoSaldo;}}}

Essecódigoiriaserepetiraolongodetodanossaaplicaçãoe,pior,alguémpodeesquecerdefazeressacomparaçãoemalgummomento,deixandoacontanasituação inconsistente.AmelhorformaderesolverissoseriaforçarquemusaaclasseContaainvocarométodosacaenãopermitiroacesso

diretoaoatributo.ÉomesmocasodavalidaçãodeCPF.

Parafazer issonoJava,bastadeclararqueosatributosnãopodemseracessadosdeforadaclasseatravésdapalavrachaveprivate:

classConta{privatedoublesaldo;//...}

privateéummodificadordeacesso(tambémchamadodemodificadordevisibilidade).

Marcando um atributo comoprivado, fechamos o acesso aomesmo em relação a todas as outras

5.1CONTROLANDOOACESSO 61

Page 72: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classes,fazendocomqueoseguintecódigonãocompile:

classTestaAcessoDireto{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();//nãocompila!vocênãopodeacessaroatributoprivadodeoutraclasseminhaConta.saldo=1000;}}

TesteAcessoDireto.java:5saldohasprivateaccessinContaminhaConta.saldo=1000;^1error

Na orientação a objetos, é prática quase que obrigatória proteger seus atributos com private.

(discutiremosoutrosmodificadoresdeacessoemoutroscapítulos).

Cadaclasseéresponsávelporcontrolarseusatributos,portantoeladevejulgarseaquelenovovaloréválidoounão!Estavalidaçãonãodevesercontroladaporquemestáusandoaclasseesimporelamesma, centralizando essa responsabilidade e facilitando futurasmudançasno sistema.Muitas outrasvezes nem mesmo queremos que outras classes saibam da existência de determinado atributo,escondendo-oporcompleto,jáqueeledizrespeitoaofuncionamentointernodoobjeto.

Repareque,queminvocaométodosacanãofazamenorideiadequeexisteumaverificaçãopara

ovalordosaque.Paraquemforusaressaclasse,bastasaberoqueométodofazenãocomoexatamenteeleofaz(oqueummétodofazésempremaisimportantedoquecomoelefaz:mudaraimplementaçãoéfácil,jámudaraassinaturadeummétodovaigerarproblemas).

A palavra chave private também pode ser usada para modificar o acesso a um método. Tal

funcionalidade é utilizada em diversos cenários: quando existe um método que serve apenas paraauxiliar a própria classe e quando há código repetido dentro de doismétodos da classe são osmaiscomuns. Sempre devemos expôr o mínimo possível de funcionalidades, para criar um baixoacoplamentoentreasnossasclasses.

Damesmamaneira que temosoprivate, temosomodificadorpublic, que permite a todos

acessaremumdeterminadoatributooumétodo:

classConta{//...publicvoidsaca(doublevalor){//possosacaratésaldoif(valor>this.saldo){System.out.println("Nãopossosacarumvalormaiorqueosaldo!");}else{this.saldo=this.saldo-valor;}}}

62 5.1CONTROLANDOOACESSO

Page 73: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

EQUANDONÃOHÁMODIFICADORDEACESSO?

Atéagora,tínhamosdeclaradovariáveisemétodossemnenhummodificadorcomoprivatee

public . Quando isto acontece, o seu método ou atributo fica num estado de visibilidade

intermediárioentreoprivateeopublic,queveremosmaisprafrente,nocapítulodepacotes.

Émuitocomum,efaztodosentido,queseusatributossejamprivateequasetodosseusmétodos

sejampublic(nãoéumaregra!).Destaforma,todaconversadeumobjetocomoutroéfeitaportroca

demensagens,istoé,acessandoseusmétodos.Algomuitomaiseducadoquemexerdiretamenteemumatributoquenãoéseu!

Melhorainda!OdiaemqueprecisarmosmudarcomoérealizadoumsaquenanossaclasseConta,

adivinhe onde precisaríamosmodificar? Apenas nométodo saca, o que faz pleno sentido. Como

exemplo,imaginecobrarCPMFdecadasaque:bastavocêmodificarali,enenhumoutrocódigo,foraaclasseConta,precisaráserrecompilado.Mais:asclassesqueusamessemétodonemprecisamficar

sabendode talmodificação!Vocêprecisaapenas recompilar aquelaclassee substituir aquele arquivo.class.Ganhamosmuitoemesconderofuncionamentodonossométodonahoradedarmanutençãoe

fazermodificações.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Oquecomeçamosavernessecapítuloéaideiadeencapsular,istoé,escondertodososmembrosdeumaclasse(comovimosacima),alémdeescondercomofuncionamasrotinas(nocasométodos)donossosistema.

Encapsular é fundamental para que seu sistema seja suscetível a mudanças: não precisaremos

Agoraéamelhorhoradeaprenderalgonovo

5.2ENCAPSULAMENTO

5.2ENCAPSULAMENTO 63

Page 74: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

mudarumaregradenegócioemvárioslugares,massimemapenasumúnicolugar, jáqueessaregraestáencapsulada.(vejaocasodométodosaca)

Oconjuntodemétodospúblicosdeumaclasseétambémchamadodeinterfacedaclasse,poisestaéaúnicamaneiraaqualvocêsecomunicacomobjetosdessaclasse.

PROGRAMANDOVOLTADOPARAAINTERFACEENÃOPARAAIMPLEMENTAÇÃO

É sempre bomprogramar pensandona interface da sua classe, como seus usuários a estarãoutilizando,enãosomenteemcomoelavaifuncionar.

A implementação em si, o conteúdo dosmétodos, não tem tanta importância para o usuáriodessaclasse,umavezqueelesóprecisasaberoquecadamétodopretendefazer,enãocomoelefaz,poisistopodemudarcomotempo.

EssafrasevemdolivroDesignPatterns,deEricGammaetal.Umlivrocultuadonomeiodaorientaçãoaobjetos.

Semprequevamosacessarumobjeto,utilizamossuainterface.Existemdiversasanalogiasfáceisnomundoreal:

Quandovocêdirigeumcarro,oqueteimportasãoospedaiseovolante(interface)enãoomotorque você está usando (implementação). É claro que um motor diferente pode te dar melhoresresultados,masoqueelefazéomesmoqueummotormenospotente,adiferençaestáemcomoele faz. Para trocar umcarro a álcool para uma gasolina você não precisa reaprender a dirigir!(trocar a implementaçãodosmétodos não precisamudar a interface, fazendo comque as outrasclassescontinuemusandoelesdamesmamaneira).

64 5.2ENCAPSULAMENTO

Page 75: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Todososcelulares fazemamesmacoisa (interface),elespossuemmaneiras (métodos)dediscar,ligar,desligar,atender,etc.Oquemudaécomoelesfazem(implementação),masreparequeparaefetuar uma ligação pouco importa se o celular é iPhone ou Android, isso fica encapsulado naimplementação(queaquisãooscircuitos).

JátemosconhecimentossuficientespararesolveraqueleproblemadavalidaçãodeCPF:

classCliente{privateStringnome;privateStringendereco;privateStringcpf;privateintidade;

publicvoidmudaCPF(Stringcpf){validaCPF(cpf);this.cpf=cpf;}

privatevoidvalidaCPF(Stringcpf){//sériederegrasaqui,falhacasonãosejaválido}

//..}

SealguémtentarcriarumClienteenãousaromudaCPFparaalterarumcpfdiretamente,vai

receberumerrodecompilação,jáqueoatributoCPFéprivado.EodiaquevocênãoprecisarverificaroCPFdequemtemmaisde60anos?Seumétodoficaoseguinte:

publicvoidmudaCPF(Stringcpf){if(this.idade<=60){validaCPF(cpf);}this.cpf=cpf;}

OcontrolesobreoCPFestácentralizado:ninguémconsegueacessá-losempassarporaí,aclasse

Clienteéaúnicaresponsávelpelosseusprópriosatributos!

Omodificadorprivate fazcomqueninguémconsigamodificar,nemmesmoler,oatributoem

questão.Comisso,temosumproblema:comofazerparamostrarosaldodeumaConta,jáquenem

mesmopodemosacessá-loparaleitura?

Precisamosentãoarranjarumamaneiradefazeresseacesso.Semprequeprecisamosarrumarumamaneiradefazeralgumacoisacomumobjeto,utilizamosdemétodos!Vamosentãocriarummétodo,digamospegaSaldo,pararealizaressasimplestarefa:

classConta{

5.3GETTERSESETTERS

5.3GETTERSESETTERS 65

Page 76: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

privatedoublesaldo;

//outrosatributosomitidos

publicdoublepegaSaldo(){returnthis.saldo;}

//deposita()esaca()omitidos}

Paraacessarmososaldodeumaconta,podemosfazer:

classTestaAcessoComPegaSaldo{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.deposita(1000);System.out.println("Saldo:"+minhaConta.pegaSaldo());}}

Parapermitiroacessoaosatributos(jáqueelessãoprivate)deumamaneiracontrolada,aprática

maiscomumécriardoismétodos,umqueretornaovaloreoutroquemudaovalor.

Aconvençãoparaessesmétodosédecolocarapalavragetousetantesdonomedoatributo.

Porexemplo,anossacontacomsaldo,limiteetitularficaassim,nocasodagentedesejardar

acessoaleituraeescritaatodososatributos:

classConta{

privateStringtitular;privatedoublesaldo;

publicdoublegetSaldo(){returnthis.saldo;}

publicvoidsetSaldo(doublesaldo){this.saldo=saldo;}

publicStringgetTitular(){returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;}}

É uma má prática criar uma classe e, logo em seguida, criar getters e setters para todos seusatributos.Vocêsódevecriarumgetterousettersetiverarealnecessidade.ReparequenesseexemplosetSaldonãodeveriatersidocriado,jáquequeremosquetodosusemdeposita()esaca().

Outrodetalheimportante,ummétodogetXnãonecessariamenteretornaovalordeumatributoque

chama X do objeto em questão. Isso é interessante para o encapsulamento. Imagine a situação:

66 5.3GETTERSESETTERS

Page 77: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

queremosqueobancosempremostrecomosaldo ovalordo limite somadoao saldo (umaprática

comumdosbancosquecostuma iludir seus clientes).Poderíamos sempre chamarc.getLimite()+

c.getSaldo(), mas isso poderia gerar uma situação de "replace all" quando precisássemos mudarcomoo saldo émostrado.Podemos encapsular isso emummétodo e, porquenão, dentrodoprópriogetSaldo?Repare:

classConta{

privateStringtitular;privatedoublesaldo;privatedoublelimite;//adicionandoumlimiteaconta

publicdoublegetSaldo(){returnthis.saldo+this.limite;}

//deposita()saca()etransfere()omitidos

publicStringgetTitular(){returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;}}

OcódigoacimanempossibilitaachamadadométodogetLimite(),elenãoexiste.Enemdeve

existir enquanto não houver essa necessidade.OmétodogetSaldo() não devolve simplesmente o

saldo...esimoquequeremosquesejamostradocomosefosseosaldo.Utilizargettersesettersnão

sóajudavocêaprotegerseusatributos,comotambémpossibilita terdemudaralgoemumsólugar...chamamosissodeencapsulamento,poisescondeamaneiracomoosobjetosguardamseusdados.Éumapráticamuitoimportante.

Nossaclasseestátotalmentepronta?Istoé,existeachancedelaficarcomsaldomenorque0?Podeparecerquenão,mas,esedepositarmosumvalornegativonaconta?Ficaríamoscommenosdinheiroqueopermitido, jáquenãoesperávamospor isso.Paranosprotegerdissobastamudarmosométododeposita()paraqueeleverifiqueseovalorénecessariamentepositivo.

Depois disso precisaríamos mudar mais algum outro código? A resposta é não, graças aoencapsulamentodosnossosdados.

5.3GETTERSESETTERS 67

Page 78: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CUIDADOCOMOSGETTERSESETTERS!

Comojádito,nãodevemoscriargettersesetterssemummotivoexplicito.NoblogdaCaelumháumartigoqueilustrabemessescasos:

http://blog.caelum.com.br/2006/09/14/nao-aprender-oo-getters-e-setters/

Quandousamosapalavrachavenew,estamosconstruindoumobjeto.Semprequandoonew é

chamado, ele executa o construtor da classe. O construtor da classe é um bloco declarado com omesmonomequeaclasse:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(){System.out.println("Construindoumaconta.");}

//..}

Então,quandofizermos:

Contac=newConta();

Amensagem"construindoumaconta"aparecerá.Écomoumarotinadeinicializaçãoqueéchamadasemprequeumnovoobjetoécriado.Umconstrutorpodeparecer,masnãoéummétodo.

OCONSTRUTORDEFAULT

Atéagora,asnossasclassesnãopossuíamnenhumconstrutor.Entãocomoéqueerapossíveldarnew,setodonewchamaumconstrutorobrigatoriamente?

Quando você não declara nenhum construtor na sua classe, o Java cria um para você. Esseconstrutoréoconstrutordefault,elenãorecebenenhumargumentoeocorpodeleévazio.

Apartirdomomentoquevocêdeclaraumconstrutor,oconstrutordefaultnãoémaisfornecido.

O interessante é queumconstrutor pode receber umargumento, podendo assim inicializar algum

5.4CONSTRUTORES

68 5.4CONSTRUTORES

Page 79: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

tipodeinformação:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(Stringtitular){this.titular=titular;}

//..}

Esse construtor recebe o titular da conta. Assim, quando criarmos uma conta, ela já terá umdeterminadotitular.

Stringcarlos="Carlos";Contac=newConta(carlos);System.out.println(c.titular);

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Tudoestavafuncionandoatéagora.Paraqueutilizamosumconstrutor?

Aideiaébemsimples.Setodacontaprecisadeumtitular,comoobrigartodososobjetosqueforemcriadosaterumvalordessetipo?BastacriarumúnicoconstrutorquerecebeessaString!

O construtor se resume a isso! Dar possibilidades ou obrigar o usuário de uma classe a passarargumentosparaoobjetoduranteoprocessodecriaçãodomesmo.

Porexemplo,nãopodemosabrirumarquivopara leiturasemdizerqualéonomedoarquivoquedesejamos ler! Portanto, nada mais natural que passar uma String representando o nome de um

arquivonahoradecriarumobjetodotipodeleituradearquivo,equeissosejaobrigatório.

EditoraCasadoCódigocomlivrosdeumaformadiferente

5.5ANECESSIDADEDEUMCONSTRUTOR

5.5ANECESSIDADEDEUMCONSTRUTOR 69

Page 80: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Vocêpodetermaisdeumconstrutornasuaclassee,nomomentodonew,oconstrutorapropriado

seráescolhido.

CONSTRUTOR:UMMÉTODOESPECIAL?

Umconstrutornão é ummétodo.Algumas pessoas o chamam de ummétodo especial,masdefinitivamentenãoé,jáquenãopossuiretornoesóéchamadoduranteaconstruçãodoobjeto.

CHAMANDOOUTROCONSTRUTOR

Um construtor só pode rodar durante a construção do objeto, isto é, você nunca conseguiráchamaroconstrutoremumobjetojáconstruído.Porém,duranteaconstruçãodeumobjeto,vocêpodefazercomqueumconstrutorchameoutro,paranãoterdeficarcopiandoecolando:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(Stringtitular){//fazmaisumasériedeinicializaçõeseconfiguraçõesthis.titular=titular;}

Conta(intnumero,Stringtitular){this(titular);//chamaoconstrutorquefoideclaradoacimathis.numero=numero;}

//..}

Existeumoutromotivo,ooutroladodosconstrutores:facilidade.Àsvezes,criamosumconstrutorquerecebediversosargumentosparanãoobrigarousuáriodeumaclasseachamardiversosmétodosdotipo'set'.

NonossoexemplodoCPF,podemosforçarqueaclasseClienterecebanomínimooCPF,dessa

maneiraumClientejáseráconstruídoecomumCPFválido.

70 5.5ANECESSIDADEDEUMCONSTRUTOR

Page 81: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

JAVABEAN

Quando criamos uma classe com todos os atributos privados, seus getters e setters e umconstrutorvazio(padrão),naverdadeestamoscriandoumJavaBean(masnãoconfundacomEJB,queéEnterpriseJavaBeans).

Nossobancotambémquercontrolaraquantidadedecontasexistentesnosistema.Comopoderíamosfazeristo?Aideiamaissimples:

Contac=newConta();totalDeContas=totalDeContas+1;

Aqui, voltamos em um problema parecido com o da validação de CPF. Estamos espalhando umcódigo por toda aplicação, e quem garante que vamos conseguir lembrar de incrementar a variáveltotalDeContastodavez?

Tentamosentão,passarparaaseguinteproposta:

classConta{privateinttotalDeContas;//...

Conta(){this.totalDeContas=this.totalDeContas+1;}}

Quandocriarmosduascontas,qualseráovalordototalDeContasdecadaumadelas?Vaiser1.

Poiscadaumatemessavariável.Oatributoédecadaobjeto.

Seria interessante então, que essa variável fosseúnica, compartilhada por todos os objetos dessaclasse.Dessamaneira,quandomudasseatravésdeumobjeto,ooutroenxergariaomesmovalor.Parafazerissoemjava,declaramosavariávelcomostatic.

privatestaticinttotalDeContas;

Quandodeclaramosumatributocomostatic,elepassaanãosermaisumatributodecadaobjeto,

esimumatributodaclasse,a informaçãoficaguardadapelaclasse,nãoémaisindividualparacadaobjeto.

Paraacessarmosumatributoestático,nãousamosapalavrachavethis,massimonomedaclasse:

classConta{privatestaticinttotalDeContas;//...

5.6ATRIBUTOSDECLASSE

5.6ATRIBUTOSDECLASSE 71

Page 82: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Conta(){Conta.totalDeContas=Conta.totalDeContas+1;}}

Já que o atributo é privado, como podemos acessar essa informação a partir de outra classe?Precisamosdeumgetterparaele!

classConta{privatestaticinttotalDeContas;//...

Conta(){Conta.totalDeContas=Conta.totalDeContas+1;}

publicintgetTotalDeContas(){returnConta.totalDeContas;}}

Comofazemosentãoparasaberquantascontasforamcriadas?

Contac=newConta();inttotal=c.getTotalDeContas();

Precisamoscriarumacontaantesdechamarométodo!Issonãoélegal,poisgostaríamosdesaberquantascontasexistemsemprecisarteracessoaumobjetoconta.Aideiaaquiéamesma,transformaressemétodoquetodoobjetocontatememummétododetodaaclasse.Usamosapalavrastaticde

novo,mudandoométodoanterior.

publicstaticintgetTotalDeContas(){returnConta.totalDeContas;}

Paraacessaressenovométodo:

inttotal=Conta.getTotalDeContas();

ReparequeestamoschamandoummétodonãocomumareferênciaparaumaConta,esimusando

onomedaclasse.

MÉTODOSEATRIBUTOSESTÁTICOS

Métodoseatributosestáticossópodemacessaroutrosmétodoseatributosestáticosdamesmaclasse,oquefaztodosentidojáquedentrodeummétodoestáticonãotemosacessoàreferênciathis,poisummétodoestáticoéchamadoatravésdaclasse,enãodeumobjeto.

Ostaticrealmentetrazum"cheiro"procedural,porémemmuitasvezesénecessário.

72 5.6ATRIBUTOSDECLASSE

Page 83: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Emalgumasempresas,oUMLéamplamenteutilizado.Àsvezes,oprogramadorrecebeoUMLjápronto, completo, e só deve preencher a implementação, devendo seguir à risca oUML.O quevocêachadessaprática?Quaisasvantagensedesvantagens.

Se uma classe só tem atributos e métodos estáticos, que conclusões podemos tirar? O que lhepareceummétodoestáticoemcasoscomoesses?

Nocasodeatributosbooleanos,pode-seusarnolugardogetosufixois.Dessamaneira,caso

tivéssemosumatributobooleanoligado,emvezdegetLigadopoderíamosterisLigado.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. Adicioneomodificadordevisibilidade(private, senecessário)paracadaatributo emétododa

classeConta.TentecriarumaContanomainemodificaroulerumdeseusatributosprivados.

Oqueacontece?

2. CrieapenasosgettersesettersnecessáriosdasuaclasseConta.Pensesempreseéprecisocriar

cadaumdeles.Porexemplo:

classConta{privateStringtitular;

//...

publicStringgetTitular(){returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;

5.7UMPOUCOMAIS...

JáconheceoscursosonlineAlura?

5.8EXERCÍCIOS:ENCAPSULAMENTO,CONSTRUTORESESTATIC

5.7UMPOUCOMAIS... 73

Page 84: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}}

Nãocopieecole!Aproveiteparapraticarsintaxe.LogopassaremosausaroEclipseeaísimteremosprocedimentosmaissimplesparaestetipodetarefa.

ReparequeométodocalculaRendimentoparecetambémumgetter.Aliás,seriacomumalguém

nomeá-lodegetRendimento.Gettersnãoprecisamapenasretornaratributos.Elespodemtrabalhar

comessesdados.

3. ModifiquesuasclassesqueacessamemodificamatributosdeumaContaparautilizarosgetterse

settersrecémcriados.

Porexemplo,ondevocêencontra:

c.titular="Batman";System.out.println(c.titular);

passapara:

c.setTitular("Batman");System.out.println(c.getTitular());

4. FaçacomquesuaclasseContapossareceber,opcionalmente,onomedotitulardaContadurante

acriaçãodoobjeto.Utilizeconstrutoresparaobteresseresultado.

Dica:utilizeumconstrutorsemargumentos também,paraocasodeapessoanãoquererpassarotitulardaConta.

Seriaalgocomo:

classConta{publicConta(){//construtorsemargumentos}

publicConta(Stringtitular){//construtorquerecebeotitular}}

Porquevocêprecisadoconstrutorsemargumentosparaqueapassagemdonomesejaopcional?

5. (opcional)AdicioneumatributonaclasseContade tipointquese chama identificador.Esse

identificador deve ter um valor único para cada instância do tipo Conta. A primeira Conta

instanciada tem identificador 1, a segunda 2, e assim por diante. Você deve utilizar os recursosaprendidosaquipararesolveresseproblema.

Crieumgetterparaoidentificador.Devemosterumsetter?

6. (opcional)Comogarantirquedatascomo31/2/2012nãosejamaceitaspelasuaclasseData?

74 5.8EXERCÍCIOS:ENCAPSULAMENTO,CONSTRUTORESESTATIC

Page 85: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

7. (opcional) Suponha que temos a classe PessoaFisica que tem um CPF como atributo. Como

garantir que pessoa física alguma tenhaCPF invalido, nem seja criada PessoaFisica sem cpf

inicial?(Suponhaquejáexisteumalgoritmodevalidaçãodecpf:bastapassarocpfporummétodovalida(Stringx)...)

1. Porqueessecódigonãocompila?

classTeste{intx=37;publicstaticvoidmain(String[]args){System.out.println(x);}}

2. ImaginequetenhaumaclasseFabricaDeCarroequerogarantirquesóexisteumobjetodessetipo

emtodaamemória.NãoexisteumapalavrachaveespecialparaistoemJava,entãoteremosdefazernossa classe de talmaneira que ela respeite essa nossa necessidade. Como fazer isso? (pesquise:singletondesignpattern)

5.9DESAFIOS

5.9DESAFIOS 75

Page 86: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO6

"Dá-seimportânciaaosantepassadosquandojánãotemosnenhum."--FrançoisChateaubriand

Neste capítulo, você será apresentado aoAmbiente deDesenvolvimentoEclipse e suas principaisfuncionalidades.

OEclipse(http://www.eclipse.org)éumaIDE(integrateddevelopmentenvironment).DiferentedeumaRAD,ondeoobjetivoédesenvolveromaisrápidopossívelatravésdoarrastar-e-soltardomouse,onde montanhas de código são gerados em background, uma IDE te auxilia no desenvolvimento,evitandoseintrometerefazermuitamágica.

O Eclipse é a IDE líder de mercado. Formada por um consórcio liderado pela IBM, possui seucódigolivre.

Veremos aqui os principais recursos do Eclipse. Você perceberá que ele evita ao máximo teatrapalhareapenasgeratrechosdecódigosóbvios,sempreaoseucomando.Existemtambémcentenasde plugins gratuitos para gerar diagramasUML, suporte a servidores de aplicação, visualizadores debancodedadosemuitosoutros.

BaixeoEclipsedo siteoficialhttp://www.eclipse.org.Apesarde ser escrito emJava, abibliotecagráficausadanoEclipse,chamadaSWT,usacomponentesnativosdosistemaoperacional.Porissovocêdevebaixaraversãocorrespondenteaoseusistemaoperacional.

Descompacteoarquivoepronto,bastarodaroexecutável.

OUTRASIDES

UmaoutraIDEopensourcefamosaéoNetbeans,daOracle.(http://www.netbeans.org).

Alémdessas,Oracle,Borland e a própria IBMpossuem IDEs comerciais e algumas versõesmaisrestritasdeusolivre.

AempresaJetBrainsdesenvolveoIntelliJIDEA,umaIDEpagaquetemganhomuitosadeptos.

ECLIPSEIDE

6.1OECLIPSE

76 6ECLIPSEIDE

Page 87: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

CliquenoíconedoEclipsenoseuDesktop.

Aprimeiraperguntaqueeletefazéqueworkspacevocêvaiusar.Workspacedefineodiretórioemqueassuasconfiguraçõespessoaiseseusprojetosserãogravados.

Vocêpodedeixarodiretóriopré-definido.

Logoemseguida,umateladeWelcomeseráaberta,ondevocê temdiversos linkspara tutoriaiseajuda.CliqueemWorkbench.

VocêpodetambémfazerocursodatadessaapostilanaCaelum

6.2APRESENTANDOOECLIPSE

6.2APRESENTANDOOECLIPSE 77

Page 88: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Feche a tela deWelcome e você verá a tela abaixo. Nesta tela, destacamos as Views (em linhacontínua)easPerspectives(emlinhapontilhada)doEclipse.

6.3VIEWSEPERSPECTIVE

78 6.3VIEWSEPERSPECTIVE

Page 89: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Mude para a perspectiva Resource, clicando no ícone ao lado da perspectiva Java, selecionandoOtheredepoisResource.Nestemomento,trabalharemoscomestaperspectiva,antesdadeJava,poiselapossuiumconjuntodeViewsmaissimples.

AViewNavigatormostraaestruturadediretórioassimcomoestánosistemadearquivos.AViewOutlinemostraumresumodasclasses,interfaceseenumeraçõesdeclaradasnoarquivojavaatualmenteeditado(servetambémparaoutrostiposdearquivos).

No menuWindow -> Show View -> Other, você pode ver as dezenas de Views que já vem

6.3VIEWSEPERSPECTIVE 79

Page 90: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

embutidasnoEclipse.Acostume-seasempreprocurarnovasViews,elaspodemteajudaremdiversastarefas.

VáemFile->New->Project.SelecionaJavaProjectecliqueemNext.

6.4CRIANDOUMPROJETONOVO

80 6.4CRIANDOUMPROJETONOVO

Page 91: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Crieumprojetochamadofj11-contas.

VocêpodechegarnessamesmatelaclicandocomobotãodadiretanoespaçodaViewNavigatoreseguindoomesmomenu.Nestatela,configureseuprojetocomonatelaabaixo:

Isto é, marque "create separate source and output folders", desta maneira seus arquivos java earquivosclassestarãoemdiretóriosdiferentes,paravocêtrabalhardeumamaneiramaisorganizada.

6.4CRIANDOUMPROJETONOVO 81

Page 92: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Clique em Finish. O Eclipse pedirá para trocar a perspectiva para Java; escolha "No" parapermaneceremResource.NaViewNavigator,vocêveráonovoprojetoesuaspastasearquivos:

VamosiniciarnossoprojetocriandoaclasseConta.Paraisso,váemFile->New->Other->Class.CliqueemNextecrieaclasseseguindoatelaabaixo:

CliqueemFinish.OEclipsepossuidiversoswizards,masusaremosomínimodeles.Ointeressanteé usar o codeassist e quick fixes que a ferramenta possui e veremos em seguida. Não se atente àsmilharesdeopçõesdecadawizard,apartemaisinteressantedoEclipsenãoéessa.

EscrevaométododepositacomoabaixoenotequeoEclipsereclamadeerroemthis.saldo

poisesteatributonãoexiste.

82 6.4CRIANDOUMPROJETONOVO

Page 93: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

VamosusarorecursodoEclipsedequickfix.ColoqueocursoremcimadoerroeaperteCtrl+1.

O Eclipse sugerirá possíveis formas de consertar o erro; uma delas é, justamente, criar o camposaldonaclasseConta,queénossoobjetivo.Cliquenestaopção.

Este recurso de quick fixes, acessível pelo Ctrl+1, é uma das grandes facilidades do Eclipse e éextremamentepoderoso.Atravésdele épossível corrigirboapartedoserrosnahoradeprogramare,comofizemos,economizaradigitaçãodecertoscódigosrepetitivos.Nonossoexemplo,nãoprecisamoscriarocampoantes;oEclipsefazissoparanós.Eleatéacertaatipagem,jáqueestamossomandoeleaumdouble.Oprivateécolocadopormotivosquejáestudamos.

VáaomenuFile->Saveparagravar.Control+Stemomesmoefeito.

6.4CRIANDOUMPROJETONOVO 83

Page 94: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

6.5CRIANDOOMAIN

84 6.5CRIANDOOMAIN

Page 95: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CrieumanovaclassechamadaPrincipal.Vamos colocar ummétodomain para testar nossa

Conta.Emvezdedigitartodoométodomain,vamosusarocodeassistdoEclipse.EscrevasómaineaperteCtrl+Espaçologoemseguida.

OEclipsesugeriráacriaçãodométodomaincompleto;selecioneestaopção.Ocontrol+espaçoé

chamadodecodeassist.Assimcomoosquick fixessãodeextrema importância.Experimenteusarocodeassistemdiversoslugares.

Dentrodométodomain,comeceadigitaroseguintecódigo:

Contaconta=newConta();conta.deposita(100.0);

Observe que, na hora de invocar o método sobre o objeto conta, o Eclipse sugere os métodospossíveis.Esterecursoébastanteútil,principalmentequandoestivermosprogramandocomclassesquenãosãoasnossas,comodaAPIdoJava.OEclipseacionaesterecursoquandovocêdigitaopontologoapósumobjeto(evocêpodeusaroCtrl+Espaçoparaacioná-lo).

Vamos imprimir o saldo com System.out.println. Mas, mesmo nesse código, o Eclipse nos

ajuda.EscrevasysoeaperteCtrl+EspaçoqueoEclipseescreveráSystem.out.println()paravocê.

Paraimprimir,chameoconta.getSaldo():

System.out.println(conta.getSaldo());

NotequeoEclipseacusaráerroemgetSaldo()porqueestemétodonãoexistenaclasseConta.

VamosusarCtrl+1emcimadoerroparacorrigiroproblema:

6.5CRIANDOOMAIN 85

Page 96: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

OEclipsesugerecriarummétodogetSaldo()naclasseConta.Selecioneestaopçãoeométodo

seráinseridoautomaticamente.

publicObjectgetSaldo(){//TODOAuto-generatedmethodstubreturnnull;}

Elegeraummétodonãoexatamentecomoqueríamos,poisnemsemprehácomooEclipse terdeantemãoinformaçõessuficientesparaqueeleacerteaassinaturadoseumétodo.ModifiqueométodogetSaldocomosegue:

publicdoublegetSaldo(){returnthis.saldo;}

EssespequenosrecursosdoEclipsesãodeextremautilidade.Dessamaneira,vocêpodeprogramarsem se preocupar commétodos que ainda não existem, já que a qualquermomento ele pode gerar oesqueleto(apartedaassinaturadométodo).

Vamosrodarométodomaindessanossaclasse.NoEclipse,cliquecomobotãodireitonoarquivo

Principal.javaeváemRunas...JavaApplication.

6.6EXECUTANDOOMAIN

86 6.6EXECUTANDOOMAIN

Page 97: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

OEclipseabriráumaViewchamadaConsoleondeseráapresentadaasaídadoseuprograma:

Quando você precisar rodar de novo, basta clicar no ícone verde de play na toolbar, que roda oprogramaanterior.Aoladodesseíconetemumasetinhaondesãolistadosos10últimosexecutados.

OEclipse possuimuitos atalhos úteis para o programador. Semdúvida os 3mais importantes deconheceredepraticarsão:

Ctrl+1Acionaoquickfixescomsugestõesparacorreçãodeerros.

Ctrl+EspaçoCompletacódigos

Ctrl+3Acionamododedescobertademenu.ExperimentedigitarCtrl+3edepoisdigitarggaseenter.OuentãodeCtrl+3edigitenewclass.

Você pode ler muito mais detalhes sobre esses atalhos no blog da Caelum:http://blog.caelum.com.br/as-tres-principais-teclas-de-atalho-do-eclipse/

6.7PEQUENOSTRUQUES

6.7PEQUENOSTRUQUES 87

Page 98: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Existemdezenasdeoutros.DentreosmaisutilizadospelosdesenvolvedoresdaCaelum,escolhemososseguintesparacomentar:

Ctrl+F11rodaaúltimaclassequevocêrodou.Éomesmoqueclicarnoíconeverdequepareceumbotãodeplaynabarradeferramentas.

Ctrl + PgUp eCtrl + PgDown Navega nas abas abertas. Útil quando estiver editando váriosarquivosaomesmotempo.

Ctrl+Shift+FFormataocódigosegundoasconvençõesdoJava

Ctrl+MExpande aViewatual para a tela toda (mesmoefeito dedar dois cliquesno títulodaView)

Ctrl+Shift+LExibetodososatalhospossíveis.

Ctrl+OExibeumoutlinepararápidanavegação

Alt+Shift+XedepoisJRodaomaindaclasseatual.Péssimoparapressionar!Maisfácilvocê

digitarControl+3edepoisdigitarRun!.AbusedesdejádoControl+3

Veremosmaisnodecorrerdocurso,emespecialquandovirmospacotes.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Crieoprojetofj11-contas.Vocêpodeusaroatalhocontrol+nouentãoirnomenuFile->New

->Project...->JavaProject.

2. Dentro do projeto fj11-contas , crie a classe Conta . Uma conta deve ter as seguintes

informações:saldo(double),titular(String),numero (int)eagencia (String).Na classe

Conta, crie osmétodosdeposita esaca comonos capítulos anteriores.Crie tambémuma

Agoraéamelhorhoradeaprenderalgonovo

6.8EXERCÍCIOS:ECLIPSE

88 6.8EXERCÍCIOS:ECLIPSE

Page 99: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classeTesteDaContacomomain e instancieumaconta.Destavez, tenteabusardocontrol+

espaçoecontrol+1.

Porexemplo:

publ<ctrlespaco>v<ctrlespaco>deposita(do<ctrlespaço>valor){

Reparequeatémesmonomesdevariáveis,elecriaparavocê!Acompanheasdicasdoinstrutor.

Muitasvezes,aocriarmosumobjeto,nemmesmodeclaramosavariável:

newConta();

Vánessalinhaedêcontrol+1.Elevaisugeriredeclararáavariávelpravocê.

3. Imaginequequeremoscriarumsetterdo titularparaaclasseConta.Dentroda classeConta,

digite:

setTit<ctrl+espaco>

OutraformaparacriarosgetterseossettersparaosatributosdaclasseConta,éutilizaroatalho

control+3enacaixadeseleçãodigiteggas,iniciaisdeGenerateGettersandSetters!

OBS:Nãocrieumsetterparaoatributosaldo!

4. Váparaaclasseque temomain e segureoCONTROLapertadoenquantovocêpassaomouse

sobreoseucódigo.Reparequetudovirouhyperlink.CliqueemummétodoquevocêestáinvocandonaclasseConta.

Vocêpodeconseguiromesmoefeito,deabriroarquivonoqualométodo foideclarado, deumamaneira ainda mais prática: sem usar o mouse, quando o cursor estiver sobre o que você queranalisar,simplesmentecliqueF3.

5. Dêumcliquedadireitaemumarquivononavigator.EscolhaCompareWith->LocalHistory.Oqueéestatela?

6.8EXERCÍCIOS:ECLIPSE 89

Page 100: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

6. UseoControl+Shift+Fparaformataroseucódigo.Dessamaneira,elevaiarrumarabagunçadeespaçamentoeentersdoseucódigo.

7. (opcional)Oquesãoosarquivos.projecte.classpath?Leiaoconteúdodeles.

8. (opcional)Cliquedadireitanoprojeto,propriedades.ÉumadastelasmaisimportantesdoEclipse,onde você pode configurar diversas informações para o seu projeto, como compilador, versões,formatadoreoutros.

90 6.8EXERCÍCIOS:ECLIPSE

Page 101: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ExisteummenunoEclipsechamadoRefactor.Eletemopçõesbastanteinteressantesparaauxiliarnaalteraçãodecódigoparamelhorarorganizaçãoouclareza.Porexemplo,umadesuasfuncionalidadesétornarpossívelmudaronomedeumavariável,métodooumesmoclassedeformaqueumaalteração(emumlugarsódosistema)atualizetodasasoutrasvezesqueusavamonomeantigo.

Usar bons nomes no seu código é um excelente começo para mantê-lo legível e fácil de darmanutenção! Mas o assunto "Refatoração" não para por aí: quebrar métodos grandes em menores,dividirclassesgrandesemalgumaspequenasemaisconcisas,melhoraroencapsulamento...todasessassãoformasderefatoração.EessemenudoEclipsenosajudaafazerváriasdelas.

6.9DISCUSSÃOEMAULA:REFACTORING

6.9DISCUSSÃOEMAULA:REFACTORING 91

Page 102: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO7

"Umadiscussãoprolongadasignificaqueambasaspartesestãoerradas"--Voltaire

Aotérminodessecapítulo,vocêserácapazde:

separarsuasclassesempacotes;preparararquivossimplesparadistribuição.

Nestecapítulo,aconselhamosquevocêpasseausaroEclipse.VocêjátemconhecimentosuficientedoserrosdecompilaçãodojavaceagorapodeaprenderasfacilidadesqueoEclipsetetrazaoajudar

vocênocódigocomoschamadosquickfixesequickassists.

Quando um programador utiliza as classes feitas por outro, surge um problema clássico: comoescreverduasclassescomomesmonome?

Porexemplo:podeserqueaminhaclassedeDatafuncionedeumcertojeito,eaclasseDatade

umcolega,deoutro jeito.PodeserqueaclassedeDatadeumabiblioteca funcione aindadeumaterceiramaneiradiferente.

Comopermitir que tudo isso realmente funcione?Como controlar quemquer usar qual classe deData?

Pensando um pouco mais, notamos a existência de um outro problema e da própria solução: osistema operacional não permite a existência de dois arquivos com o mesmo nome sob o mesmodiretório,portantoprecisamosorganizarnossasclassesemdiretóriosdiferentes.

Osdiretóriosestãodiretamenterelacionadosaoschamadospacotesecostumamagruparclassesdefuncionalidadessimilaresourelacionadas.

Por exemplo, no pacote java.util temos as classes Date , SimpleDateFormat e

GregorianCalendar;todaselastrabalhamcomdatasdeformasdiferentes.

PACOTES-ORGANIZANDOSUASCLASSESEBIBLIOTECAS

7.1ORGANIZAÇÃO

92 7PACOTES-ORGANIZANDOSUASCLASSESEBIBLIOTECAS

Page 103: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

SeaclasseClienteestánopacotecontas,eladeveráestarnodiretóriocomomesmonome:

contas. Se ela se localiza no pacote br.com.caelum.contas , significa que está no diretório

br/com/caelum/contas.

AclasseCliente,queselocalizanesseúltimodiretóriomencionado,deveserescritadaseguinte

forma:

packagebr.com.caelum.contas;

classCliente{//...}

Ficafácilnotarqueapalavrachavepackageindicaqualopacote/diretóriocontémestaclasse.

Umpacotepodeconternenhumoumaissubpacotese/ouclassesdentrodele.

EditoraCasadoCódigocomlivrosdeumaformadiferente

7.2DIRETÓRIOS

7.2DIRETÓRIOS 93

Page 104: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

PADRÃODANOMENCLATURADOSPACOTES

Opadrãodasunparadarnomeaospacotesérelativoaonomedaempresaquedesenvolveuaclasse:

br.com.nomedaempresa.nomedoprojeto.subpacotebr.com.nomedaempresa.nomedoprojeto.subpacote2br.com.nomedaempresa.nomedoprojeto.subpacote2.subpacote3

Ospacotessópossuemletrasminúsculas,nãoimportaquantaspalavrasestejamcontidasnele.Essepadrãoexisteparaevitaraomáximooconflitodepacotesdeempresasdiferentes.

Asclassesdopacotepadrãodebibliotecasnãoseguemessanomenclatura,que foidadaparabibliotecasdeterceiros.

Para usar uma classe do mesmo pacote, basta fazer referência a ela como foi feito até agorasimplesmenteescrevendoopróprionomedaclasse.SequisermosqueaclasseBancofiquedentrodo

pacotebr.com.caelum.contas,eladeveserdeclaradaassim:

packagebr.com.caelum.contas;

classBanco{Stringnome;}

ParaaclasseClienteficarnomesmopacote,seguimosamesmafórmula:

packagebr.com.caelum.contas;

classCliente{Stringnome;Stringendereco;}

AnovidadechegaaotentarutilizaraclasseBanco(ouCliente)emumaoutraclassequeesteja

foradessepacote,porexemplo,nopacotebr.com.caelum.contas.main:

packagebr.com.caelum.contas.main;

classTesteDoBanco{

publicstaticvoidmain(String[]args){br.com.caelum.contas.BancomeuBanco=newbr.com.caelum.contas.Banco();meuBanco.nome="BancodoBrasil";System.out.println(meuBanco.nome);}

}

7.3IMPORT

94 7.3IMPORT

Page 105: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ReparequeprecisamosreferenciaraclasseBancocomtodoonomedopacotenasuafrente.Esseé

oconhecidoFullyQualifiedNamedeumaclasse.Emoutraspalavras,esseéoverdadeironomedeumaclasse,porissoduasclassescomomesmonomeempacotesdiferentesnãoconflitam.

Mesmoassim,aotentarcompilaraclasseanterior,surgeumerroreclamandoqueaclasseBanco

nãoestávisível.

Acontecequeasclassessósãovisíveisparaoutrasnomesmopacotee,parapermitirqueaclasseTesteDoBanco veja e acesse a classe Banco em outro pacote, precisamos alterar essa última e

transformá-laempública:

packagebr.com.caelum.contas;

publicclassBanco{Stringnome;}

Apalavra chavepublic libera o acesso para classes de outros pacotes.Domesmo jeito que o

compilador reclamou que a classe não estava visível, ele reclama que o atributo/variável membrotambém não está. É fácil deduzir como resolver o problema: utilizando novamente o modificadorpublic:

packagebr.com.caelum.contas;

publicclassBanco{publicStringnome;}

Podemos testar nosso exemplo anterior, lembrando que utilizar atributos como público não trazencapsulamentoeestáaquicomoilustração.

VoltandoaocódigodoTesteDoBanco, é necessário escrever todoopacote para identificar qual

classequeremosusar?Oexemploqueusamosficoubemcomplicadodeler:

br.com.caelum.contas.BancomeuBanco=newbr.com.caelum.contas.Banco();

Existe umamaneiramais simples de se referenciar a classeBanco: basta importá-la dopacotebr.com.caelum.contas:

packagebr.com.caelum.contas.main;

//parapodermosreferenciar//aBancodiretamenteimportbr.com.caelum.contas.Banco;

publicclassTesteDoBanco{

publicstaticvoidmain(String[]args){BancomeuBanco=newBanco();meuBanco.nome="BancodoBrasil";}

7.3IMPORT 95

Page 106: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

Issofazcomquenãoprecisemosnosreferenciarutilizandoofullyqualifiedname,podendoutilizarBancodentrodonossocódigoemvezdeescreverolongobr.com.caelum.contas.Banco.

PACKAGE,IMPORT,CLASS

Émuito importantemanter aordem!Primeiro, apareceuma (ounenhuma)vezopackage;

depois,podeaparecerumoumaisimports;e,porúltimo,asdeclaraçõesdeclasses.

IMPORTX.Y.Z.*;

É possível "importar um pacote inteiro" (todas as classes do pacote, exceto os subpacotes)atravésdocoringa*:

importjava.util.*;

Importar todas as classes de umpacote não implica em perda de performance em tempo deexecução,maspode trazerproblemascomclassesdemesmonome!Alémdisso, importardeumemuméconsideradoboaprática,poisfacilitaaleituraparaoutrosprogramadores.UmaIDEcomooEclipsejávaifazerissoporvocê,assimcomoaorganizaçãoemdiretórios.

OsmodificadoresdeacessoexistentesemJavasãoquatro,eatéomomentojávimostrês,massóexplicamosdois.

public - Todos podem acessar aquilo que for definido como public . Classes, atributos,

construtoresemétodospodemserpublic.

protected-Aquiloqueéprotectedpodeseracessadoportodasasclassesdomesmopacotee

por todas as classes que o estendam,mesmoque essas não estejamnomesmopacote. Somenteatributos,construtoresemétodospodemserprotected.

padrão(semnenhummodificador) -Senenhummodificador forutilizado, todas as classesdomesmopacotetêmacessoaoatributo,construtor,métodoouclasse.

private - A única classe capaz de acessar os atributos, construtores e métodos privados é a

própriaclasse.Classes,comoconhecemos,nãopodemserprivate,masatributos,construtorese

7.4ACESSOAOSATRIBUTOS,CONSTRUTORESEMÉTODOS

96 7.4ACESSOAOSATRIBUTOS,CONSTRUTORESEMÉTODOS

Page 107: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

métodossim.

CLASSESPÚBLICAS

Paramelhororganizarseucódigo,oJavanãopermitemaisdeumaclassepúblicaporarquivoeoarquivodeveserNomeDaClasse.java.

Umavezqueoutrosprogramadoresirãoutilizaressaclasse,quandoprecisaremolharocódigodamesma,ficamaisfácilencontrá-lasabendoqueelaestánoarquivodemesmonome.

Classesaninhadaspodemserprotectedouprivate,masesseéumtópicoavançadoque

nãoseráestudadonessemomento.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

VocêpodeusaraperspectivaJavadoEclipse.AviewprincipaldenavegaçãoéoPackageExplorer,queagrupaclassespelospacotesemvezdediretórios(vocêpodeusá-laemconjuntocomaNavigator,bastatambémabri-lapeloWindow/ShowView/PackageExplorer).

JáconheceoscursosonlineAlura?

7.5USANDOOECLIPSECOMPACOTES

7.5USANDOOECLIPSECOMPACOTES 97

Page 108: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Antes de movermos nossas classes, declare-as como públicas e coloque-as em seus respectivosarquivos:umarquivoparacadaclasse.

Vocêpodemoverumaclassedepacotearrastando-aparaodestinodesejado.ReparequeoEclipsejádeclarapackageseimportsnecessários:

98 7.5USANDOOECLIPSECOMPACOTES

Page 109: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

NoEclipsenuncaprecisamosdeclararumimport,poiselesemprevaisugeririssoquandousarmos

oCtrl+Espaçononomedeumaclasse.

VocêtambémpodeusaroCtrl+1nocasodadeclaraçãodepacotepossuiralgumerro.

Atenção: utilize os recursos do Eclipse para realizar essas mudanças. Use a view package-

explorer,quevaiauxiliarbastanteamanipulaçãodosarquivosediretórios.Tambémutilizeosquick

fixesquandooEclipsereclamardosdiversosproblemasdecompilaçãoqueaparecerão.Épossívelfazeresse exercício inteiro semmodificar uma linhade códigomanualmente. Aproveite para praticar edescobriroEclipse,eviteusá-loapenascomoumeditordetexto.

Por exemplo, com o Eclipse nunca precisamos nos preocupar com os imports: ao usar o autocomplete,elejájogaoimportláemcima.E,sevocênãofezisso,elesugerecolocaroimport.

1. Selecionandoosrcdoseuprojeto,façactrl+NeescrevaPackageparaoseusistemadeContascomeçar a utilizar pacotes. Na janela de criação de pacotes escreva o nome completo do pacoteseguindo a convençãode códigodaSun, desdeobr, e oEclipse tratará de fazer a separaçãodaspastascorretamente.Cuidado:paraessecurso,osnomesdospacotesprecisamserosseguintes:

br.com.caelum.contas.main:colocaraclassecomométodomainaqui(oTeste)

7.6EXERCÍCIOS:PACOTES

7.6EXERCÍCIOS:PACOTES 99

Page 110: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

br.com.caelum.contas.modelo:colocaraclasseConta

Antesdecorrigirqualquererrodecompilação,primeiromovatodasassuasclasses,semdeixarnenhumanopacotedefault.

2. Sevocêaindanãotiverseparadocadaclasseemumarquivo,essaéahorademudarisso.Coloquecadaclasseemseurespectivoarquivo.java.Façaissoindependentedeelaserpública:éumaboa

prática.

3. Casoocódigonãocompileprontamente, reparequepelomenosalgummétodoquedeclaramosépackage-private quando, na verdade, precisamos que ele seja public. O mesmo vale para as

classes:algumasdelasprecisarãoserpúblicas.

Se houver algumerro de compilação, use o recurso de quick fix doEclipse aqui: elemesmovaisugerirqueomodificadordeacessodeveserpúblico.Paraisso,useoctrl+1emcadaumdoserros,escolhendooquickfixmaisadequadoparaseuproblema.

4. (Opcional)AbraaviewNavigatorparavercomoficouosarquivosnosistemadearquivosdoseu

sistemaoperacional.Paraisso,usectrl+3,comeceadigitarNavigatoreescolhaaopçãodeabriressaview..

100 7.6EXERCÍCIOS:PACOTES

Page 111: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO8

"Perdertempoemaprendercoisasquenãointeressam,priva-nosdedescobrircoisasinteressantes"--CarlosDrummonddeAndrade

Aotérminodessecapítulo,vocêserácapazde:

criaroJARdoseuaplicativo;colocarumJARnobuildpathdoseuprojeto;lerumjavadoc;criarojavadocdoseuaplicativo.

Assimqueumprogramaficapronto,émeiocomplicadoenviardezenasoucentenasdeclassesparacadaclientequequerutilizá-lo.

Ojeitomaissimplesdetrabalharcomumconjuntodeclassesécompactá-losemumarquivosó.OformatodecompactaçãopadrãoéoZIPcomaextensãodoarquivocompactadoJAR.

OARQUIVO.JAR

OarquivojarouJavaARchive,possuiumconjuntodeclasses(earquivosdeconfigurações)compactados, no estilo de um arquivo zip. O arquivo jar pode ser criado com qualquer

compactadorzipdisponívelnomercado,inclusiveoprogramajarquevemjuntocomoJDK.

Paracriarumarquivojardonossoprogramadebanco,bastairaodiretórioondeestãocontidasasclasseseusarocomandoaseguirparacriaroarquivobanco.jarcomtodasasclassesdospacotes

br.com.caelum.utilebr.com.caelum.banco:

jar-cvfbanco.jarbr/com/caelum/util/*.classbr/com/caelum/banco/*.class

Parausaressearquivobanco.jarpararodaroTesteDoBancobastarodarojavacomoarquivo

jarcomoargumento:

FERRAMENTAS:JAREJAVADOC

8.1ARQUIVOS,BIBLIOTECASEVERSÕES

8FERRAMENTAS:JAREJAVADOC 101

Page 112: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

java-classpathbanco.jarbr.com.caelum.contas.main.TesteDoBanco

Paraadicionarmaisarquivos.jar,quepodemserbibliotecas,aoprogramabastarodarojavada

seguintemaneira:

java-classpathbiblioteca1.jar;biblioteca2.jarNomeDaClasse

ValelembrarqueopontoevírgulautilizadosóéválidoemambienteWindows.EmLinux,MaceoutrosUnix,éodoispontos(variadeacordocomosistemaoperacional).

Hátambémumarquivodemanifestoquecontéminformaçõesdoseujarcomo,porexemplo,qualclasseelevairodarquandoojarforchamado.Masnãosepreocupepois,comoEclipse,essearquivoégeradoautomaticamente.

BIBLIOTECAS

Diversas bibliotecas podem ser controladas de acordo com a versão por estarem semprecompactadasemumarquivo.jar.Bastaverificaronomedabiblioteca (porexemplolog4j-

1.2.13.jar)paradescobriraversãodela.

Então é possível rodar dois programas aomesmo tempo, cada umutilizando uma versão dabibliotecaatravésdoparâmetro-classpathdojava.

CRIANDOUM.JARAUTOMATICAMENTE

Existemdiversasferramentasqueservemparaautomatizaroprocessodedeploy,queconsisteemcompilar,gerardocumentação,bibliotecasetc.AsduasmaisfamosassãooANTeoMAVEN,ambossãoprojetosdogrupoApache.

OEclipsepodegerarfacilmenteumjar,porém,seoseubuildécomplexoeprecisaprepararecopiar uma série de recursos, as ferramentas indicadas acima possuem sofisticadasmaneiras derodarumscriptbatch.

102 8.1ARQUIVOS,BIBLIOTECASEVERSÕES

Page 113: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Nesteexemplo,vamosgeraroarquivoJARdonossoprojetoapartirdoEclipse:

CliquecomobotãodireitoemcimadonomedoseuprojetoeselecioneaopçãoExport.

Na tela Export (como mostra a figura abaixo), selecione a opção "JAR file" e aperte o botão"Next".

VocêpodetambémfazerocursodatadessaapostilanaCaelum

8.2GERANDOOJARPELOECLIPSE

8.2GERANDOOJARPELOECLIPSE 103

Page 114: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Naopção"JARfile:",selecioneolocalquevocêdesejasalvaroarquivoJAR.Eaperte"Next".

Napróximatela,simplesmentecliqueemnext,poisnãohánenhumaconfiguraçãoaserfeita.

104 8.2GERANDOOJARPELOECLIPSE

Page 115: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Natelaabaixo,naopção"selecttheclassoftheapplicationentrypoint",vocêdeveescolherqualclasseseráaclassequevairodarautomaticamentequandovocêexecutaroJAR.

Entrenalinhadecomando:java-jarbanco.jar

É comum dar um nome mais significativo aos JARs, incluindo nome da empresa, do projeto eversão,comocaelum-banco-1.0.jar.

ComovamossaberoquecadaclassetemnoJava?Quaissãoseusmétodos,oqueelesfazem?

E, a partir da Internet, você pode acessar através do link:http://download.java.net/jdk8/docs/api/index.html

No site da Oracle, você pode (e deve) baixar a documentação das bibliotecas do Java,frequentementereferidacomo"javadoc"ouAPI(sendonaverdadeadocumentaçãodaAPI).

8.3JAVADOC

8.3JAVADOC 105

Page 116: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Nestadocumentação,noquadrosuperioresquerdo,vocêencontraospacotese,noinferioresquerdo,está a listagem das classes e interfaces do respectivo pacote (ou de todos, caso nenhum tenha sidoespecificado). Clicando-se em uma classe ou interface, o quadro da direita passa a detalhar todosatributosemétodos.

Reparequemétodoseatributosprivadosnãoestãoaí.Oimportanteédocumentaroquesuaclassefaz,enãocomoelafaz:detalhesdeimplementação,comoatributosemétodosprivados,nãointeressamaodesenvolvedorqueusaráasuabiblioteca(ou,aomenos,nãodeveriaminteressar).

Vocêtambémconseguegeraressejavadocapartirdalinhadecomando,comocomando:javadoc.

ParageraroJavadocapartirdoEclipseémuitosimples,sigaospassosabaixo:

Na barra de menu, selecione o menu Project, depois a opção "Generate Javadoc...". (apenasdisponívelseestivernaperspectivaJava,masvocêpodeacessaromesmowizardpeloexportdoprojeto).

8.4GERANDOOJAVADOC

106 8.4GERANDOOJAVADOC

Page 117: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Emseguida, aparecerãoasopçõesparageraradocumentaçãodoseu sistema, selecione todasasclassesdoseusistemaedeixeasoutrasopçõescomoestão.Nãoesqueçademarcarocaminhodaopção"Destination",poiséláqueestarásuadocumentação.

8.4GERANDOOJAVADOC 107

Page 118: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Abraadocumentaçãoatravésdocaminhoquevocêmarcoueabraoarquivo index.html,quevaichamarumapáginasemelhanteaessadafiguraabaixo.

Para colocarmos comentários na documentação, devemos adicionar ao código, sob forma decomentário,abrindootextocom/**efechandocom*/e,nasoutraslinhas,apenascolocando*.

Tambémpodemosdefiniroutrasinformaçõesnestetexto,como:autor,versão,parâmetros,retorno,etc.Adicionealgunscomentáriosaoseuprojetocomoabaixo:

/***ClasseresponsávelpormoldarasContasdoBanco**@authorManoelSantosdaSilva*/

publicclassConta{...}

Ouadicionealgunscomentáriosemalgummétodoseu:

/***Metodoqueincrementaosaldo.*@paramvalor*/

publicvoiddeposita(doublevalor){

108 8.4GERANDOOJAVADOC

Page 119: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

...}

Vejacomoficou:

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

8.5EXERCÍCIOS:JAREJAVADOC

8.5EXERCÍCIOS:JAREJAVADOC 109

Page 120: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

1. Gereumjardoseusistemacomoarquivodemanifesto.Execute-ocomjava-jar:

java-jarcaelum-banco-1.0.jar

SeoWindowsouoLinux foi configuradopara trabalhar comaextensão .jar,bastavocêdarumduplo clique no arquivo, que ele será "executado": o arquivo Manifest será lido para que ele

descubraqualéaclassecommainqueoJavadeveprocessar.

2. GereoJavadocdoseusistema.Paraisso,váaomenuProject,depoisàopçãoGenerateJavadoc,seestivernaperspectivaJava.Senão,dêumcliquecomobotãodireitonoseuprojeto,escolhaExportedepoisjavadocesigaoprocedimentodescritonaúltimaseçãodestecapítulo.

IndependentedaperspectivaquevocêusanoEclipse,vocêtambémpodeusaroctrl+3ecomeçaraescreverJavaDoc,atéqueaopçãodeexportaroJavaDocapareça.

INTERFACEVERSUSIMPLEMENTAÇÃONOVAMENTE!

Repare que a documentação gerada não mostra o conteúdo dos métodos, nem atributos emétodosprivados!Issofazpartedaimplementação,eoqueimportaparaquemusaumabibliotecaéainterface:oqueelafaz.

Jásabemoscomodocumentarnossoprojetoegerarumjarparadistribuí-lomaselaaindanãotemuma interface gráfica do usuário. Se quisermos rodar o nosso sistema temos que executá-lo peloterminal com os valores hard-coded. Seria mais interessante que tivéssemos uma interface maisamigávelparaqueousuáriopudesse interagircomonossosistema.Aomesmotempo,nãoqueremosnospreocuparnessemomentoemcriartodasasclassespararepresentaressainterfacegráfica,queremosapenasutilizaralgojápronto.

Para isso, vamos importar uma biblioteca externa. O próprio Eclipse já nos dá suporte para aimportaçãodejars.Parafazerisso,bastairnomenuProject->Properties,selecionaraopçãoJavaBuildPath,depoisselecionaraabaLibrariese,finalmente,clicarnobotãoAddExternalJars... .Agoraésóselecionar o jar a ser importado e clicar emOpen.Clique emOknovamente para fechar a janela deimportaçãoepronto!Nossabibliotecajáestáprontaparaserutilizada.

1. Vamosimportarumjarquecontémainterfacegráficadousuárioparaonossosistemadecontas.

8.6IMPORTANDOUMJAREXTERNO

8.7EXERCÍCIOS:IMPORTANDOUMJAR

110 8.6IMPORTANDOUMJAREXTERNO

Page 121: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

VánomenuProject->PropertiesSelecioneaopçãoJavaBuildPath

SelecioneaabaLibraries

CliquenobotãoAddExternalJars...

Selecioneoarquivofj11-lib-contas.jarlocalizadonapastadosarquivosdoscursos/11

CliquenobotãoOkparafecharajaneladeimportação

2. Para verificarmos que a importação deu certo, vamos chamar uma classe da biblioteca importadaparaexibirumajaneladeboas-vindas.

CrieumaclasseTestaJarnopacotebr.com.caelum.contas.main.

Crietambémométodomain.

3. Dentrodométodocriado,vamosinvocarométodomaindaclasseOlaMundo que existe no jar

importado.Seucódigodeveficardessamaneira:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.OlaMundo;

publicclassTestaJar{

publicstaticvoidmain(String[]args){OlaMundo.main(args);}}

NãoesqueçadeimportaraclasseOlaMundodopacotebr.com.caelum.javafx.api.main.Useo

atalhoctrl+shift+O.

8.7EXERCÍCIOS:IMPORTANDOUMJAR 111

Page 122: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

4. Executeasuaaplicaçãoevejaseapareceuumajaneladeboas-vindascomoaseguir:

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

AgoraquejáimportamosoJarquecontémainterfacegráfica,vamosdarumaolhadanaprimeirateladonossosistema:

Agoraéamelhorhoradeaprenderalgonovo

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

112 8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

Page 123: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Nestatela,podemosperceberquetemosbotõesparaasaçõesdecriaçãodeconta,saqueedepósito,quedevemutilizaraimplementaçãoexistenteemnossaclasseConta.

Se quisermos visualizar a tela, podemos criar um main que chamará a classe TelaDeContas

responsávelpelasuaexibição:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA 113

Page 124: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Aoexecutarmosaaplicaçãoocorreráumerro:

Masporqueesteerroocorreu?Acontecequeatelaprecisaconheceralguémquesaibaexecutarasaçõesdesaqueedepósitonaconta,queconsigabuscarosdadosdatelaparapopularaconta.Comonãotemosninguémquesaibafazeristoainda,ocorreuoerro.

VamosentãocriaraclasseManipuladorDeContasqueseráresponsávelporfazeresta"ponte"entre

atelaeaclassedeConta:

packagebr.com.caelum.contas;

publicclassManipuladorDeContas{

}

Agora,aoexecutarmosaaplicação,veremosqueatelaaparececomsucesso:

114 8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

Page 125: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Esetentarmosclicarnobotãodecriaçãodeconta?Tambémocorreumerro!

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA 115

Page 126: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

DestavezoerroindicaquefaltaométodocriaContadentrodaclasseManipuladorDeContas.

Vamosentãocriá-lo:

publicclassManipuladorDeContas{

publicvoidcriaConta(){Contaconta=newConta();conta.setAgencia("1234");conta.setNumero(56789);conta.setTitular("Batman");}}

Paraconseguirmosobterasinformaçõesdatela,todososmétodosquecriaremosprecisamreceberumparâmetrodotipoEventoqueconteráasinformaçõesdigitadas.Mesmoquenãoutilizemoseste

parâmetro,precisamosrecebê-lo.

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

publicvoidcriaConta(Eventoevento){Contaconta=newConta();conta.setAgencia("1234");conta.setNumero(56789);conta.setTitular("Batman");}}

Setentarmosexecutaraaplicaçãoeclicarnobotãocriaconta,vemosqueagoranãoocorremaisnenhumerromasaomesmotempoosdadosdacontanãosãopopuladosna tela. Istoacontecepoisavariávelconta é apenas local,ou seja, ela sóexistedentrodométodocriaConta.Alémdisso se

quiséssemosdepositarumvalornaconta,emqualcontadepositaríamos?Elanãoévisívelparanenhum

116 8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

Page 127: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

outrométodo!

PrecisamosqueestavariávelsejaumatributodoManipuladorDeContas.Vamosalterar:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

privateContaconta;

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setAgencia("1234");this.conta.setNumero(56789);this.conta.setTitular("Batman");}}

Testandoagoraconseguimosverosdadosdacontanatela!

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA 117

Page 128: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Só falta criarmos os métodos saca e deposita. Vamos começar implementando o método

deposita. Nele precisamos do valor digitado pelo usuário na tela e é pra isto que serve a classe

Evento. Se quisermos buscar um valor do tipo double, podemos invocar o método double

passandoonomedocampoquequeremosrecuperarcomoparâmetro.Comovaloremmãos,podemosentãopassá-loparaométododesejado.Nossométodofica:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

//...

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}}

Podemosfazeromesmoparaométodosaca:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

//...

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}

publicvoidsaca(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.saca(valorDigitado);}}

Agoraconseguimosrodaraaplicaçãoechamarasaçõesdesaqueedepósitoqueosaldoéatualizadocomsucesso!

118 8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

Page 129: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

1. CrieaclasseManipuladorDeContasdentrodopacotebr.com.caelum.contas.Reparequeos

pacotes br.com.caelum.contas.main e br.com.caelum.contas.modelo são subpacotes do

pacotebr.com.caelum.contas,portantoopacotebr.com.caelum.contasjáexiste.Paracriara

classenestepacote,bastaselecioná-lonajaneladecriaçãodaclasse:

8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA

8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA 119

Page 130: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

A classe ManipuladorDeContas fará a ligação da Conta com a tela, por isso precisaremos

declararumatributodotipoConta.

2. CrieométodocriaContaquerecebecomoparâmetroumobjetodotipoEvento.Instancieuma

contaparaoatributocontaecoloqueosvaloresdenumero,agenciaetitular.Algocomo:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setTitular("Batman");//façaomesmoparaosoutrosatributos}

3. Comacontainstanciada,agorapodemosimplementarasfuncionalidadesdesaqueedepósito.CrieométododepositaquerecebeumEvento,queéaclassequeretornaosdadosdatelanostipos

queprecisamos.Porexemplo,sequisermosovaloradepositarsabemosqueeleédotipodoublee

queonomedocamponatelaévalorentãopodemosfazer:

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}

120 8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA

Page 131: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

4. Crie agora o método saca. Ele também deve receber um Evento nos mesmos moldes do

deposita.

5. Precisamos agora testar nossa aplicação, crie a classe TestaContas dentro do pacote

br.com.caelum.contascomummain.NelavamoschamaromaindaclasseTelaDeContas

quemostraráateladenossosistema.Nãoseesqueçadefazeroimportdestaclasse!

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

Rodeaaplicação,crieacontaetentefazerasoperaçõesdesaqueedepósito.Tudodevefuncionarnormalmente.

8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA 121

Page 132: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO9

"Ohomemabsurdoéaquelequenuncamuda."--GeorgesClemenceau

Aotérminodessecapítulo,vocêserácapazde:

dizeroqueéherançaequandoutilizá-la;reutilizarcódigoescritoanteriormente;criarclassesfilhasereescrevermétodos;usartodoopoderqueopolimorfismodá.

Comotodaempresa,nossoBancopossuifuncionários.VamosmodelaraclasseFuncionario:

publicclassFuncionario{privateStringnome;privateStringcpf;privatedoublesalario;//métodosdevemviraqui}

Alémdeumfuncionáriocomum,hátambémoutroscargos,comoosgerentes.Osgerentesguardama mesma informação que um funcionário comum, mas possuem outras informações, além de terfuncionalidadesumpoucodiferentes.Umgerentenonossobancopossuitambémumasenhanuméricaquepermiteoacessoaosistemainternodobanco,alémdonúmerodefuncionáriosqueelegerencia:

publicclassGerente{privateStringnome;privateStringcpf;privatedoublesalario;privateintsenha;privateintnumeroDeFuncionariosGerenciados;

publicbooleanautentica(intsenha){if(this.senha==senha){System.out.println("AcessoPermitido!");returntrue;}else{System.out.println("AcessoNegado!");returnfalse;}

HERANÇA,REESCRITAEPOLIMORFISMO

9.1REPETINDOCÓDIGO?

122 9HERANÇA,REESCRITAEPOLIMORFISMO

Page 133: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

//outrosmétodos}

PRECISAMOSMESMODEOUTRACLASSE?

PoderíamosterdeixadoaclasseFuncionariomaisgenérica,mantendonelasenhadeacesso,

e o número de funcionários gerenciados.Caso o funcionário não fosse umgerente, deixaríamosestesatributosvazios.

Essaéumapossibilidade,porémpodemoscomeçaratermuitoatributosopcionais,eaclasseficariaestranha.Eemrelaçãoaosmétodos?AclasseGerente temométodoautentica, que

nãofazsentidoexistiremumfuncionárioquenãoégerente.

Se tivéssemos um outro tipo de funcionário que tem características diferentes do funcionáriocomum,precisaríamoscriarumaoutraclasseecopiarocódigonovamente!

Além disso, se um dia precisarmos adicionar uma nova informação para todos os funcionários,precisaremospassarportodasasclassesdefuncionárioeadicionaresseatributo.Oproblemaacontecenovamentepornãocentralizarmosasinformaçõesprincipaisdofuncionárioemumúnicolugar!

Existeumjeito,emJava,derelacionarmosumaclassedetalmaneiraqueumadelasherdatudoqueaoutratem.Istoéumarelaçãodeclassemãeeclassefilha.Nonossocaso,gostaríamosdefazercomqueoGerentetivessetudoqueumFuncionariotem,gostaríamosqueelafosseumaextensão deFuncionario.Fazemosistoatravésdapalavrachaveextends.

publicclassGerenteextendsFuncionario{privateintsenha;privateintnumeroDeFuncionariosGerenciados;

publicbooleanautentica(intsenha){if(this.senha==senha){System.out.println("AcessoPermitido!");returntrue;}else{System.out.println("AcessoNegado!");returnfalse;}}

//setterdasenhaomitido}

Em todo momento que criarmos um objeto do tipo Gerente, este objeto possuirá também os

atributosdefinidosnaclasseFuncionario,poisumGerenteéumFuncionario:

9.1REPETINDOCÓDIGO? 123

Page 134: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicclassTestaGerente{publicstaticvoidmain(String[]args){Gerentegerente=newGerente();

//podemoschamarmétodosdoFuncionario:gerente.setNome("JoãodaSilva");

//etambémmétodosdoGerente!gerente.setSenha(4231);}}

DizemosqueaclasseGerenteherdatodososatributosemétodosdaclassemãe,nonossocaso,aFuncionario.Para sermaispreciso, ela tambémherdaosatributosemétodosprivados,porémnão

consegue acessá-los diretamente. Para acessar um membro privado na filha indiretamente, serianecessárioqueamãeexpusesseumoutrométodovisívelqueinvocasseesseatributooumétodoprivado.

SUPERESUBCLASSE

A nomenclatura mais encontrada é que Funcionario é a superclasse de Gerente , eGerente é a subclasse de Funcionario . Dizemos também que todo Gerente é umFuncionário.OutraformaédizerqueFuncionarioéclassemãedeGerenteeGerenteéclassefilhadeFuncionario.

E se precisamos acessar os atributos que herdamos? Não gostaríamos de deixar os atributos deFuncionario,public,poisdessamaneiraqualquerumpoderiaalterarosatributosdosobjetosdeste

tipo.Existeumoutromodificadordeacesso,oprotected,queficaentreoprivateeopublic.

Umatributoprotectedsópodeseracessado(visível)pelaprópriaclasse,porsuassubclasses,epelas

classesqueseencontramnomesmopacote.

publicclassFuncionario{protectedStringnome;protectedStringcpf;protecteddoublesalario;//métodosdevemviraqui}

124 9.1REPETINDOCÓDIGO?

Page 135: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

SEMPREUSARPROTECTED?

Entãoporqueusarprivate?Depoisdeumtempoprogramandoorientadoaobjetos,vocêvai

começarasentirquenemsempreéumaboaideiadeixarqueaclassefilhaacesseosatributosdaclassemãe, pois isso quebra um pouco a ideia de que só aquela classe deveriamanipular seusatributos.Essaéumadiscussãoumpoucomaisavançada.

Alémdisso,nãosóassubclasses,mastambémasoutrasclassesqueseencontramnomesmopacote, podem acessar os atributos protected. Veja outras alternativas ao protected no

exercíciodediscussãoemsaladeaulajuntamentecomoinstrutor.

Da mesma maneira, podemos ter uma classe Diretor que estenda Gerente e a classe

PresidentepodeestenderdiretamentedeFuncionario.

Fique claro que essa é uma decisão de negócio. Se Diretor vai estender de Gerente ou não, vaidependerse,paravocê,DiretoréumGerente.

Umaclassepodeterváriasfilhas,maspodeterapenasumamãe,éachamadaherançasimplesdojava.

9.1REPETINDOCÓDIGO? 125

Page 136: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Todofimdeano,osfuncionáriosdonossobancorecebemumabonificação.Osfuncionárioscomunsrecebem10%dovalordosalárioeosgerentes,15%.

VamosvercomoficaaclasseFuncionario:

publicclassFuncionario{protectedStringnome;protectedStringcpf;protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*0.10;}//métodos}

SedeixarmosaclasseGerentecomoelaestá,elavaiherdarométodogetBonificacao.

Gerentegerente=newGerente();gerente.setSalario(5000.0);System.out.println(gerente.getBonificacao());

O resultado aqui será 500.Não queremos essa resposta, pois o gerente deveria ter 750 de bônusnesse caso. Para consertar isso, uma das opções seria criar um novo método na classe Gerente,

chamado, por exemplo, getBonificacaoDoGerente. O problema é que teríamos dois métodos em

Gerente, confundindo bastante quem for usar essa classe, além de que cada um da uma resposta

diferente.

NoJava,quandoherdamosummétodo,podemosalterarseucomportamento.Podemosreescrever(reescrever,sobrescrever,override)estemétodo:

publicclassGerenteextendsFuncionario{

EditoraCasadoCódigocomlivrosdeumaformadiferente

9.2REESCRITADEMÉTODO

126 9.2REESCRITADEMÉTODO

Page 137: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnthis.salario*0.15;}//...}

AgoraométodoestácorretoparaoGerente.Refaçaotesteevejaqueovalorimpressoéocorreto

(750):

Gerentegerente=newGerente();gerente.setSalario(5000.0);System.out.println(gerente.getBonificacao());

AANOTAÇÃO@OVERRIDE

Hácomodeixarexplícitonoseucódigoquedeterminadométodoéareescritadeummétododasua classe mãe. Fazemos isso colocando @Override em cima do método. Isso é chamado

anotação.Existemdiversasanotaçõesecadaumavaiterumefeitodiferentesobreseucódigo.

@OverridepublicdoublegetBonificacao(){returnthis.salario*0.15;}

Repare que, por questões de compatibilidade, isso não é obrigatório. Mas caso ummétodoesteja anotado com @Override, ele necessariamente precisa estar reescrevendo um método daclassemãe.

Depoisde reescrito,nãopodemosmais chamarométodoantigoque foraherdadodaclassemãe:realmente alteramos o seu comportamento. Mas podemos invocá-lo no caso de estarmos dentro daclasse.

Imaginequepara calcular abonificaçãodeumGerente devemos fazer igual ao cálculodeum

FuncionarioporémadicionandoR$1000.Poderíamosfazerassim:

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnthis.salario*0.10+1000;}//...}

9.3INVOCANDOOMÉTODOREESCRITO

9.3INVOCANDOOMÉTODOREESCRITO 127

Page 138: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Aquiteríamosumproblema:odiaqueogetBonificacaodoFuncionariomudar,precisaremos

mudar o método do Gerente para acompanhar a nova bonificação. Para evitar isso, o

getBonificacaodoGerentepodechamarodoFuncionarioutilizandoapalavrachavesuper.

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnsuper.getBonificacao()+1000;}//...}

Essa invocação vai procurar o método com o nome getBonificacao de uma super classe de

Gerente.NocasoelelogovaiencontraressemétodoemFuncionario.

Essaéumapráticacomum,poismuitoscasosométodoreescritogeralmentefaz"algoamais"queométododaclassemãe.Chamarounãoométododecimaéumadecisãosuaedependedoseuproblema.Algumasvezesnãofazsentidoinvocarométodoquereescrevemos.

OqueguardaumavariáveldotipoFuncionario?UmareferênciaparaumFuncionario,nuncao

objetoemsi.

Naherança,vimosquetodoGerenteéumFuncionario,poiséumaextensãodeste.Podemos

nos referir a um Gerente como sendo um Funcionario . Se alguém precisa falar com um

Funcionariodobanco,podefalarcomumGerente!Porque?PoisGerenteéumFuncionario.

Essaéasemânticadaherança.

Gerentegerente=newGerente();Funcionariofuncionario=gerente;funcionario.setSalario(5000.0);

Polimorfismo é a capacidade de um objeto poder ser referenciado de várias formas. (cuidado,polimorfismonãoquerdizerqueoobjetoficasetransformando,muitopelocontrário,umobjetonascedeumtipoemorredaqueletipo,oquepodemudaréamaneiracomonosreferimosaele).

9.4POLIMORFISMO

128 9.4POLIMORFISMO

Page 139: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Atéaquitudobem,maseseeutentar:

funcionario.getBonificacao();

Qual é o retorno desse método? 500 ou 750? No Java, a invocação de método sempre vai serdecidida em tempo de execução. O Java vai procurar o objeto na memória e, aí sim, decidir qualmétododeveserchamado,semprerelacionandocomsuaclassedeverdade,enãocomaqueestamosusando para referenciá-lo. Apesar de estarmos nos referenciando a esse Gerente como sendo um

Funcionario,ométodoexecutadoéodoGerente.Oretornoé750.

Parece estranho criar um gerente e referenciá-lo como apenas um funcionário. Por que faríamosisso?Naverdade,asituaçãoquecostumaapareceréaquetemosummétodoquerecebeumargumentodotipoFuncionario:

classControleDeBonificacoes{privatedoubletotalDeBonificacoes=0;

publicvoidregistra(Funcionariofuncionario){this.totalDeBonificacoes+=funcionario.getBonificacao();}

publicdoublegetTotalDeBonificacoes(){returnthis.totalDeBonificacoes;}}

E,emalgumlugardaminhaaplicação(ounomain,seforapenasparatestes):

ControleDeBonificacoescontrole=newControleDeBonificacoes();

Gerentefuncionario1=newGerente();funcionario1.setSalario(5000.0);controle.registra(funcionario1);

Funcionariofuncionario2=newFuncionario();funcionario2.setSalario(1000.0);controle.registra(funcionario2);

System.out.println(controle.getTotalDeBonificacoes());

ReparequeconseguimospassarumGerenteparaummétodoquerecebeumFuncionariocomo

argumento. Pense como numa porta na agência bancária com o seguinte aviso: "Permitida a entradaapenas de Funcionários". Um gerente pode passar nessa porta? Sim, pois Gerente é umFuncionario.

Qual será o valor resultante? Não importa que dentro do método registra doControleDeBonificacoesrecebaFuncionario.Quandoelereceberumobjetoquerealmenteéum

Gerente,oseumétodoreescritoseráinvocado.Reafirmando:nãoimportacomonosreferenciamosaumobjeto,ométodoqueseráinvocadoésempreoqueédele.

No dia emque criarmos uma classeSecretaria, por exemplo, que é filha deFuncionario,

9.4POLIMORFISMO 129

Page 140: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

precisaremos mudar a classe de ControleDeBonificacoes? Não. Basta a classe Secretaria

reescrever os métodos que lhe parecerem necessários. É exatamente esse o poder do polimorfismo,juntamentecomareescritademétodo:diminuiroacoplamentoentreasclasses,paraevitarquenovoscódigosresultememmodificaçõeseminúmeroslugares.

ReparequequemcriouControleDeBonificacoespodenunca ter imaginadoacriaçãodaclasse

Secretaria ouEngenheiro. Contudo, não será necessário reimplementar esse controle em cada

novaclasse:reaproveitamosaquelecódigo.

HERANÇAVERSUSACOPLAMENTO

Notequeousodeherançaaumentaoacoplamentoentreasclasses,istoé,oquantoumaclassedependedeoutra.Arelaçãoentreclassemãeefilhaémuitoforteeissoacabafazendocomqueoprogramadordasclassesfilhas tenhaqueconhecera implementaçãodaclassemãeevice-versa-ficadifícilfazerumamudançapontualnosistema.

Por exemplo, imagine se tivermos quemudar algo na nossa classeFuncionario,masnão

quiséssemosquetodososfuncionáriossofressemamesmamudança.Precisaríamospassarporcadauma das filhas de Funcionario verificando se ela se comporta como deveria ou se devemos

sobrescreverotalmétodomodificado.

Esseéumproblemadaherança,enãodopolimorfismo,que resolveremosmais tardecomaajudadeInterfaces.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

JáconheceoscursosonlineAlura?

9.5UMOUTROEXEMPLO

130 9.5UMOUTROEXEMPLO

Page 141: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Imaginequevamosmodelarumsistemaparaafaculdadequecontroleasdespesascomfuncionárioseprofessores.Nossofuncionárioficaassim:

publicclassEmpregadoDaFaculdade{privateStringnome;privatedoublesalario;publicdoublegetGastos(){returnthis.salario;}publicStringgetInfo(){return"nome:"+this.nome+"comsalário"+this.salario;}//métodosdeget,seteoutros}

Ogastoquetemoscomoprofessornãoéapenasseusalário.Temosdesomarumbônusde10reaisporhora/aula.Oquefazemosentão?Reescrevemosométodo.AssimcomoogetGastosédiferente,o

getInfotambémserá,poistemosdemostrarashoras/aulatambém.

publicclassProfessorDaFaculdadeextendsEmpregadoDaFaculdade{privateinthorasDeAula;publicdoublegetGastos(){returnthis.getSalario()+this.horasDeAula*10;}publicStringgetInfo(){StringinformacaoBasica=super.getInfo();Stringinformacao=informacaoBasica+"horasdeaula:"+this.horasDeAula;returninformacao;}//métodosdeget,seteoutrosqueforemnecessários}

Anovidade,aqui,éapalavrachavesuper.Apesardométodo ter sido reescrito,gostaríamosde

acessar ométodo da classemãe, para não ter de copiar e colocar o conteúdo dessemétodo e depoisconcatenarcomainformaçãodashorasdeaula.

Comotiramosproveitodopolimorfismo?Imaginequetemosumaclassederelatório:

publicclassGeradorDeRelatorio{publicvoidadiciona(EmpregadoDaFaculdadef){System.out.println(f.getInfo());System.out.println(f.getGastos());}}

Podemos passar para nossa classe qualquer EmpregadoDaFaculdade! Vai funcionar tanto para

professor,quantoparafuncionáriocomum.

Umcertodia,muitodepoisdeterminaressaclassederelatório,resolvemosaumentarnossosistema,e colocar uma classe nova, que representa o Reitor . Como ele também é um

EmpregadoDaFaculdade,seráquevamosprecisaralteraralgonanossaclassedeRelatorio?Não.

Essa é a ideia!Quemprogramou a classeGeradorDeRelatorio nunca imaginou que existiria uma

9.5UMOUTROEXEMPLO 131

Page 142: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classeReitore,mesmoassim,osistemafunciona.

publicclassReitorextendsEmpregadoDaFaculdade{//informaçõesextraspublicStringgetInfo(){returnsuper.getInfo()+"eeleéumreitor";}//nãosobrescrevemosogetGastos!!!}

SenãohouvesseherançaemJava,comovocêpoderiareaproveitarocódigodeoutraclasse?

Uma discussãomuito atual é sobre o abuso no uso da herança.Algumas pessoas usam herançaapenas para reaproveitar o código, quando poderiam ter feito uma composição. Procure sobreherançaversuscomposição.

Mesmodepoisdereescreverummétododaclassemãe,aclassefilhaaindapodeacessarométodoantigo. Isto é feito através da palavra chave super.método(). Algo parecido ocorre entre os

construtoresdasclasses,oque?

MAISSOBREOMAUUSODAHERANÇA

NoblogdaCaelumexisteumartigointeressanteabordandoessetópico:

http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/

JamesGosling,umdoscriadoresdoJava,éumcríticodomauusodaherança.Nestaentrevistaelediscuteapossibilidadedeseutilizarapenasinterfacesecomposição,eliminandoanecessidadedaherança:

http://www.artima.com/intv/gosling3P.html

1. Vamostermaisdeumtipodecontanonossosistemaentãovamosprecisardeumanovatelaparacadastrarosdiferentestiposdeconta.Essatelajáestáprontaeparautilizá-lasóprecisamosalteraraclassequeestamoschamandonométodomain()noTestaContas.java:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.SistemaBancario;

publicclassTestaContas{

9.6UMPOUCOMAIS...

9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO

132 9.6UMPOUCOMAIS...

Page 143: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicstaticvoidmain(String[]args){SistemaBancario.mostraTela(false);//TelaDeContas.main(args);}}

2. AorodaraclasseTestaContasagora,teremosatelaabaixo:

Vamosentrarna teladecriaçãodecontasparavermosoqueprecisamos implementarparaqueosistemafuncione.Paraisso,cliquenobotãoNovaConta.Aseguintetelaaparecerá:

Podemos perceber que além das informações que já tínhamos na conta, temos agora o tipo: sequeremosumacontacorrenteouumacontapoupança.Vamosentãocriarasclassescorrespondentes.

CrieaclasseContaCorrentenopacotebr.com.caelum.contas.modeloe façacomqueela

sejafilhadaclasseConta

CrieaclasseContaPoupancanopacotebr.com.caelum.contas.modeloe façacomqueela

sejafilhadaclasseConta

9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO 133

Page 144: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

3. Precisamos pegar os dados da tela para conseguirmos criar a conta correspondente. NoManipuladorDeContas vamos alterar ométodocriaConta.Atualmente, apenas criamos uma

novacontacomosdadosdiretonocódigo.Vamosfazercomqueagoraosdadossejamrecuperadosdatelaparacolocarmosnanovaconta,faremosissoutilizandooobjetoevento:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setAgencia(evento.getString("agencia"));this.conta.setNumero(evento.getInt("numero"));this.conta.setTitular(evento.getString("titular"));}

Masprecisamosdizer qual tipode conta quequeremos criar!Devemos então recuperar o tipodacontaescolhidoecriaracontacorrespondente.Paraisso,aoinvésdecriarumobjetodotipo'Conta',vamosusarométodogetSelecionadoNoRadiodoobjetoeventoparapegarotipo,fazerumif

paraverificaresse tipoesódepoiscriaroobjetodotipocorrespondente.Apósessasmudanças,ométodocriaContaficarácomoabaixo:

publicvoidcriaConta(Eventoevento){Stringtipo=evento.getSelecionadoNoRadio("tipo");if(tipo.equals("ContaCorrente")){this.conta=newContaCorrente();}elseif(tipo.equals("ContaPoupança")){this.conta=newContaPoupanca();}this.conta.setAgencia(evento.getString("agencia"));this.conta.setNumero(evento.getInt("numero"));this.conta.setTitular(evento.getString("titular"));}

4. Apesarde jáconseguirmoscriarosdois tiposdecontas,nossa listanãoconsegueexibiro tipodecadacontanalistadatelainicial.Pararesolverisso,podemoscriarummétodogetTipoemcada

umadenossascontasfazendocomqueacontacorrentedevolvaastring"ContaCorrente"eacontapoupançadevolvaastring"ContaPoupança":

publicclassContaCorrenteextendsConta{publicStringgetTipo(){return"ContaCorrente";}}

publicclassContaPoupancaextendsConta{publicStringgetTipo(){return"ContaPoupança";}}

5. AltereosmétodossacaedepositaparabuscaremocampovalorOperacaoaoinvésdeapenas

valornaclasseManipuladorDeContas.

6. Vamosmudaro comportamentodaoperaçãode saquede acordo como tipode contaque estiversendo utilizada.Na classeManipuladorDeContas vamos alterar ométodo saca para tirar 10

134 9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO

Page 145: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

centavosdecadasaqueemumacontacorrente:

publicvoidsaca(Eventoevento){doublevalor=evento.getDouble("valorOperacao");if(this.conta.getTipo().equals("ContaCorrente")){this.conta.saca(valor+0.10);}else{this.conta.saca(valor);}}

AotentarmoschamarométodogetTipo,oEclipsereclamouqueessemétodonãoexistenaclasse

Contaapesardeexistirnasclassesfilhas.Comoestamostratandotodasascontasgenericamente,

sóconseguimosacessarosmétodosdaclassemãe.Vamosentãocolocá-lonaclasseConta:

publicclassConta{publicStringgetTipo(){return"Conta";}}

7. Agoraocódigocompilamastemosumoutroproblema.AlógicadonossosaquevazouparaaclasseManipuladorDeContas.Sealgumdiaprecisarmosalterarovalordataxanosaque, teríamosque

mudar em todos os lugares onde fazemos uso do método saca . Esta lógica deveria estar

encapsuladadentrodométodosacadecadaconta.Vamosentãosobrescreverométododentroda

classeContaCorrente:

publicclassContaCorrenteextendsConta{@Overridepublicvoidsaca(doublevalor){this.saldo-=(valor+0.10);}

//restantedaclasse}

Repareque,paraacessaroatributo saldoherdadodaclasseConta,vocêvaiprecisarmudaromodificadordevisibilidadedesaldoparaprotected.

Agora que a lógica está encapsulada, podemos corrigir o método saca da classe

ManipuladorDeContas:

publicvoidsaca(Eventoevento){doublevalor=evento.getDouble("valorOperacao");this.conta.saca(valor);}

Percebaqueagoratratamosacontadeformagenérica!

8. Rode a classe TestaContas, adicione uma conta de cada tipo e veja se o tipo é apresentado

corretamentenalistadecontasdatelainicial.

Agora,cliquenacontacorrenteapresentadanalistaparaabrirateladedetalhesdecontas.Testeas

9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO 135

Page 146: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

operações de saque e depósito e perceba que a conta apresenta o comportamento de uma contacorrenteconformeoesperado.

Esetentarmosrealizarumatransferênciadacontacorrenteparaacontapoupança?Oqueacontece?

9. VamoscomeçarimplementandoométodotransferenaclasseConta:

publicvoidtransfere(doublevalor,Contaconta){this.saca(valor);conta.deposita(valor);}

Tambémprecisamos implementar ométodotransfere na classeManipuladorDeContas para

fazerovínculoentreatelaeaclasseConta:

publicvoidtransfere(Eventoevento){Contadestino=(Conta)evento.getSelecionadoNoCombo("destino");conta.transfere(evento.getDouble("valorTransferencia"),destino);}

Rodedenovoaaplicaçãoetesteaoperaçãodetransferência.

10. Considereocódigoabaixo:

Contac=newConta();ContaCorrentecc=newContaCorrente();ContaPoupancacp=newContaPoupanca();

Semudarmosessecódigopara:

Contac=newConta();Contacc=newContaCorrente();Contacp=newContaPoupanca();

Compila?Roda?Oquemuda?Qualéautilidadedisso?Realmente,essanãoéamaneiramaisútildo polimorfismo. Porém existe uma utilidade de declararmos uma variável de um tipo menosespecíficodoqueoobjetorealmenteé,comofazemosnaclasseManipuladorDeContas.

Éextremamenteimportanteperceberquenãoimportacomonosreferimosaumobjeto,ométodoqueserá invocadoésempreomesmo!AJVMvaidescobriremtempodeexecuçãoqualdeveserinvocado,dependendodequetipoéaqueleobjeto,nãoimportandocomonosreferimosaele.

11. (Opcional)AnossaclasseContadevolveapalavra"Conta"nométodogetTipo.Useapalavra

chavesuper nos métodos getTipo reescritos nas classes filhas, para não ter de reescreve a

palavra"Conta"aodevolverostipos"ContaCorrente"e"ContaPoupança".

12. (Opcional)SevocêprecisassecriarumaclasseContaInvestimento,e seumétodosaca fosse

complicadíssimo,vocêprecisariaalteraraclasseManipuladorDeContas?

136 9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO

Page 147: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Discuta com o instrutor e seus colegas alternativas ao uso do atributo protected na herança.

Preciso realmente afrouxar o encapsulamento do atributo por causa da herança? Como fazer para oatributocontinuarprivatenamãeeasfilhasconseguiremdealgumaformartrabalharcomele?

VocêpodetambémfazerocursodatadessaapostilanaCaelum

9.8 DISCUSSÕES EM AULA: ALTERNATIVAS AO ATRIBUTOPROTECTED

9.8DISCUSSÕESEMAULA:ALTERNATIVASAOATRIBUTOPROTECTED 137

Page 148: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO10

"Dá-seimportânciaaosantepassadosquandojánãotemosnenhum."--FrançoisChateaubriand

Aotérminodessecapítulo,vocêserácapazdeutilizarclassesabstratas,quandonecessário.

VamosrecordaremcomopodeestarnossaclasseFuncionario:

publicclassFuncionario{

protectedStringnome;protectedStringcpf;protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*1.2;}

//outrosmétodosaqui

}

ConsidereonossoControleDeBonificacao:

publicclassControleDeBonificacoes{

privatedoubletotalDeBonificacoes=0;

publicvoidregistra(Funcionariof){System.out.println("Adicionandobonificaçãodofuncionario:"+f);this.totalDeBonificacoes+=f.getBonificacao();}

publicdoublegetTotalDeBonificacoes(){returnthis.totalDeBonificacoes;}}

Nossométodoregistra recebe qualquer referência do tipo Funcionario, isto é, podem ser

objetosdo tipoFuncionario e qualquer de seus subtipos:Gerente,Diretor e, eventualmente,

alguma nova subclasse que venha ser escrita, sem prévio conhecimento do autor daControleDeBonificacao.

EstamosutilizandoaquiaclasseFuncionarioparaopolimorfismo.Senãofosseela,teríamosum

CLASSESABSTRATAS

10.1REPETINDOMAISCÓDIGO?

138 10CLASSESABSTRATAS

Page 149: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

grande prejuízo: precisaríamos criar um método registra para receber cada um dos tipos de

Funcionario,umparaGerente,umparaDiretor,etc.Reparequeperderessepoderémuitopiordoqueapequenavantagemqueaherançatrazemherdarcódigo.

Porém,emalgunssistemas,comoéonossocaso,usamosumaclassecomapenasessesintuitos:deeconomizar um pouco código e ganhar polimorfismo para criar métodos mais genéricos, que seencaixemadiversosobjetos.

Faz sentido ter uma referência do tipoFuncionario?Essapergunta é diferente de saber se faz

sentidoterumobjetodotipoFuncionario:nessecaso,fazsimeémuitoútil.

ReferenciandoFuncionariotemosopolimorfismodereferência,jáquepodemosreceberqualquer

objetoquesejaumFuncionario.Porém,darnewemFuncionariopodenãofazersentido,istoé,

não queremos receber umobjeto do tipoFuncionario,mas sim que aquela referência seja ou um

Gerente,ouumDiretor,etc.AlgomaisconcretoqueumFuncionario.

ControleDeBonificacoescdb=newControleDeBonificacoes();Funcionariof=newFuncionario();cdb.adiciona(f);//fazsentido?

Vejamosumoutrocasoemquenãofazsentidoterumobjetodaqueletipo,apesardaclasseexistir:imagineaclassePessoa eduas filhas,PessoaFisica ePessoaJuridica.Quandopuxamosum

relatóriodenossosclientes(umaarraydePessoaporexemplo),queremosquecadaumdelessejaou

umaPessoaFisica,ouumaPessoaJuridica.AclassePessoa, nesse caso, estaria sendousada

apenasparaganharopolimorfismoeherdaralgumascoisas:nãofazsentidopermitirinstanciá-la.

Pararesolveressesproblemas,temosasclassesabstratas.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

10.2CLASSEABSTRATA

10.2CLASSEABSTRATA 139

Page 150: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

O que, exatamente, vem a ser a nossa classe Funcionario ? Nossa empresa tem apenas

Diretores,Gerentes,Secretárias, etc.Ela é uma classeque apenas idealiza um tipo, define

apenasumrascunho.

Paraonossosistema,éinadmissívelqueumobjetosejaapenasdotipoFuncionario(podeexistir

umsistemaemquefaçasentidoterobjetosdotipoFuncionarioouapenasPessoa,mas,nonosso

caso,não).

Usamosapalavrachaveabstractparaimpedirqueelapossaserinstanciada.Esseéoefeitodireto

deseusaromodificadorabstractnadeclaraçãodeumaclasse:

publicabstractclassFuncionario{

protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*1.2;}

//outrosatributosemétodoscomunsatodosFuncionarios

}

E,nomeiodeumcódigo:

Funcionariof=newFuncionario();//nãocompila!!!

Ocódigoacimanãocompila.Oproblemaéinstanciaraclasse-criarreferência,vocêpode.Seelanãopodeserinstanciada,paraqueserve?Serveparaopolimorfismoeherançadosatributosemétodos,quesãorecursosmuitopoderosos,comojávimos.

Vamosentãoherdardessaclasse,reescrevendoométodogetBonificacao:

publicclassGerenteextendsFuncionario{

publicdoublegetBonificacao(){returnthis.salario*1.4+1000;}}

140 10.2CLASSEABSTRATA

Page 151: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Mas qual é a real vantagem de uma classe abstrata? Poderíamos ter feito isto com uma herançacomum. Por enquanto, a única diferença é que não podemos instanciar um objeto do tipoFuncionario,quejáédegrandevalia,dandomaisconsistênciaaosistema.

FiqueclaroqueanossadecisãodetransformarFuncionarioemumaclasseabstratadependeudo

nossodomínio.Podeserque,emumsistemacomclassessimilares,façasentidoqueumaclasseanálogaaFuncionariosejaconcreta.

SeométodogetBonificacaonãofossereescrito,eleseriaherdadodaclassemãe,fazendocom

quedevolvesseosaláriomais20%.

Levando em consideração que cada funcionário em nosso sistema tem uma regra totalmentediferente para ser bonificado, faz algum sentido ter essemétodona classeFuncionario? Será que

existeumabonificaçãopadrãoparatodotipodeFuncionario?Parecequenão,cadaclassefilhaterá

ummétodo diferente de bonificação pois, de acordo comnosso sistema, não existe uma regra geral:queremos que cada pessoa que escreve a classe de um Funcionario diferente (subclasses de

Funcionario)reescrevaométodogetBonificacaodeacordocomassuasregras.

Poderíamos,então,jogarforaessemétododaclasseFuncionario?Oproblemaéque,seelenão

existisse, não poderíamos chamar o método apenas com uma referência a um Funcionario, pois

ninguém garante que essa referência aponta para um objeto que possui essemétodo. Será que entãodevemosretornarumcódigo,comoumnúmeronegativo?Issonãoresolveoproblema:seesquecermosdereescreveressemétodo,teremosdadoserradossendoutilizadoscomobônus.

10.3MÉTODOSABSTRATOS

10.3MÉTODOSABSTRATOS 141

Page 152: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ExisteumrecursoemJavaque,emumaclasseabstrata,podemosescreverquedeterminadométodoserásempreescritopelasclassesfilhas.Istoé,ummétodoabstrato.

Eleindicaquetodasasclassesfilhas(concretas,istoé,quenãoforemabstratas)devemreescreveressemétodoounãocompilarão.Écomosevocêherdassearesponsabilidadedeteraquelemétodo.

COMODECLARARUMMÉTODOABSTRATO

Àsvezes,nãoficaclarocomodeclararummétodoabstrato.

Basta escrever a palavra chave abstract na assinatura do mesmo e colocar um ponto e

vírgulaemvezdeabreefechachaves!

publicabstractclassFuncionario{

publicabstractdoublegetBonificacao();

//outrosatributosemétodos

}

Reparequenãocolocamosocorpodométodoeusamosapalavrachaveabstractparadefiniro

mesmo. Por que não colocar corpo algum?Porque essemétodo nunca vai ser chamado, sempre quealguémchamarométodogetBonificacao,vaicairemumadassuasfilhas,querealmenteescreveram

ométodo.

Qualquer classe que estender a classe Funcionario será obrigada a reescrever este método,

tornando-o"concreto".Senãoreescreveremessemétodo,umerrodecompilaçãoocorrerá.

OmétododoControleDeBonificacaoestavaassim:

publicvoidregistra(Funcionariof){System.out.println("Adicionandobonificaçãodofuncionario:"+f);this.totalDeBonificacoes+=f.getBonificacao();}

ComopossoacessarométodogetBonificacaoseelenãoexistenaclasseFuncionario?

Jáqueométodoéabstrato,comcertezasuassubclassestêmessemétodo,oquegarantequeessainvocação demétodo não vai falhar. Basta pensar que uma referência do tipoFuncionario nunca

apontaparaumobjetoquenão temométodogetBonificacao, pois não é possível instanciar uma

classe abstrata, apenas as concretas.Ummétodo abstrato obriga a classe em que ele se encontra serabstrata,oquegaranteacoerênciadocódigoacimacompilar.

10.4AUMENTANDOOEXEMPLO

142 10.4AUMENTANDOOEXEMPLO

Page 153: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Ese,nonossoexemplodeempresa, tivéssemoso seguintediagramadeclasses comos seguintesmétodos:

Ouseja,tenhoaclasseabstrataFuncionario,comométodoabstratogetBonificacao;asclasses

GerenteePresidenteestendendoFuncionarioeimplementandoométodogetBonificacao;e,

porfim,aclasseDiretor,queestendeGerente,masnãoimplementaométodogetBonificacao.

Essasclassesvãocompilar?Vãorodar?

Arespostaésim.E,alémdetudo,farãoexatamenteoquenósqueremos,pois,quandoGerentee

Presidentepossuemosmétodosperfeitamenteimplementados,aclasseDiretor,quenãopossuio

métodoimplementado,vaiusaraimplementaçãoherdadadeGerente.

10.4AUMENTANDOOEXEMPLO 143

Page 154: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

E esse diagrama, no qual incluímos uma classe abstrata Secretaria sem o método

getBonificacao , que é estendida por mais duas classes ( SecretariaAdministrativa ,

SecretariaAgencia)que,porsuavez,implementamométodogetBonificacao,vaicompilar?Vai

rodar?

Denovo,arespostaésim,poisSecretariaéumaclasseabstratae,porisso,oJavatemcertezade

que ninguém vai conseguir instanciá-la e, muito menos, chamar o método getBonificacao dela.

Lembrando que, nesse caso, não precisamos nem ao menos escrever o método abstratogetBonificacaonaclasseSecretaria.

Seeunãoreescreverummétodoabstratodaminhaclassemãe,ocódigonãocompilará.Masposso,emvezdisso,declararaclassecomoabstrata!

JAVA.IO

Classes abstratas não possuem nenhum segredo no aprendizado,mas quem está aprendendoorientaçãoaobjetospodeterumaenormedificuldadeparasaberquandoutilizá-las,oqueémuitonormal.

Estudaremosopacote java.io,queusabastantes classesabstratas, sendoumexemplo realdeusodesserecurso,quevaimelhoraroentendimentodelas.(classeInputStreamesuasfilhas)

144 10.4AUMENTANDOOEXEMPLO

Page 155: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Uma classe que estende uma classe normal também pode ser abstrata! Ela não poderá serinstanciada,massuaclassepaisim!

Umaclasseabstratanãoprecisanecessariamenteterummétodoabstrato.

1. ReparequeanossaclasseContaéumaexcelentecandidataparaumaclasseabstrata.Porquê?Que

métodosseriaminteressantescandidatosaseremabstratos?

TransformeaclasseContaemabstrata:

publicabstractclassConta{//...}

2. ComoaclasseContaagoraéabstrata,nãoconseguimosdarnewnelamais.Senãopodemosdar

newemConta,qualéautilidadedeterummétodoquerecebeumareferênciaaConta como

argumento?Aliás,possoterisso?

3. Apenasparaentendermelhoroabstract,comenteométodogetTipo()daContaPoupanca,

dessaformaeleherdaráométododiretamentedeConta.

TransformeométodogetTipo()daclasseContaemabstrato.Repareque,aocolocarapalavra

chaveabstractaoladodométodo,oEclipserapidamentevaisugerirquevocêdeveremovero

corpo(body)dométodocomumquickfix.

SuaclasseContadeveficarparecidacom:

Agoraéamelhorhoradeaprenderalgonovo

10.5PARASABERMAIS...

10.6EXERCÍCIOS:CLASSESABSTRATAS

10.5PARASABERMAIS... 145

Page 156: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicabstractclassConta{//atributosemétodosquejáexistiam

publicabstractStringgetTipo();}

QualéoproblemacomaclasseContaPoupanca?

4. DescomenteométodogetTipo na classeContaPoupanca, e se necessário altere-opara que a

classepossacompilarnormalmente.

5. (opcional) Existe outramaneira de a classeContaPoupanca compilar se você não reescrever o

métodoabstrato?

6. (opcional)PraqueterométodogetTiponaclasseContaseelenãofaznada?Oqueacontecese

simplesmenteapagarmosessemétododaclasseContaedeixarmosométodogetTiponasfilhas?

7. (opcional) Posso chamar um método abstrato de dentro de um outro método da própria classeabstrata?Porexemplo,imaginequeexistaoseguintemétodonaclasseConta:

publicStringrecuperaDadosParaImpressao(){Stringdados="Titular:"+this.titular;dados+="\nNúmero:"+this.numero;dados+="\nAgência:"+this.agencia;dados+="\nSaldo:R$"+this.saldo;returndados;}

PodemosinvocarogetTipodentrodestemétodo?Algocomo:

dados+="\nTipo:"+this.getTipo();

146 10.6EXERCÍCIOS:CLASSESABSTRATAS

Page 157: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO11

"Umaimagemvalemilpalavras.Umainterfacevalemilimagens."--BenShneiderman

Aotérminodessecapítulo,vocêserácapazde:

dizeroqueéumainterfaceeasdiferençasentreherançaeimplementação;escreverumainterfaceemJava;utilizá-lascomoumpoderosorecursoparadiminuiracoplamentoentreasclasses.

ImaginequeumSistemadeControledoBancopode seracessado, alémdepelosGerentes,pelosDiretoresdoBanco.Então,teríamosumaclasseDiretor:

publicclassDiretorextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro}

}

EaclasseGerente:

publicclassGerenteextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro//nocasodogerenteverificatambémseodepartamentodele//temacesso}

}

INTERFACES

11.1AUMENTANDONOSSOEXEMPLO

11INTERFACES 147

Page 158: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ReparequeométododeautenticaçãodecadatipodeFuncionariopodevariarmuito.Masvamos

aosproblemas.Considere oSistemaInterno e seu controle: precisamos receber umDiretor ou

Gerentecomoargumento,verificarseeleseautenticaecolocá-lodentrodosistema.

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){//invocarométodoautentica?//nãoda!NemtodoFuncionariotem}}

OSistemaInterno aceitaqualquer tipodeFuncionario, tendo ele acesso ao sistemaounão,

masnotequenemtodoFuncionariopossuiométodoautentica.Issonosimpededechamaresse

método com uma referência apenas a Funcionario (haveria um erro de compilação). O que fazer

então?

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){funcionario.autentica(...);//nãocompila}}

UmapossibilidadeécriardoismétodosloginnoSistemaInterno:umparareceberDiretore

outroparareceberGerente.Jávimosqueessanãoéumaboaescolha.Porquê?

publicclassSistemaInterno{

//designproblemáticopublicvoidlogin(Diretorfuncionario){funcionario.autentica(...);}

//designproblemáticopublicvoidlogin(Gerentefuncionario){funcionario.autentica(...);}

}

148 11.1AUMENTANDONOSSOEXEMPLO

Page 159: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Cada vez que criarmos uma nova classe de Funcionario que é autenticável, precisaríamos

adicionarumnovométododeloginnoSistemaInterno.

MÉTODOSCOMMESMONOME

EmJava,métodospodemteromesmonomedesdequenãosejamambíguos,istoé,queexistaumamaneiradedistinguirnomomentodachamada.

Issosechamasobrecargademétodo.(Overloading.Nãoconfundircomoverriding,queéumconceitomuitomaispoderoso).

Uma solução mais interessante seria criar uma classe no meio da árvore de herança,FuncionarioAutenticavel:

publicclassFuncionarioAutenticavelextendsFuncionario{

publicbooleanautentica(intsenha){//fazautenticacaopadrão}

//outrosatributosemétodos

}

As classes Diretor e Gerente passariam a estender de FuncionarioAutenticavel, e o

SistemaInternoreceberiareferênciasdessetipo,comoaseguir:

publicclassSistemaInterno{

publicvoidlogin(FuncionarioAutenticavelfa){

intsenha=//pegasenhadeumlugar,oudeumscannerdepolegar

//aquieupossochamaroautentica!//PoistodoFuncionarioAutenticaveltembooleanok=fa.autentica(senha);

}}

11.1AUMENTANDONOSSOEXEMPLO 149

Page 160: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Repare que FuncionarioAutenticavel é uma forte candidata a classe abstrata.Mais ainda, o

métodoautenticapoderiaserummétodoabstrato.

O uso de herança resolve esse caso,mas vamos a uma outra situação umpoucomais complexa:precisamosquetodososclientestambémtenhamacessoaoSistemaInterno.Oquefazer?Umaopção

écriaroutrométodologinemSistemaInterno:masjádescartamosessaanteriormente.

Uma outra, que é comum entre os novatos, é fazer uma herança sem sentido para resolver oproblema,porexemplo, fazerClienteextendsFuncionarioAutenticavel.Realmente, resolveo

problema,mastrarádiversosoutros.ClientedefinitivamentenãoéFuncionarioAutenticavel.Sevocê fizer isso,oCliente terá, por exemplo, ummétodogetBonificacao, umatributo salario e

outrosmembrosquenãofazemomenorsentidoparaestaclasse!Nãofaçaherançaquandoarelaçãonãoéestritamente"éum".

150 11.1AUMENTANDONOSSOEXEMPLO

Page 161: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Como resolver essa situação? Note que conhecer a sintaxe da linguagem não é o suficiente,precisamosestruturar/desenharbemanossaestruturadeclasses.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

O que precisamos para resolver nosso problema? Arranjar uma forma de poder referenciarDiretor,GerenteeClientedeumamesmamaneira,istoé,acharumfatorcomum.

Seexistisseumaformanaqualessasclassesgarantissemaexistênciadeumdeterminadométodo,

EditoraCasadoCódigocomlivrosdeumaformadiferente

11.2INTERFACES

11.2INTERFACES 151

Page 162: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

atravésdeumcontrato,resolveríamosoproblema.

Todaclassedefine2itens:

oqueumaclassefaz(asassinaturasdosmétodos)comoumaclassefazessastarefas(ocorpodosmétodoseatributosprivados)

Podemos criar um "contrato" que define tudo o que uma classe deve fazer se quiser ter umdeterminadostatus.Imagine:

contratoAutenticavel:

quemquiserserAutenticavelprecisasaberfazer:1.autenticardadaumasenha,devolvendoumbooleano

Quemquiser, pode "assinar" esse contrato, sendo assim obrigado a explicar como será feita essaautenticação.Avantageméque,seumGerenteassinaressecontrato,podemosnosreferenciaraum

GerentecomoumAutenticavel.

PodemoscriaressecontratoemJava!

publicinterfaceAutenticavel{

booleanautentica(intsenha);

}

Chama-seinterfacepoiséamaneirapelaqualpoderemosconversarcomumAutenticavel.

Interfaceéamaneiraatravésdaqualconversamoscomumobjeto.

Lemos a interface da seguinte maneira: "quem desejar ser autenticável precisa saber autenticardadouminteiroeretornandoumbooleano".Elaéumcontratoondequemassinaseresponsabilizaporimplementaressesmétodos(cumprirocontrato).

Uma interfacepodedefinirumasériedemétodos,masnuncaconter implementaçãodeles.Ela sóexpõeoqueoobjetodevefazer,enãocomoelefaz,nemoqueeletem.Comoelefazvaiserdefinidoemumaimplementaçãodessainterface.

EoGerentepode"assinar"ocontrato,ouseja,implementarainterface.Nomomentoemqueeleimplementaessainterface,eleprecisaescreverosmétodospedidospelainterface(muitoparecidocomoefeitodeherdarmétodosabstratos,aliás,métodosdeumainterfacesãopúblicoseabstratos,sempre).Paraimplementarusamosapalavrachaveimplementsnaclasse:

publicclassGerenteextendsFuncionarioimplementsAutenticavel{

privateintsenha;

//outrosatributosemétodos

publicbooleanautentica(intsenha){

152 11.2INTERFACES

Page 163: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

if(this.senha!=senha){returnfalse;}//podefazeroutraspossíveisverificações,comosaberseesse//departamentodogerentetemacessoaoSistema

returntrue;}

}

Oimplementspodeserlidodaseguintemaneira:"AclasseGerentesecomprometeasertratada

comoAutenticavel,sendoobrigadaaterosmétodosnecessários,definidosnestecontrato".

Apartirdeagora,podemostratarumGerentecomosendoumAutenticavel.Ganhamosmais

polimorfismo!TemosmaisumaformadereferenciaraumGerente.Quandocrioumavariáveldotipo

Autenticavel, estou criando uma referência paraqualquer objeto de uma classe que implementeAutenticavel,diretaouindiretamente:

Autenticavela=newGerente();//possoaquichamarométodoautentica!

Novamente, a utilização mais comum seria receber por argumento, como no nossoSistemaInterno:

publicclassSistemaInterno{

publicvoidlogin(Autenticavela){intsenha=//pegasenhadeumlugar,oudeumscannerdepolegarbooleanok=a.autentica(senha);

//aquieupossochamaroautentica!//nãonecessariamenteéumFuncionario!//Maisainda,eunãoseiqueobjetoa//referência"a"estáapontandoexatamente!Flexibilidade.}

11.2INTERFACES 153

Page 164: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

Pronto!EjápodemospassarqualquerAutenticavelparaoSistemaInterno.Entãoprecisamos

fazercomqueoDiretortambémimplementeessainterface.

publicclassDiretorextendsFuncionarioimplementsAutenticavel{

//métodoseatributos,alémdeobrigatoriamenteteroautentica

}

PodemospassarumDiretor.Nodiaemquetivermosmaisumfuncionáriocomacessoaosistema,

bastaqueeleimplementeessainterface,paraseencaixarnosistema.

QualquerAutenticavelpassadoparaoSistemaInternoestábomparanós.Reparequepouco

importa quem o objeto referenciado realmente é, pois ele tem um método autentica que é o

necessário para nosso SistemaInterno funcionar corretamente. Aliás, qualquer outra classe que

futuramenteimplementeessainterfacepoderáserpassadacomoargumentoaqui.

Autenticaveldiretor=newDiretor();Autenticavelgerente=newGerente();

Ou,seachamosqueoFornecedorprecisateracesso,bastaqueeleimplementeAutenticavel.

Olhesóotamanhododesacoplamento:quemescreveuoSistemaInternosóprecisasaberqueeleé

Autenticavel.

publicclassSistemaInterno{

publicvoidlogin(Autenticavela){//nãoimportaseeleéumgerenteoudiretor//seráqueéumfornecedor?//Eu,oprogramadordoSistemaInterno,nãomepreocupo//Invocareiométodoautentica}

}

154 11.2INTERFACES

Page 165: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

NãofazdiferençaseéumDiretor,Gerente,Cliente ouqualquer classequevenhapor aí.

Basta seguir o contrato! Mais ainda, cada Autenticavel pode se autenticar de uma maneira

completamentediferentedeoutro.

Lembre-se: a interface define que todos vão saber se autenticar (o que ele faz), enquanto aimplementaçãodefinecomoexatamentevaiserfeito(comoelefaz).

Amaneiracomoosobjetossecomunicamnumsistemaorientadoaobjetosémuitomaisimportantedoquecomoelesexecutam.Oqueumobjetofazémaisimportantedoquecomoelefaz.Aquelesqueseguemessaregra,terãosistemasmaisfáceisdemanteremodificar.Comovocêjápercebeu,estaéumadasideiasprincipaisquequeremospassare,provavelmente,amaisimportantedetodoessecurso.

MAISSOBREINTERFACES:HERANÇAEMÉTODOSDEFAULT

Diferentementedasclasses,umainterfacepodeherdardemaisdeumainterface.Écomoumcontrato que depende que outros contratos sejam fechados antes deste valer. Você não herdamétodoseatributos,massimresponsabilidades.

Um outro recurso em interfaces são os métodos default a partir do Java 8. Você pode simdeclararummétodoconcreto,utilizandoapalavradefaultaolado,esuasimplementaçõesnão

precisamnecessariamente reescrevê-lo.Veremosque isso acontece, por exemplo, comométodoList.sort,duranteocapítulodecoleções.Éumtruquemuitoutilizadoparapoderevoluiruma

interfacesemquebrarcompatibilidadecomasimplementaçõesanteriores.

Interfaces representam uma barreira no aprendizado do Java: parece que estamos escrevendo umcódigoquenãoservepranada, jáque teremosessa linha (aassinaturadométodo)escritanasnossasclassesimplementadoras.Essaéumamaneiraerradadesepensar.Oobjetivodousodeumainterfaceédeixarseucódigomaisflexívelepossibilitaramudançadeimplementaçãosemmaiorestraumas.Nãoéapenasumcódigodeprototipação,umcabeçalho!

Osmais radicais dizem que toda classe deve ser "interfaceada", isto é, só devemos nos referir aobjetos através de suas interfaces. Se determinada classe não tem uma interface, ela deveria ter. Osautoresdestematerialachamtalmedidaradicaldemais,porémousodeinterfacesemvezdeherançaéamplamente aconselhado. Você pode encontrar mais informações sobre o assunto nos livrosDesignPatterns,RefactoringeEffectiveJava.

NolivroDesignPatterns,logonoinício,osautorescitam2regras"deouro".Umaé"eviteherança,prefiracomposição"eaoutra,"programevoltadoainterfaceenãoàimplementação".

11.3DIFICULDADENOAPRENDIZADODEINTERFACES

11.3DIFICULDADENOAPRENDIZADODEINTERFACES 155

Page 166: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Veremosousodeinterfacesnocapítulodecoleções,oquemelhoraoentendimentodoassunto.OexemplodainterfaceComparabletambémémuitoesclarecedor,ondeenxergamosoreaproveitamento

de código através das interfaces, além do encapsulamento. Para o método Collections.sort() ,

pouco importa quem vai ser passado como argumento. Para ele, basta que a coleção seja de objetoscomparáveis.ElepodeordenarElefante,ConexaoouContaCorrente, desdeque implementem

Comparable.

Comofazercomquetodasaschamadasparabancosdedadosdiferentesrespeitemamesmaregra?Usandointerfaces!

ImagineumainterfaceConexaocontendotodososmétodosnecessáriosparaacomunicaçãoetroca

dedadoscomumbancodedados.Cadabancodedadosficaencarregadodecriarasuaimplementaçãoparaessainterface.

QuemforusarumaConexaonãoprecisaseimportarcomqualobjetoexatamenteestátrabalhando,

jáqueelevaicumpriropapelque todaConexao deve ter.Não importa se éumaconexãocomum

OracleouMySQL.

Apesar do java.sql.Connection não trabalhar bem assim, a ideia é muito similar, porém as

conexõesvêmdeumafactorychamadaDriverManager.

Conexãoabancodedadosestáforadoescopodessetreinamento,maséumdosprimeirostópicosabordadosnocursoFJ-21,juntamentecomDAO.

11.4 EXEMPLO INTERESSANTE: CONEXÕES COM O BANCO DEDADOS

156 11.4EXEMPLOINTERESSANTE:CONEXÕESCOMOBANCODEDADOS

Page 167: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

UMPOUCOMAIS...

Possosubstituirtodaminhaherançaporinterfaces?Qualéavantagemeadesvantagem?

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. Nossobancoprecisatributardinheirodealgunsbensquenossosclientespossuem.Paraissovamoscriarumainterfacenopacotebr.com.caelum.contas.modelodonossoprojetofj11-contasjá

existente:

publicinterfaceTributavel{publicdoublegetValorImposto();}

Lemos essa interface da seguinte maneira: "todos que quiserem ser tributável precisam saberretornarovalordoimposto,devolvendoumdouble".

Alguns bens são tributáveis e outros não, ContaPoupanca não é tributável, já para

ContaCorrentevocêprecisapagar1%dacontaeoSeguroDeVidatemumataxafixade42reais

mais2%dovalordoseguro.

AproveiteoEclipse!QuandovocêescreverimplementsTributavelnaclasseContaCorrente,

o quick fix do Eclipse vai sugerir que você reescreva o método; escolha essa opção e, depois,preenchaocorpodométodoadequadamente:

publicclassContaCorrenteextendsContaimplementsTributavel{

//outrosatributosemétodos

publicdoublegetValorImposto(){

JáconheceoscursosonlineAlura?

11.5EXERCÍCIOS:INTERFACES

11.5EXERCÍCIOS:INTERFACES 157

Page 168: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

returnthis.getSaldo()*0.01;}}

CrieaclasseSeguroDeVida,aproveitandonovamentedoEclipse,paraobter:

publicclassSeguroDeVidaimplementsTributavel{privatedoublevalor;privateStringtitular;privateintnumeroApolice;

publicdoublegetValorImposto(){return42+this.valor*0.02;}

//gettersesettersparaosatributos}

Alémdisso,escrevaométodogetTipoparaqueotipodoprodutoapareçanainterfacegráfica:

publicStringgetTipo(){return"SegurodeVida";}

2. Vamos criar a classeManipuladorDeSeguroDeVida dentro do pacote br.com.caelum.contas

paravincularaclasseSeguroDeVida coma tela de criaçãode seguros.Esta classe deve ter um

atributodotipoSeguroDeVida.

Crie também o método criaSeguro que deve receber um parâmetro do tipo Evento para

conseguirobterosdadosda tela.Vocêdevepegarosparâmetros"numeroApolice"do tipoint,

"titular"dotipoStringe"valor"dotipodouble.

Ocódigofinaldeveficarparecidocomocódigoabaixo:

packagebr.com.caelum.contas;

importbr.com.caelum.contas.modelo.SeguroDeVida;importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeSeguroDeVida{

privateSeguroDeVidaseguroDeVida;

publicvoidcriaSeguro(Eventoevento){this.seguroDeVida=newSeguroDeVida();this.seguroDeVida.setNumeroApolice(evento.getInt("numeroApolice"));this.seguroDeVida.setTitular(evento.getString("titular"));this.seguroDeVida.setValor(evento.getDouble("valor"));}}

3. ExecuteaclasseTestaContasetentecadastrarumnovosegurodevida.Osegurocadastradodeve

aparecernatabeladesegurosdevida.

4. Queremosagorasaberqualovalortotaldosimpostosdetodosostributáveis.Vamosentãocriara

158 11.5EXERCÍCIOS:INTERFACES

Page 169: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

classeManipuladorDeTributaveis dentrodopacotebr.com.caelum.contas.Crie tambémo

métodocalculaImpostosquerecebeumparâmetrodotipoEvento:

packagebr.com.caelum.contas;

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeTributaveis{

publicvoidcalculaImpostos(Eventoevento){//aquicalcularemosototal}}

5. Agora que criamos o tributavel, vamos habilitar a última aba de nosso sistema. Altere a classeTestaContasparapassarovalortruenachamadadométodomostraTela.Observequeagora

que temos o seguro de vida funcionando, a tela de relatório já consegue imprimir o valor dosimpostosindividuaisdecadatipodeTributavel.

6. NométodocalculaImpostosprecisamosbuscarosvaloresdeimpostosdecadaTributavele

somá-los. Para saber a quantidade de tributáveis, a classe Evento possui ummétodo chamado

getTamanhoDaListaquedevereceberonomedalistadesejada,nocaso"listaTributaveis".Existe

tambémumoutrométodoqueretornaumTributaveldeumadeterminadaposiçãodeumalista,

ondeprecisamospassaronomedalistaeoíndicedoelemento.Precisamospercorreralistainteira,passandoporcadaposiçãoentãoutilizaremosumforparaisto.

packagebr.com.caelum.contas;

importbr.com.caelum.contas.modelo.Tributavel;importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeTributaveis{

privatedoubletotal;

publicvoidcalculaImpostos(Eventoevento){total=0;inttamanho=evento.getTamanhoDaLista("listaTributaveis");for(inti=0;i<tamanho;i++){Tributavelt=evento.getTributavel("listaTributaveis",i);total+=t.getValorImposto();}}

publicdoublegetTotal(){returntotal;}}

Repare que, de dentro do ManipuladorDeTributaveis , você não pode acessar o método

getSaldo,porexemplo,poisvocênãotemagarantiadequeoTributavelquevaiserpassado

como argumento tem esse método. A única certeza que você tem é de que esse objeto tem os

11.5EXERCÍCIOS:INTERFACES 159

Page 170: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

métodosdeclaradosnainterfaceTributavel.

Éinteressanteenxergarqueasinterfaces(comoaqui,nocaso,Tributavel)costumamligarclasses

muito distintas, unindo-as por uma característica que elas tem em comum. No nosso exemplo,SeguroDeVidaeContaCorrentesãoentidadescompletamentedistintas,porémambaspossuema

característicadeseremtributáveis.

SeamanhãogovernocomeçaratributaratémesmoPlanoDeCapitalizacao,bastaqueessaclasse

implemente a interface Tributavel! Repare no grau de desacoplamento que temos: a classe

GerenciadorDeImpostoDeRendanemimaginaquevaitrabalharcomoPlanoDeCapitalizacao.

Para ela, o único fato que importa é que o objeto respeite o contrato de um tributável, isso é, ainterfaceTributavel.Novamente:programevoltadoàinterface,nãoàimplementação.

Quaisosbenefíciosdemanterocódigocombaixoacoplamento?

7. (opcional)CrieaclasseTestaTributavelcomummétodomainparatestaronossoexemplo:

publicclassTestaTributavel{

publicstaticvoidmain(String[]args){ContaCorrentecc=newContaCorrente();cc.deposita(100);System.out.println(cc.getValorImposto());

//testandopolimorfismo:Tributavelt=cc;System.out.println(t.getValorImposto());}}

TentechamarométodogetSaldoatravésdareferênciat,oqueocorre?Porquê?

AlinhaemqueatribuímosccaumTributaveléapenasparavocêenxergarqueépossívelfazê-

lo.Nessenossocaso,issonãotemumautilidade.Essapossibilidadefoiútilnoexercícioanterior.

Atenção: casovocê faça esse exercício, faça issonumprojeto à parteconta-interface já que

usaremosaContacomoclasseemexercíciosfuturos.

1. (Opcional)TransformeaclasseContaemumainterface.

publicinterfaceConta{publicdoublegetSaldo();publicvoiddeposita(doublevalor);publicvoidsaca(doublevalor);publicvoidatualiza(doubletaxaSelic);}

11.6EXERCÍCIOSOPCIONAIS

160 11.6EXERCÍCIOSOPCIONAIS

Page 171: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AdapteContaCorrenteeContaPoupancaparaessamodificação:

publicclassContaCorrenteimplementsConta{//...}

publicclassContaPoupancaimplementsConta{//...}

Algumcódigovaiterdesercopiadoecolado?Issoétãoruim?

2. (Opcional)Àsvezes,éinteressantecriarmosumainterfacequeherdadeoutrasinterfaces:essas,sãochamadassubinterfaces.Essas,nadamaissãodoqueumagrupamentodeobrigaçõesparaaclassequeaimplementar.

publicinterfaceContaTributavelextendsConta,Tributavel{}

Dessamaneira, quem for implementar essa nova interface precisa implementar todos osmétodosherdadosdassuassuperinterfaces(etalvezaindanovosmétodosdeclaradosdentrodela):

publicclassContaCorrenteimplementsContaTributavel{//métodos}

Contac=newContaCorrente();Tributavelt=newContaCorrente();

Reparequeocódigopodeparecerestranho,poisainterfacenãodeclaramétodoalgum,sóherdaosmétodosabstratosdeclaradosnasoutrasinterfaces.

Aomesmotempoqueumainterfacepodeherdardemaisdeumaoutrainterface,classessópodempossuirumaclassemãe(herançasimples).

Discuta com o instrutor e seus colegas, alternativas à herança. Falaremos de herança versuscomposiçãoeporquêaherançaémuitasvezesconsideradamaléfica.

Numaentrevista,JamesGosling,"paidojava",falasobreumalinguagempuramentededelegaçãoechegaadizer:

Rather than subclassing, just use pure interfaces. It's not so much that class inheritance isparticularlybad.Itjusthasproblems.

(Traduçãolivre:"Emvezdefazersubclasses,usesimplesmenteinterfaces.Nãoéqueaherançadeclassessejaparticularmenteruim.Elasótemproblemas.")

11.7 DISCUSSÃO: FAVOREÇA COMPOSIÇÃO EM RELAÇÃO ÀHERANÇA

11.7DISCUSSÃO:FAVOREÇACOMPOSIÇÃOEMRELAÇÃOÀHERANÇA 161

Page 172: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

http://www.artima.com/intv/gosling3P.html

No blog da Caelum há também um post sobre o assunto:http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

162 11.7DISCUSSÃO:FAVOREÇACOMPOSIÇÃOEMRELAÇÃOÀHERANÇA

Page 173: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO12

"Quempensapouco,erramuito"--LeonardodaVinci

Aotérminodessecapítulo,vocêserácapazde:

controlarerrosetomardecisõesbaseadasnosmesmos;criarnovostiposdeerrosparamelhorarotratamentodelesemsuaaplicaçãooubiblioteca;assegurarqueummétodofuncionoucomodizemseu"contrato".

VoltandoàsContasquecriamosnocapítulo6,oqueaconteceriaaotentarchamarométodosaca

comumvalorforadolimite?Osistemamostrariaumamensagemdeerro,masquemchamouométodosacanãosaberáqueissoaconteceu.

Comoavisaraquelequechamouométododequeelenãoconseguiufazeraquiloquedeveria?

Em Java, osmétodos dizem qual o contrato que eles devem seguir. Se, ao tentar sacar, ele nãoconseguefazeroquedeveria,eleprecisa,aomenos,avisaraousuárioqueosaquenãofoifeito.

Vejanoexemploabaixo:estamosforçandoumaContaaterumvalornegativo,istoé,estarnum

estadoinconsistentedeacordocomanossamodelagem.

ContaminhaConta=newConta();minhaConta.deposita(100);minhaConta.setLimite(100);minhaConta.saca(1000);//osaldoé-900?É100?É0?Achamadaaométodosacafuncionou?

Em sistemas de verdade, é muito comum que quem saiba tratar o erro é aquele que chamou ométodoenãoaprópriaclasse!Portanto,nadamaisnaturaldoqueaclassesinalizarqueumerroocorreu.

A solução mais simples utilizada antigamente é a de marcar o retorno de um método comobooleaneretornartrue,setudoocorreudamaneiraplanejada,oufalse,casocontrário:

booleansaca(doublequantidade){//possosacaratésaldo+limiteif(quantidade>this.saldo+this.limite){System.out.println("Nãopossosacarforadolimite!");returnfalse;}else{

EXCEÇÕESECONTROLEDEERROS

12.1MOTIVAÇÃO

12EXCEÇÕESECONTROLEDEERROS 163

Page 174: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

this.saldo=this.saldo-quantidade;returntrue;}}

Umnovoexemplodechamadaaométodoacima:

ContaminhaConta=newConta();minhaConta.deposita(100);minhaConta.setLimite(100);if(!minhaConta.saca(1000)){System.out.println("Nãosaquei");}

Reparequetivemosdelembrardetestaroretornodométodo,masnãosomosobrigadosafazerisso.Esquecerdetestaroretornodessemétodoteriaconsequênciasdrásticas:amáquinadeautoatendimentopoderiaviraliberaraquantiadesejadadedinheiro,mesmoqueosistemanãotivesseconseguidoefetuarométodosacacomsucesso,comonoexemploaseguir:

ContaminhaConta=newConta();minhaConta.deposita(100);

//...doublevalor=5000;minhaConta.saca(valor);//vairetornarfalse,masninguémverifica!caixaEletronico.emite(valor);

Mesmo invocando o método e tratando o retorno de maneira correta, o que faríamos se fossenecessáriosinalizarquandoousuáriopassouumvalornegativocomoquantidade?Umasoluçãoseriaalteraroretornodebooleanparainte retornarocódigodoerroqueocorreu. Issoéconsiderado

umamáprática(conhecidatambémcomousode"magicnumbers").

Alémdevocêperderoretornodométodo,ovalordevolvidoé"mágico"esólegívelperanteextensadocumentação,alémdenãoobrigaroprogramadoratrataresseretornoe,nocasodeesquecerisso,seuprogramacontinuarárodandojánumestadoinconsistente.

Repareoqueaconteceriasefossenecessárioretornarumoutrovalor.Oexemploabaixomostraumcasoonde, atravésdo retorno, não serápossível descobrir seocorreuumerroounão, poisométodoretornaumcliente.

publicClienteprocuraCliente(intid){if(idInvalido){//avisaométodoquechamouestequeocorreuumerro}else{Clientecliente=newCliente();cliente.setId(id);//cliente.setNome("nomedocliente");returncliente;}}

Poresseseoutrosmotivos,utilizamosumcódigodiferenteemJavaparatrataraquiloquechamamosde exceções: os casos onde acontece algo que, normalmente, não iria acontecer. O exemplo do

164 12.1MOTIVAÇÃO

Page 175: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

argumentodosaqueinválidooudoidinválidodeumclienteéumaexceçãoàregra.

EXCEÇÃO

Uma exceção representa uma situação que normalmente não ocorre e representa algo deestranhoouinesperadonosistema.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Antesderesolvermosonossoproblema,vamosvercomoaJavaVirtualMachineageaosedepararcomsituaçõesinesperadas,comodivisãoporzeroouacessoaumíndicedaarrayquenãoexiste.

1. ParaaprendermososconceitosbásicosdasexceptionsdoJava,testeoseguintecódigovocêmesmo:

classTesteErro{publicstaticvoidmain(String[]args){System.out.println("iniciodomain");metodo1();System.out.println("fimdomain");}

staticvoidmetodo1(){System.out.println("iniciodometodo1");metodo2();System.out.println("fimdometodo1");}

staticvoidmetodo2(){System.out.println("iniciodometodo2");ContaCorrentecc=newContaCorrente();for(inti=0;i<=15;i++){cc.deposita(i+1000);

Seuslivrosdetecnologiaparecemdoséculopassado?

12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS

12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS 165

Page 176: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out.println(cc.getSaldo());if(i==5){cc=null;}}System.out.println("fimdometodo2");}}

Repareométodomainchamandometodo1eesse,porsuavez,chamandoometodo2.Cadaum

dessesmétodospodetersuasprópriasvariáveislocais,istoé:ometodo1nãoenxergaasvariáveis

declaradasdentrodomaineporaíemdiante.

ComooJava(emuitasdasoutraslinguagens)fazisso?Todainvocaçãodemétodoéempilhadaemuma estrutura de dados que isola a área de memória de cada um. Quando um método termina(retorna),elevoltaparaométodoqueo invocou.Eledescobre issoatravésdapilhade execução(stack):bastaremoveromarcadorqueestánotopodapilha:

Porém, o nosso metodo2 propositadamente possui um enorme problema: está acessando uma

referêncianulaquandooíndiceforiguala6!

Rodeocódigo.Qualéasaída?Oqueissorepresenta?Oqueelaindica?

Essa saída é o conhecido rastro da pilha (stacktrace). É uma saída importantíssima para oprogramador - tanto que, em qualquer fórum ou lista de discussão, é comum os programadoresenviarem,juntamentecomadescriçãodoproblema,essastacktrace.Masporqueissoaconteceu?

O sistema de exceções do Java funciona da seguinte maneira: quando uma exceção é lançada(throw), a JVMentra emestadode alerta evai ver seométodo atual tomaalgumaprecaução aotentarexecutaressetrechodecódigo.Comopodemosver,ometodo2nãotomanenhumamedida

166 12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS

Page 177: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

diferentedoquevimosatéagora.

Comoometodo2nãoestá tratandoesseproblema,aJVMpáraaexecuçãodeleanormalmente,

sem esperar ele terminar, e volta um stackframe pra baixo, onde será feita nova verificação: "ometodo1estáseprecavendodeumproblemachamadoNullPointerException?""Não..."Volta

paraomain,ondetambémnãoháproteção,entãoaJVMmorre(naverdade,quemmorreéapenas

a Thread corrente; se quiser saber mais sobre, há um apêndice de Threads e Programação

Concorrentenofinaldaapostila).

Obviamente,aquiestamosforçandoessecasoenãofariasentidotomarmoscuidadocomele.Éfácilarrumar um problema desses: basta verificar antes de chamar osmétodos se a variável está comreferêncianula.

Porém,apenasparaentenderocontroledefluxodeumaException,vamoscolocarocódigoque

vaitentar(try)executaroblocoperigosoe,casooproblemasejadotipoNullPointerException,eleserápego(caught).ReparequeéinteressantequecadaexceçãonoJavatenhaumtipo...elapodeteratributosemétodos.

2. Adicioneumtry/catchemvoltadofor,pegandoNullPointerException.Oqueo código

imprime?

try{for(inti=0;i<=15;i++){cc.deposita(i+1000);System.out.println(cc.getSaldo());if(i==5){cc=null;}}}catch(NullPointerExceptione){System.out.println("erro:"+e);}

12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS 167

Page 178: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

3. Emvezdefazerotryemtornodoforinteiro,tenteapenascomoblocodedentrodofor:

for(inti=0;i<=15;i++){try{cc.deposita(i+1000);System.out.println(cc.getSaldo());if(i==5){cc=null;}}catch(NullPointerExceptione){System.out.println("erro:"+e);}}

Qualéadiferença?

4. Retireotry/catchecoloqueeleemvoltadachamadadometodo2.

System.out.println("iniciodometodo1");try{metodo2();}catch(NullPointerExceptione){System.out.println("erro:"+e);}System.out.println("fimdometodo1");

168 12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS

Page 179: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

5. Façaomesmo,retirandootry/catchnovamenteecolocandoemvoltadachamadadometodo1.

Rodeoscódigos,oqueacontece?

System.out.println("iniciodomain");try{metodo1();}catch(NullPointerExceptione){System.out.println("erro:"+e);}System.out.println("fimdomain");

Repareque,apartirdomomentoqueumaexceptionfoicatched(pega,tratada,handled),aexecuçãovoltaaonormalapartirdaqueleponto.

12.3EXCEÇÕESDERUNTIMEMAISCOMUNS

12.3EXCEÇÕESDERUNTIMEMAISCOMUNS 169

Page 180: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Quetaltentardividirumnúmeroporzero?SeráqueaJVMconseguefazeraquiloquenósdefinimosquenãoexiste?

publicclassTestandoADivisao{

publicstaticvoidmain(String[]args){inti=5571;i=i/0;System.out.println("Oresultado"+i);}}

Tenteexecutaroprogramaacima.Oqueacontece?

ReparequeumNullPointerExceptionpoderiaserfacilmenteevitadocomumifquechecaria

seareferênciaédiferentedenull.

Outrocasoemquetambémocorretaltipodeexceçãoéquandoumcasterradoéfeito(veremosmaisprafrente).Emtodososcasos,taisproblemasprovavelmentepoderiamserevitadospeloprogramador.É por esse motivo que o java não te obriga a dar o try/catch nessas exceptions e chamamos essasexceções de unchecked. Em outras palavras, o compilador não checa se você está tratando essasexceções.

ERROS

OserrosemJava sãoum tipodeexceçãoque tambémpodemser tratados.Eles representamproblemasnamáquinavirtualenãodevemsertratadosem99%doscasos,jáqueprovavelmenteomelhorasefazerédeixaraJVMencerrar(ouapenasaThreademquestão).

Ficaclaro,comosexemplosdecódigoacima,quenãoénecessáriodeclararquevocêestátentandofazeralgoondeumerropossaocorrer.Osdoisexemplos,comousemotry/catch, compilarame

rodaram.Emum,oerroterminouoprogramae,nooutro,foipossíveltratá-lo.

Mas não é só esse tipo de exceção que existe em Java. Um outro tipo, obriga a quem chama ométodo ou construtor a tratar essa exceção. Chamamos esse tipo de exceção de checked, pois ocompilador checará se ela está sendo devidamente tratada, diferente das anteriores, conhecidas como

12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS

170 12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS

Page 181: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

unchecked.

Umexemplointeressanteéodeabrirumarquivoparaleitura,ondepodeocorreroerrodoarquivonãoexistir(veremoscomotrabalharcomarquivosemoutrocapítulo,nãosepreocupecomistoagora):

classTeste{publicstaticvoidmetodo(){newjava.io.FileInputStream("arquivo.txt");}}

O código acima não compila e o compilador avisa que é necessário tratar oFileNotFoundExceptionquepodeocorrer:

Paracompilarefazeroprogramafuncionar,temosduasmaneirasquepodemostrataroproblema.Oprimeiro,étratá-locomotryecatchdomesmojeitoqueusamosnoexemploanterior,dereferência

nula:

publicstaticvoidmetodo(){

try{newjava.io.FileInputStream("arquivo.txt");}catch(java.io.FileNotFoundExceptione){System.out.println("Naofoipossívelabriroarquivoparaleitura");}

}

Asegundaformadetrataresseerro,édelegareleparaquemchamouonossométodo,istoé,passarparaafrente.

publicstaticvoidmetodo()throwsjava.io.FileNotFoundException{

newjava.io.FileInputStream("arquivo.txt");

}

NoEclipseébemsimplesfazertantoumtry/catchcomoumthrows:

Tentedigitaressecódigonoeclipse:

publicclassTestaException{publicstaticvoidmain(String[]args){newjava.io.FileInputStream("arquivo.txt");}}

OEclipsevaireclamar:

12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS 171

Page 182: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Evocêtemduasopções:

Addthrowsdeclaration,quevaigerar:

publicclassTestaException{publicstaticvoidmain(String[]args)throwsFileNotFoundException{newjava.io.FileInputStream("arquivo.txt");}}

Surroundwithtry/catch,quevaigerar:

publicclassTestaException2{publicstaticvoidmain(String[]args){try{newjava.io.FileInputStream("arquivo.txt");}catch(FileNotFoundExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

Noinício,existeumagrandetentaçãodesemprepassaroproblemaprafrenteparaoutrosotratarem.Podeserquefaçasentido,dependendodocaso,masnãoatéomain,porexemplo.Acontecequequemtenta abrir um arquivo sabe como lidar com um problema na leitura. Quem chamou ummétodo nocomeçodoprogramapodenãosaberou,piorainda, tentarabrircincoarquivosdiferentesenãosaberqualdelesteveumproblema!

Não há uma regra para decidir em que momento do seu programa você vai tratar determinadaexceção. Isso vai depender de em que ponto você tem condições de tomar uma decisão em relaçãoàqueleerro.Enquantonãoforomomento,vocêprovavelmentevaipreferirdelegararesponsabilidadeparaométodoqueteinvocou.

172 12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS

Page 183: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

BOASPRÁTICASNOTRATAMENTODEEXCEÇÕES

NoblogdaCaelumháumextensoartigodiscutindoasboaspráticasemrelaçãoaotratamentodeexceções.

http://blog.caelum.com.br/2006/10/07/lidando-com-exceptions/

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

UmapequenapartedaFamíliaThrowable:

Agoraéamelhorhoradeaprenderalgonovo

12.5UMPOUCODAGRANDEFAMÍLIATHROWABLE

12.5UMPOUCODAGRANDEFAMÍLIATHROWABLE 173

Page 184: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Épossíveltratarmaisdeumerroquasequeaomesmotempo:

Comotryecatch:

try{objeto.metodoQuePodeLancarIOeSQLException();}catch(IOExceptione){//..}catch(SQLExceptione){//..}

Comothrows:

publicvoidabre(Stringarquivo)throwsIOException,SQLException{//..}

Vocêpode,também,escolhertrataralgumasexceçõesedeclararasoutrasnothrows:

publicvoidabre(Stringarquivo)throwsIOException{try{objeto.metodoQuePodeLancarIOeSQLException();}catch(SQLExceptione){//..}}

É desnecessário declarar no throws as exceptions que são unchecked, porém é permitido e às

vezes,facilitaaleituraeadocumentaçãodoseucódigo.

Lembre-sedométodosacadanossaclasseConta.Eledevolveumboolean casoconsigaou

nãosacar:

publicbooleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo-=valor;returntrue;}}

Podemos,também,lançarumaException,oqueéextremamenteútil.Dessamaneira,resolvemos

oproblemadealguémpoderesquecerdefazerumifnoretornodeummétodo.

Apalavrachave throw, que está no imperativo, lançaumaException. Isto é bemdiferente dethrows,queestánopresentedoindicativo,equeapenasavisadapossibilidadedaquelemétodolançá-

la,obrigandoooutrométodoqueváutilizardestedesepreocuparcomessaexceçãoemquestão.

12.6MAISDEUMERRO

12.7LANÇANDOEXCEÇÕES

174 12.6MAISDEUMERRO

Page 185: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewRuntimeException();}else{this.saldo-=valor;}}

Nonossocaso, lançaumadotipounchecked.RuntimeExceptionéaexceptionmãede todasas

exceptionsunchecked.Adesvantagem, aqui, é que ela émuito genérica; quem receber esse erro nãosabedizerexatamentequalfoioproblema.PodemosentãousarumaExceptionmaisespecífica:

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewIllegalArgumentException();}else{this.saldo-=valor;}}

IllegalArgumentExceptiondizumpoucomais:algofoipassadocomoargumentoeseumétodo

não gostou. Ela é uma Exception unchecked pois estende de RuntimeException e já faz parte da

bibliotecadojava.(IllegalArgumentExceptionéamelhorescolhaquandoumargumentosempreé

inválidocomo,porexemplo,númerosnegativos,referênciasnulas,etc).

Parapegaresseerro,nãousaremosumif/elseesimumtry/catch,porquefazmaissentidojá

queafaltadesaldoéumaexceção:

Contacc=newContaCorrente();cc.deposita(100);

try{cc.saca(100);}catch(IllegalArgumentExceptione){System.out.println("SaldoInsuficiente");}

PodíamosmelhoraraindamaisepassarparaoconstrutordaIllegalArgumentExceptionomotivo

daexceção:

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewIllegalArgumentException("Saldoinsuficiente");}else{this.saldo-=valor;}}

Ométodo getMessage() definido na classe Throwable (mãe de todos os tipos de erros e

exceptions)vairetornaramensagemquepassamosaoconstrutordaIllegalArgumentException.

try{cc.saca(100);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());

12.7LANÇANDOEXCEÇÕES 175

Page 186: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Imaginequevamossacardinheirodediversascontas:

Contacc=newContaCorrente();cc.deposita(100);

Contacp=newContaPoupanca();cp.deposita(100);

//sacandodascontas:

cc.saca(50);System.out.println("conseguisacardacorrente!");

cp.saca(50);System.out.println("conseguisacardapoupança!");

Podemosescolhervárioslugaresparacolocartry/catch:

try{cc.saca(50);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}System.out.println("conseguisacardacorrente!");

try{cp.saca(50);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}System.out.println("conseguisacardapoupança!");

Essa não parece umaopção boa, pois amensagem "consegui sacar" será impressamesmo que ocatchsejaacionado.Semprequetemosalgoquedependedalinhadecimaparasercorreto,devemos

EditoraCasadoCódigocomlivrosdeumaformadiferente

12.8OQUECOLOCARDENTRODOTRY?

176 12.8OQUECOLOCARDENTRODOTRY?

Page 187: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

agrupá-lonotry:

try{cc.saca(50);System.out.println("conseguisacardacorrente!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

try{cp.saca(50);System.out.println("conseguisacardapoupança!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Mas há ainda uma outra opção: imagine que, para o nosso sistema, uma falha ao sacar da contapoupançadevepararoprocessodesaquesenemtentarsacardacontacorrente.Paraisso,agruparíamosmaisainda:

try{cc.saca(50);System.out.println("conseguisacardacorrente!");cp.saca(50);System.out.println("conseguisacardapoupança!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Oquevocêvaicolocardentrodotryinfluenciamuitoaexecuçãodoprograma!Pensedireitonaslinhasquedependemumadaoutraparaaexecuçãocorretadasualógicadenegócios.

Ébemcomumcriarumaprópriaclassedeexceçãoparacontrolarmelhorousodesuasexceções.Dessamaneira,podemospassarvaloresespecíficosparaelacarregar,quesejamúteisdealgumaforma.Vamoscriaranossa:

Voltamos para o exemplo das Contas , vamos criar a nossa Exceção de

SaldoInsuficienteException:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Emvezde lançar umIllegalArgumentException, vamos lançar nossaprópria exception, com

umamensagemquedirá"SaldoInsuficiente":

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewSaldoInsuficienteException("SaldoInsuficiente,"+

12.9CRIANDOSEUPRÓPRIOTIPODEEXCEÇÃO

12.9CRIANDOSEUPRÓPRIOTIPODEEXCEÇÃO 177

Page 188: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

"tenteumvalormenor");}else{this.saldo-=valor;}}

E,paratestar,crieumaclassequedepositeumvaloretentesacarumvalormaior:

publicstaticvoidmain(String[]args){Contacc=newContaCorrente();cc.deposita(10);

try{cc.saca(100);}catch(SaldoInsuficienteExceptione){System.out.println(e.getMessage());}}

PodemostransformaressaExceptiondeuncheckedparachecked,obrigandoaquemchamaesse

métodoadartry-catch,outhrows:

publicclassSaldoInsuficienteExceptionextendsException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Osblocostryecatchpodemconterumaterceiracláusulachamadafinallyqueindicaoque

deveserfeitoapósotérminodoblocotryoudeumcatchqualquer.

É interessante colocar algo que é imprescindível de ser executado, caso o que você queria fazertenhadadocerto,ounão.Ocasomaiscomuméodeliberarumrecursonofinally,comoumarquivoouconexãocombancodedados,paraquepossamosteracertezadequeaquelearquivo(ouconexão)váserfechado,mesmoquealgotenhafalhadonodecorrerdocódigo.

Noexemploaseguir,oblocofinallyserásempreexecutado,independentementedetudoocorrer

bemoudeaconteceralgumproblema:

try{//blocotry}catch(IOExceptionex){//blococatch1}catch(SQLExceptionsqlex){//blococatch2}finally{//blocoqueserásempreexecutado,independente//sehouveounãoexceptioneseelafoitratadaounão}

Há também, no Java 7, um recurso poderoso conhecido como try-with-resources, que permite

12.10PARASABERMAIS:FINALLY

178 12.10PARASABERMAIS:FINALLY

Page 189: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

utilizarasemânticadofinallydeumamaneirabemmaissimples.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. Na classeConta,modifique ométododeposita(doublex): Ele deve lançar uma exception

chamadaIllegalArgumentException,quejáfazpartedabibliotecadoJava,semprequeovalor

passadocomoargumentoforinválido(porexemplo,quandofornegativo).

publicvoiddeposita(doublevalor){if(valor<0){thrownewIllegalArgumentException();}else{this.saldo+=valor;}}

2. Rodeaaplicação,cadastreumacontaetentedepositarumvalornegativo.Oqueacontece?

3. Ao lançar a IllegalArgumentException, passe via construtor uma mensagem a ser exibida.

LembrequeaStringrecebidacomoparâmetroéacessíveldepoisviaométodogetMessage()

herdadoportodasasExceptions.

publicvoiddeposita(doublevalor){if(valor<0){thrownewIllegalArgumentException("Vocêtentoudepositar"+"umvalornegativo");}else{this.saldo+=valor;}}

Rodeaaplicaçãonovamenteevejaqueagoraamensagemaparecenatela.

4. FaçaomesmoparaométodosacadaclasseContaCorrente,afinaloclientetambémnãopode

JáconheceoscursosonlineAlura?

12.11EXERCÍCIOS:EXCEÇÕES

12.11EXERCÍCIOS:EXCEÇÕES 179

Page 190: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

sacarumvalornegativo!

5. Vamosvalidartambémqueoclientenãopodesacarumvalormaiordoqueosaldodisponívelemconta.CriesuaprópriaException,SaldoInsuficienteException.Paraisso,vocêprecisacriar

umaclassecomessenomequesejafilhadeRuntimeException.

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

}

NométodosacadaclasseContaCorrentevamosutilizarestanovaException:

@Overridepublicvoidsaca(doublevalor){if(valor<0){thrownewIllegalArgumentException("Vocêtentousacarumvalornegativo");}if(this.saldo<valor){thrownewSaldoInsuficienteException();}this.saldo-=(valor+0.10);}

Atenção:nemsempreéinteressantecriarmosumnovotipodeexception!Dependedocaso.Nesteaqui,seriamelhoraindautilizarmosIllegalArgumentException.Aboapráticadizquedevemos

preferirusarasjáexistentesdoJavasemprequepossível.

6. (opcional)ColoqueumconstrutornaclasseSaldoInsuficienteExceptionquerecebaovalorque

eletentousacar(istoé,elevaireceberumdoublevalor).

Quandoestendemosumaclasse,nãoherdamosseusconstrutores,maspodemosacessá-losatravésdapalavra chave super de dentro de um construtor. As exceções do Java possuem uma série de

construtores úteis para poder populá-las já com uma mensagem de erro. Então vamos criar umconstrutoremSaldoInsuficienteExceptionquedelegueparaoconstrutordesuamãe.Essavai

guardaressamensagemparapodermostrá-laaoserinvocadoométodogetMessage:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(doublevalor){super("Saldoinsuficienteparasacarovalorde:"+valor);}}

Dessamaneira, na hora de dar o throw new SaldoInsuficienteException você vai precisar

passaressevalorcomoargumento:

if(this.saldo<valor){thrownewSaldoInsuficienteException(valor);}

Atenção: você pode se aproveitar do Eclipse para isso: comece já passando o valor como

180 12.11EXERCÍCIOS:EXCEÇÕES

Page 191: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

argumentoparaoconstrutordaexceptioneoEclipsevaireclamarquenãoexistetalconstrutor.Oquickfix(ctrl+1)vaisugerirqueelesejaconstruindo,poupando-lhetempo!

Eagora,comoficaométodosacadaclasseContaCorrente?

7. (opcional)DeclareaclasseSaldoInsuficienteExceptioncomofilhadiretadeException em

vezdeRuntimeException.Elapassaaserchecked.Oqueissoresulta?

Vocêvaiprecisaravisarqueoseumétodosaca()throwsSaldoInsuficienteException,pois

elaéumacheckedexception.Alémdisso,quemchamaessemétodovaiprecisartomarumadecisãoentretry-catchouthrows.FaçausodoquickfixdoEclipsenovamente!

Depois, retorne a exception para unchecked, isto é, para ser filha de RuntimeException, pois

utilizaremoselaassimemexercíciosdoscapítulosposteriores.

1. Oqueaconteceseacabaramemóriadajavavirtualmachine?

Existeumapéssimapráticadeprogramaçãoemjavaqueéadeescreverocatcheothrowscom

Exception.

ExistemcódigosquesempreusamExceptionpoisissocuidadetodosospossíveiserros.Omaior

problemadissoégeneralizaroerro.Sealguém jogaalgodo tipoException para quemo chamou,

quemrecebenãosabequalotipoespecíficodeerroocorreuenãovaisabercomotrataromesmo.

Sim,hácasosondeotratamentodemaisdeumaexceptionpodeserfeitodeumamesmamaneira.Por exemplo, se queremos terminar a aplicação tanto no caso de IOException quanto em

SQLException . Se fizermos catch(Exception e) para pegar esses dois casos, teremos um

problema:aaplicaçãovaipararmesmoqueoutraexceçãosejalançada.Asoluçãocorretaseriaterdoiscatches,masaíteríamoscódigorepetido.Paraevitarocódigorepetido,podemosusaromulti-catchdoJava 7, que permite um mesmo catch cuidar de mais de 1 exceção, através da sintaxecatch(IOException|SQLExceptione){...}.

12.12DESAFIOS

12.13DISCUSSÃOEMAULA:CATCHETHROWSEMEXCEPTION

12.12DESAFIOS 181

Page 192: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

182 12.13DISCUSSÃOEMAULA:CATCHETHROWSEMEXCEPTION

Page 193: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO13

"Nossascabeçassãoredondasparaqueospensamentospossammudardedireção."--FrancisPiacaba

Aotérminodessecapítulo,vocêserácapazde:

utilizarasprincipaisclassesdopacotejava.langeleradocumentaçãopadrãodeprojetosjava;

usaraclasseSystemparaobterinformaçõesdosistema;

utilizaraclasseStringdeumamaneiraeficienteeconhecerseusdetalhes;

utilizarosmétodosherdadosdeObjectparageneralizarseuconceitodeobjetos.

Jáusamos,pordiversasvezes,asclassesStringeSystem.VimososistemadepacotesdoJavae

nunca precisamos dar um import nessas classes. Isso ocorre porque elas estão dentro do pacote

java.lang,queéautomaticamenteimportadoparavocê.Éoúnicopacotecomestacaracterística.

Vamosverumpoucodesuasprincipaisclasses.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

A classe System possui uma série de atributos e métodos estáticos. Já usamos o atributo

OPACOTEJAVA.LANG

13.1PACOTEJAVA.LANG

Seuslivrosdetecnologiaparecemdoséculopassado?

13.2UMPOUCOSOBREACLASSESYSTEM

13OPACOTEJAVA.LANG 183

Page 194: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out,paraimprimir.

Olhandoadocumentação,vocêvaiperceberqueoatributooutédotipoPrintStreamdopacote

java.io.Veremos sobre essa classemais adiante. Já podemos perceber que poderíamos quebrar o

System.out.printlnemduaslinhas:

PrintStreamsaida=System.out;saida.println("olamundo!");

OSystemcontatambémcomummétodoquesimplesmentedesligaavirtualmachine,retornando

umcódigodeerroparaosistemaoperacional,éoexit.

System.exit(0);

VeremostambémumpoucomaissobreaclasseSystemnospróximoscapítulosenoapêndicede

Threads.ConsulteadocumentaçãodoJavaevejaoutrosmétodosúteisdaSystem.

Todométodoque precisamos receber algumparâmetro temos que declarar o tipo domesmo.Porexemplo,nonossométodosacaprecisamospassarcomoparâmetroumvalordo tipodouble. Se

tentarmospassarqualquercoisadiferentedissoteremosumerrodecompilação.

AgoravamosobservaroseguintemétododopróprioJava:

System.out.println("Olámundo!");

Nestecaso,ométodoprintlnestárecebendoumaString epoderíamospensarqueo tipode

parâmetroqueelerecebeéString.Masaomesmo tempopodemospassarparaessemétodocoisas

completamente diferentes como int, Conta, Funcionario, SeguroDeVida, etc. Como esse

métodoconseguerecebertantosparâmetrosdetiposdiferentes?

Umapossibilidade seria o uso da sobrecarga, declarando umprintln para cada tipo de objeto

diferente.Mas claramente não é isso que acontece já que conseguimos criar uma classe qualquer einvocarométodoprintlnpassandoessanovaclassecomoparâmetroeelefuncionaria!

Paraentenderoqueestáacontecendo,vamosconsiderarummétodoquerecebeumaConta:

publicvoidimprimeDados(Contaconta){System.out.println(conta.getTitular()+"-"+conta.getSaldo());}

Esse método pode ser invocado passando como parâmetro qualquer tipo de conta que temos nonossosistema:ContaCorrenteeContaPoupancapoisambassãofilhasdeConta.Sequiséssemos

queonossométodoconseguissereceberqualquertipodeobjetoteríamosqueterumaclassequefossemãedetodosessesobjetos.ÉparaissoqueexisteaclasseObject!

13.3JAVA.LANG.OBJECT

184 13.3JAVA.LANG.OBJECT

Page 195: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Semprequandodeclaramosumaclasse,essaclasseéobrigadaaherdardeoutra.Istoé,paratodaclasse que declararmos, existe uma superclasse. Porém, criamos diversas classes sem herdar deninguém:

classMinhaClasse{

}

QuandooJavanãoencontraapalavrachaveextends, ele consideraquevocêestáherdandoda

classeObject,quetambémseencontradentrodopacotejava.lang.Vocêatémesmopodeescrever

essaherança,queéomesmo:

publicclassMinhaClasseextendsObject{

}

Todasasclasses,semexceção,herdamdeObject,sejadiretaouindiretamente,poiselaéamãe,vó,bisavó,etcdequalquerclasse.

Podemos tambémafirmarquequalquerobjeto emJavaéumObject, podendo ser referenciado

como tal. Então, qualquer objeto possui todos osmétodos declarados na classe Object e veremos

algunsdeleslogoapósocasting.

A habilidade de poder se referir a qualquer objeto como Object nos traz muitas vantagens.

Podemos criar um método que recebe um Object como argumento, isto é, qualquer objeto! Por

exemplo,ométodoprintlnpoderiaserimplementadodaseguintemaneira:

publicvoidprintln(Objectobj){write(obj.toString());//ométodowriteescreveumastringnoconsole}

Dessaforma,qualquerobjetoquepassarmoscomoparâmetropoderáserimpressonoconsoledesdequeelepossuaométodotoString.ParagarantirquetodososobjetosdoJavapossuamessemétodo,

elefoiimplementadonaclasseObject.

Por padrão, o método toString do Object retorna o nome da classe @ um número de

identidade:

Conta@34f5d74a

Masesequisermosimprimiralgodiferente?Nanossateladedetalhesdeconta,temosumacaixadeseleçãoondenossascontasestãosendoapresentadascomovalordopadrãodotoString.Sempreque

queremos modificar o comportamento de um método em relação a implementação herdada da

13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING

toString

13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING 185

Page 196: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

superclasse,podemossobrescrevê-lonaclassefilha:

publicabstractclassConta{protecteddoublesaldo;//outrosatributos...

@OverridepublicStringtoString(){return"[titular="+titular+",numero="+numero+",agencia="+agencia+"]";}}

Agorapodemosusaressemétodoassim:

ContaCorrentecc=newContaCorrente();System.out.println(cc.toString());

E omelhor, se for apenas para jogar na tela, você nem precisa chamar o toString! Ele já é

chamadoparavocê:

ContaCorrentecc=newContaCorrente();System.out.println(cc);//OtoStringéchamadopelaclassePrintStream

Geraomesmoresultado!

VocêaindapodeconcatenarStringsemJavacomooperador+.SeoJavaencontraumobjetono

meiodaconcatenação,eletambémchamaotoStringdele.

ContaCorrentecc=newContaCorrente();System.out.println("Conta:"+cc);

Atéagoraestamosignorandoofatoquepodemosmaisdeumacontademesmonúmeroeagêncianonossosistema.Atualmente,quandoinserimosumanovaconta,osistemaverificaseacontainseridaéigualaalgumaoutracontajácadastrada.Masqualcritériodeigualdadeéutilizadoporpadrãoparafazeressaverificação?

Assim como no caso dotoString, todos objetos do Java possuem um outrométodo chamado

equalsqueéutilizadoparacompararobjetosdaqueletipo.Porpadrão,essemétodoapenascompara

asreferênciasdosobjetos.Comotodavezqueinserimosumanovacontanosistemaestamosfazendonewemalgumtipodeconta,asreferênciasnuncavãoseriguais,mesmoosdados(númeroeagência)

sendoiguais.

Mas,esefosseprecisocompararosatributos?Quaisatributoseledeveriacomparar?OJavaporsisónãofazisso,maspodemossobrescreveroequalsdaclasseObjectparacriarmosessecritériode

comparação.

OequalsrecebeumObjectcomoargumentoedeveverificarseelemesmoéigualaoObject

equals

186 13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING

Page 197: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

recebidopararetornarumboolean.Sevocênãoreescreveressemétodo,ocomportamentoherdadoé

fazerum==comoobjetorecebidocomoargumento.

publicabstractclassConta{protecteddoublesaldo;//outrosatributos...

publicbooleanequals(Objectobject){//primeiroverificaseooutroobjectnãoénuloif(object==null){returnfalse;}

if(this.numero==object.numero&&this.agencia.equals(object.agencia)){returntrue;}returnfalse;}}

NomomentoquerecebemosumareferênciaparaumObject,comovamosacessarosmétodose

atributosdesseobjetoqueimaginamosserumaConta?Seestamosreferenciando-ocomoObject,

nãopodemosacessá-locomosendoConta.Ocódigoacimanãocompila!

PoderíamosentãoatribuiressareferênciadeObjectparaContaparadepoisacessarosatributos

necessários?Tentemos:

ContaoutraConta=object;

NóstemoscertezadequeesseObject se refereaumaConta, jáqueanossa lista só imprime

contas.MasocompiladorJavanãotemgarantiassobreisso!Essalinhaacimanãocompila,poisnemtodoObjectéumaConta.

Pararealizaressaatribuição,paraissodevemos"avisar"ocompiladorJavaquerealmentequeremosfazer isso, sabendodo riscoquecorremos.Fazemosocastingdereferências, parecido comde tiposprimitivos:

ContaoutraConta=(Conta)object;

Ocódigopassaacompilar,masseráqueroda?Essecódigorodasemnenhumproblema,poisemtempodeexecuçãoaJVMverificaráseessareferênciarealmenteéparaumobjetodetipoConta, e

está!Senãoestivesse,umaexceçãodotipoClassCastExceptionserialançada.

Comisso,nossométodoequalsficariaassim:

publicabstractclassConta{protecteddoublesaldo;//outrosatributos...

Castingdereferências

13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING 187

Page 198: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicbooleanequals(Objectobject){if(object==null){returnfalse;}

ContaoutraConta=(Conta)object;if(this.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia)){returntrue;}returnfalse;}}

VocêpoderiacriarummétodocomoutronomeemvezdereescreverequalsquerecebeObject,

mas ele é importante poismuitas bibliotecas o chamam através do polimorfismo, como veremos nocapítulodojava.util.

O método hashCode() anda de mãos dadas com o método equals() e é de fundamental

entendimento no caso de você utilizar suas classes com estruturas de dados que usam tabelas deespalhamento.Tambémfalaremosdelenocapítulodejava.util.

REGRASPARAAREESCRITADOMÉTODOEQUALS

Pelo contrato definido pela classe Object devemos retornar false também no caso do

objetopassadonãoserdetipocompatívelcomasuaclasse.Entãoantesdefazerocastingdevemosverificarisso,eparatalusamosapalavrachaveinstanceof,outeríamosumaexceptionsendo

lançada.

Alémdisso,podemosresumirnossoequalsdetalformaanãousarumif:

publicbooleanequals(Objectobject){if(object==null){returnfalse;}if(!(objectinstanceofConta)){returnfalse;}ContaoutraConta=(Conta)object;return(this.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia));}

188 13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING

Page 199: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Comoverificar seaclasseThrowable que é a superclassedeException também reescreveo

métodotoString?

AmaioriadasclassesdoJavaquesãomuitoutilizadasterãoseusmétodosequalsetoString

reescritosconvenientemente.

2. Utilize-sedadocumentaçãodoJavaedescubradequeclasseéoobjetoreferenciadopeloatributooutdaSystem.

Repareque,comodevidoimport,poderíamosescrever:

//faltaadeclaraçãodasaída________saida=System.out;saida.println("ola");

Avariávelsaida precisa ser declaradadeque tipo?É issoquevocêprecisa descobrir. Sevocê

digitaressecódigonoEclipse,elevaitesugerirumquickfixedeclararáavariávelparavocê.

Estudaremosessaclasseemumcapítulofuturo.

3. Rodeaaplicaçãoecadastreduascontas.Na teladedetalhesdeconta,verifiqueoqueaparecenacaixadeseleçãodecontaparatransferência.Porqueissoacontece?

4. Reescreva ométodo toString da sua classe Conta fazendo com que uma mensagem mais

explicativa seja devolvida. Lembre-se de aproveitar dos recursos do Eclipse para isto: digitandoapenasocomeçodonomedométodoaserreescritoepressionandoctrl+espaço,elevai sugerirreescrever o método, poupando o trabalho de escrever a assinatura do método e cometer algumengano.

publicabstractclassConta{

Agoraéamelhorhoradeaprenderalgonovo

13.5EXERCÍCIOS:JAVA.LANG.OBJECT

13.5EXERCÍCIOS:JAVA.LANG.OBJECT 189

Page 200: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

protecteddoublesaldo;

@OverridepublicStringtoString(){return"[titular="+titular+",numero="+numero+",agencia="+agencia+"]";}//restantedaclasse

}

Rode a aplicação novamente, cadastre duas contas e verifique novamente a caixa de seleção datransferência.Oqueaconteceu?

5. Reescrevaométodoequals da classe Conta para que duas contas com omesmonúmero eagênciasejamconsideradasiguais.Esboço:

publicabstractclassConta{

publicbooleanequals(Objectobj){if(obj==null){returnfalse;}

ContaoutraConta=(Conta)obj;

returnthis.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia);}}

Vocêpodeusar octrl+ espaço doEclipsepara escrever o esqueletodométodoequals, bastadigitardentrodaclasseequepressionarctrl+espaço.

Rodeaaplicaçãoetenteadicionarduascontascomomesmonúmeroeagência.Oqueacontece?

StringéumaclasseemJava.VariáveisdotipoStringguardamreferênciasaobjetos,enãoum

valor,comoacontececomostiposprimitivos.

Aliás,podemoscriarumaStringutilizandoonew:

Stringx=newString("fj11");Stringy=newString("fj11");

Criamosaqui,doisobjetosdiferentes.Oqueacontecequandocomparamosessasduas referênciasutilizandoo==?

if(x==y){System.out.println("referênciaparaomesmoobjeto");}else{System.out.println("referênciasparaobjetosdiferentes!");

13.6JAVA.LANG.STRING

190 13.6JAVA.LANG.STRING

Page 201: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}

Temosaquidoisobjetosdiferentes!E,então,comofaríamosparaverificarseoconteúdodoobjetoéomesmo?Utilizamosométodoequals,quefoireescritopelaString,parafazeracomparaçãode

charemchar.

if(x.equals(y)){System.out.println("consideramosiguaisnocritériodeigualdade");}else{System.out.println("consideramosdiferentesnocritériodeigualdade");}

Aqui,acomparaçãoretornaverdadeiro.Porquê?PoisquemimplementouaclasseStringdecidiu

queesteseriaomelhorcritériodecomparação.Vocêpodedescobriroscritériosdeigualdadedecadaclassepeladocumentação.

PodemostambémconcatenarStringsusandoo+.PodemosconcatenarStringscomqualquer

objeto,atémesmonúmeros:

inttotal=5;System.out.println("ototalgastoé:"+total);

O compilador utilizará os métodos apropriados da classe String e possivelmente métodos de

outrasclassespararealizartaltarefa.

SequisermoscompararduasStrings,utilizamosométodocompareTo,querecebeumaString

comoargumentoedevolveum inteiro indicandoseaString vemantes, é igual ouvemdepois da

Stringrecebida.Seforemiguais,édevolvido0;seforanterioràStringdoargumento,devolve

uminteironegativo;e,seforposterior,uminteiropositivo.

Fatoimportante:umaStringéimutável.OjavacriaumpooldeStringsparausarcomocachee,seaStringnãofosseimutável,mudandoovalordeumaStringafetariatodasasStringsdeoutras

classesquetivessemomesmovalor.

Reparenocódigoabaixo:

Stringpalavra="fj11";palavra.toUpperCase();System.out.println(palavra);

Pode parecer estranho,mas ele imprime "fj11" emminúsculo. Todométodo que parece alterar ovalordeumaString,naverdade,criaumanovaStringcomasmudançassolicitadasearetorna!

Tantoqueessemétodonãoévoid.Ocódigorealmenteútilficariaassim:

Stringpalavra="fj11";Stringoutra=palavra.toUpperCase();System.out.println(outra);

Ouvocêpodeeliminaracriaçãodeoutravariáveltemporária,seacharconveniente:

13.6JAVA.LANG.STRING 191

Page 202: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Stringpalavra="fj11";palavra=palavra.toUpperCase();System.out.println(palavra);

Isso funciona da mesma forma para todos os métodos que parecem alterar o conteúdo de umaString.

Sevocêaindaquisertrocaronúmero1para2,faríamos:

Stringpalavra="fj11";palavra=palavra.toUpperCase();palavra=palavra.replace("1","2");System.out.println(palavra);

Ouaindapodemosconcatenaras invocaçõesdemétodo, jáqueumaString é devolvida a cada

invocação:

Stringpalavra="fj11";palavra=palavra.toUpperCase().replace("1","2");System.out.println(palavra);

O funcionamento do pool interno de Strings do Java tem uma série de detalhes e você podeencontrarmaisinformaçõessobreistonadocumentaçãodaclasseStringenoseumétodointern().

OUTROSMÉTODOSDACLASSESTRING

Existem diversos métodos da classe String que são extremamente importantes.

Recomendamos sempre consultar o javadoc relativo a essa classe para aprender cada vez maissobreamesma.

Porexemplo,ométodocharAt(i),retornaocaractereexistentenaposiçãoidaString,o

métodolengthretornaonúmerodecaracteresnamesmaeométodosubstringquerecebeumintedevolveaSubStringapartirdaposiçãopassadaporaqueleint.

OindexOf recebeumcharouumaStringedevolveoíndiceemqueaparecepelaprimeira

veznaStringprincipal(hátambémolastIndexOfquedevolveoíndicedaúltimaocorrência).

OtoUpperCaseeotoLowerCasedevolvemumanovaStringtodaemmaiúsculaetodaem

minúscula,respectivamente.

ApartirdoJava6,temosaindaométodoisEmpty,quedevolvetrueseaStringforvaziaou

falsecasocontrário.

Algunsmétodosúteisparabuscassãoocontainseomatches.

Hámuitosoutrosmétodos,recomendamosquevocêsempreconsulteojavadocdaclasse.

192 13.6JAVA.LANG.STRING

Page 203: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

JAVA.LANGSTRINGBUFFERESTRINGBUILDER

ComoaclasseStringéimutável,trabalharcomumamesmaStringdiversasvezespodeter

um efeito colateral: gerar inúmeras Strings temporárias. Isto prejudica a performance da

aplicaçãoconsideravelmente.

NocasodevocêtrabalharmuitocomamanipulaçãodeumamesmaString (por exemplo,

dentrodeumlaço),oidealéutilizaraclasseStringBuffer.AclasseStringBufferrepresenta

umasequênciadecaracteres.DiferentementedaString,elaémutável,enãopossuiaquelepool.

AclasseStringBuildertemexatamenteosmesmosmétodos,comadiferençadelanãoser

thread-safe.VeremossobreesteconceitonocapítulodeThreads.String.

1. Queremosqueascontasapresentadasnacaixadeseleçãodatransferênciaapareçamcomonomedotitularemmaiúsculas.ParafazerissovamosalterarométodotoStringdaclasseConta.Utilize

ométodotoUpperCasedaStringparaisso.

2. Após alterarmosométodotoString, aconteceu algumamudança comonomedo titular que é

apresentadonalistadecontas?Porque?

3. Testeosexemplosdessecapítulo,paraverqueumaStringéimutável.Porexemplo:

publicclassTestaString{

publicstaticvoidmain(String[]args){Strings="fj11";s.replaceAll("1","2");System.out.println(s);}

}

Comofazerparaeleimprimirfj22?

4. Como fazerpara saber seumaString se encontra dentrodeoutra?Epara tirar os espaços em

brancodaspontasdeumaString?EparasaberseumaStringestávazia?Eparasaberquantos

caracterestemumaString?

TomecomohábitosemprepesquisaroJavaDoc!ConheceraAPI,aospoucos,é fundamentalparaquevocênãoprecisereescreveraroda!

5. (opcional)Escreva ummétodo que usa osmétodoscharAt elength de umaString para

13.7EXERCÍCIOS:JAVA.LANG.STRING

13.7EXERCÍCIOS:JAVA.LANG.STRING 193

Page 204: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

imprimiramesmacaractereacaractere,comcadacaractereemumalinhadiferente.

6. (opcional) Reescreva o método do exercício anterior, mas modificando ele para que imprima aStringde trásparaa frenteeemuma linhasó.Teste-apara"Socorram-me, subinoônibusem

Marrocos"e"anotaramadatadamaratona".

7. (opcional)PesquiseaclasseStringBuilder(ouStringBuffernoJava1.4).Elaémutável.Porque

usá-laemvezdaString?Quandousá-la?

Comovocêpoderia reescreverométododeescrever aString de trás para a frente usandoum

StringBuilder?

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. ConvertaumaStringparaumnúmerosemusarasbibliotecasdojavaquejáfazemisso.Issoé,

umaStringx="762"devegeraruminti=762.

Paraajudar,saibaqueumcharpodeser"transformado"emintcomomesmovalornumérico

fazendo:

charc='3';inti=c-'0';//ivale3!

Aquiestamosnosaproveitandodoconhecimentodatabelaunicode:osnúmerosde0a9estãoemsequência! Você poderia usar o método estático Character.getNumericValue(char) em vez

disso.

EditoraCasadoCódigocomlivrosdeumaformadiferente

13.8DESAFIO

13.9DISCUSSÃOEMAULA:OQUEVOCÊPRECISAFAZEREMJAVA?

194 13.8DESAFIO

Page 205: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

QualéasuanecessidadecomoJava?Precisafazeralgoritmosderedesneurais?Gerargráficos3D?Relatórios emPDF?Gerar códigodebarra?Gerarboletos?ValidarCPF?Mexer comumarquivodoExcel?

O instrutor vai mostrar que para a maioria absoluta das suas necessidades, alguém já fez umabibliotecaeadisponibilizou.

13.9DISCUSSÃOEMAULA:OQUEVOCÊPRECISAFAZEREMJAVA? 195

Page 206: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO14

"Ohomemesqueceráantesamortedopaiqueaperdadapropriedade"--Maquiavel

Aotérminodessecapítulo,vocêserácapazde:

declarareinstanciararrays;popularepercorrerarrays.

Dentrodeumbloco,podemosdeclarardiversasvariáveiseusá-las:

doublesaldoDaConta1=conta1.getSaldo();doublesaldoDaConta2=conta2.getSaldo();doublesaldoDaConta3=conta3.getSaldo();doublesaldoDaConta4=conta4.getSaldo();

Isso pode se tornar um problema quando precisamos mudar a quantidade de variáveis a seremdeclaradasdeacordocomumparâmetro.Esseparâmetropodevariar,comoporexemplo,aquantidadedenúmerocontidosnumbilhetedeloteria.Umjogosimplespossui6números,maspodemoscomprarumbilhetemaiscaro,com7númerosoumais.

Parafacilitaressetipodecasopodemosdeclararumvetor(array)dedoubles:

double[]saldosDasContas;

Odouble[]éumtipo.Umaarrayésempreumobjeto,portanto,avariávelsaldosDasContasé

umareferência.Vamosprecisarcriarumobjetoparapoderusaraarray.Comocriamosoobjeto-array?

saldosDasContas=newdouble[10];

Oque fizemos foicriarumaarraydedoublede10posiçõeseatribuiroendereçonoqualela foicriada.Podemosaindaacessarasposiçõesdoarray:

saldosDasContas[5]=conta5.getSaldo();

Ocódigoacimaalteraasextaposiçãodoarray.NoJava,osíndicesdoarrayvãode0an-1,ondenéotamanhodadonomomentoemquevocêcriouoarray.Sevocêtentaracessarumaposiçãoforadessealcance,umerroocorreráduranteaexecução.

UMPOUCODEARRAYS

14.1OPROBLEMA

196 14UMPOUCODEARRAYS

Page 207: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ARRAYS-UMPROBLEMANOAPRENDIZADODEMUITASLINGUAGENS

Aprender a usar arrays pode ser um problema em qualquer linguagem. Isso porque envolveumasériedeconceitos,sintaxeeoutros.NoJava,muitasvezesutilizamosoutrosrecursosemvezdearrays,emespecialospacotesdecoleçõesdoJava,queveremosnocapítulo15.Portanto,fiquetranquilocasonãoconsigadigerirtodasintaxedasarraysnumprimeiromomento.

No caso do bilhete de loteria, podemos utilizar o mesmo recurso. Mais ainda, a quantidade denúmerosdonossobilhetepodeserdefinidoporumavariável.Considerequenindicaquantosnúmeros

nossobilheteterá,podemosentãofazer:

int[]numerosDoBilhete=newint[n];

Eassimpodemosacessaremodificarosinteiroscomíndicede0an-1.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

É comum ouvirmos "array de objetos". Porém quando criamos uma array de alguma classe, elapossui referências. O objeto, como sempre, está na memória principal e, na sua array, só ficamguardadasasreferências(endereços).

ContaCorrente[]minhasContas;minhasContas=newContaCorrente[10];

JáconheceoscursosonlineAlura?

14.2ARRAYSDEREFERÊNCIAS

14.2ARRAYSDEREFERÊNCIAS 197

Page 208: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Quantascontasforamcriadasaqui?Naverdade,nenhuma.Foramcriados10espaçosquevocêpodeutilizarparaguardarumareferênciaaumaContaCorrente.Porenquanto,elessereferenciamparalugarnenhum(null).Sevocêtentar:

System.out.println(minhasContas[0].getSaldo());

Umerroduranteaexecuçãoocorrerá!Pois,naprimeiraposiçãodaarray,nãoháumareferênciaparaumaconta,nemparalugarnenhum.Vocêdevepopularsuaarrayantes.

ContaCorrentecontaNova=newContaCorrente();contaNova.deposita(1000.0);minhasContas[0]=contaNova;

Ouvocêpodefazerissodiretamente:

minhasContas[1]=newContaCorrente();minhasContas[1].deposita(3200.0);

Umaarraydetiposprimitivosguardavalores,umarraydeobjetosguardareferências.

Mase seagoraquisermosguardar tantoContaCorrente quantoContaPoupança?UmarraydeContaCorrente só consegueguardar objetos domesmo tipo.Sequisermosguardar os dois tiposdeconta,devemoscriarumarraydeConta!

Conta[]minhasContas=newConta[10];minhasContas[0]=newContaCorrente();minhasContas[1]=newContaPoupanca();

Perceba que não estamos criando umobjeto do tipoConta, que é abstrata, estamos criando 10

espaçosqueguardamreferênciasparaqualquertipodeconta.

14.3PERCORRENDOUMAARRAY

198 14.3PERCORRENDOUMAARRAY

Page 209: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Percorrerumarrayémuitosimplesquandofomosnósqueacriamos:

publicstaticvoidmain(String[]args){int[]idades=newint[10];for(inti=0;i<10;i++){idades[i]=i*10;}for(inti=0;i<10;i++){System.out.println(idades[i]);}}

Porém,emmuitoscasos,recebemosumaarraycomoargumentoemummétodo:

publicvoidimprimeArray(int[]array){//nãocompila!!for(inti=0;i<????;i++){System.out.println(array[i]);}}

Atéondeofordeveir?TodaarrayemJavatemumatributoquesechamalength,evocêpode

acessá-loparasaberotamanhodoarrayaoqualvocêestásereferenciandonaquelemomento:

publicvoidimprimeArray(int[]array){for(inti=0;i<array.length;i++){System.out.println(array[i]);}}

ARRAYSNÃOPODEMMUDARDETAMANHO

Apartirdomomentoqueumaarrayfoicriada,elanãopodemudardetamanho.

Sevocêprecisardemaisespaço,seránecessáriocriarumanovaarraye,antesdesereferirela,copieoselementosdaarrayvelha.

OJava5.0trazumanovasintaxeparapercorremosarrays(ecoleções,queveremosmaisafrente).

Nocasodevocênãoternecessidadedemanterumavariávelcomoíndicequeindicaaposiçãodoelementonovetor(queéumagrandepartedoscasos),podemosusaroenhanced-for.

publicclassAlgumaClasse{publicstaticvoidmain(String[]args){int[]idades=newint[10];for(inti=0;i<10;i++){idades[i]=i*10;}

//imprimindotodaaarray

14.4PERCORRENDOUMAARRAYNOJAVA5.0

14.4PERCORRENDOUMAARRAYNOJAVA5.0 199

Page 210: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

for(intx:idades){System.out.println(x);}}}

Nãoprecisamosmaisdolengthparapercorrermatrizescujotamanhonãoconhecemos:

publicclassAlgumaClasse{publicvoidimprimeArray(int[]array){for(intx:array){System.out.println(x);}}}

Omesmoéválidoparaarraysdereferências.Essefornadamaiséqueumtruquedecompilação

parafacilitaressatarefadepercorrerarraysetorná-lamaislegível.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Paraconsolidarmososconceitossobrearrays,vamosfazeralgunsexercíciosquenãointerferememnossoprojeto.

1. CrieumaclasseTestaArrays enométodomain crie umarrayde contas de tamanho10.Em

seguida,façaumlaçoparacriar10contascomsaldosdistintosecolocá-lasnoarray.Porexemplo,vocêpodeutilizaroíndicedolaçoemultiplicá-lopor100paragerarosaldodecadaconta:

Conta[]contas=newConta[10];

for(inti=0;i<contas.length;i++){Contaconta=newContaCorrente();conta.deposita(i*100.0);//escrevaocódigoparaguardaracontanaposiçãoidoarray}

2. AindanaclasseTestaArrays,façaumoutrolaçoparacalculareimprimiramédiadossaldosde

VocêpodetambémfazerocursodatadessaapostilanaCaelum

14.5EXERCÍCIOS:ARRAYS

200 14.5EXERCÍCIOS:ARRAYS

Page 211: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

todasascontasdoarray.

3. (opcional) Crie uma classe TestaSplit que reescreva uma frase com as palavras na ordem

invertida."Socorram-me,subinoônibusemMarrocos"deveretornar"MarrocosemônibusnosubiSocorram-me,".Utilize ométodosplit daString para te auxiliar. Essemétodo divide uma

StringdeacordocomoseparadorespecificadoedevolveaspartesemumarraydeString,por

exemplo:

Stringfrase="Umamensagemqualquer";String[]palavras=frase.split("");

//Agorasóbastapercorreroarraynaordeminversaimprimindoaspalavras

4. (opcional)CrieumaclasseBancodentrodopacotebr.com.caelum.contas.modeloOBanco

deve ter umnome e umnúmero (obrigatoriamente) e uma referência a uma arraydeConta de

tamanho10,alémdeoutrosatributosquevocêjulgarnecessário.

publicclassBanco{privateStringnome;privateintnumero;privateConta[]contas;

//outrosatributosquevocêacharnecessário

publicBanco(Stringnome,intnumero){this.nome=nome;this.numero=numero;this.contas=newContaCorrente[10];}

//gettersparanomeenúmero,nãocolocarossetterspoisjárecebemosno//construtor}

5. (opcional)AclasseBancodeveterummétodoadiciona,querecebeumareferênciaaConta

comoargumentoeguardaessaconta.

VocêdeveinseriraContaemumaposiçãodaarrayqueestejalivre.Existemváriasmaneiraspara

vocêfazerisso:guardarumcontadorparaindicarqualapróximaposiçãovaziaouprocurarporumaposiçãovaziatodavez.Oqueseriamaisinteressante?

Sequiserverificarqualaprimeiraposiçãovazia(nula)eadicionarnela,poderiaserfeitoalgocomo:

publicvoidadiciona(Contac){for(inti=0;i<this.contas.length;i++){//verificarseaposiçãoestávazia//adicionarnoarray}}

Éimportanterepararqueométodoadicionanãorecebetitular,agencia,saldo,etc.Essaseriaumamaneiranemumpoucoestruturada,muitomenosorientadaaobjetosdesetrabalhar.Vocêantescria

14.5EXERCÍCIOS:ARRAYS 201

Page 212: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

umaContaejápassaareferênciadela,quedentrodoobjetopossuititular,saldo,etc.

6. (opcional)CrieumaclasseTestaBancoquepossuiráummétodomain.Dentrodelecriealgumas

instânciasdeContaepasseparaobancopelométodoadiciona.

Bancobanco=newBanco("CaelumBank",999);//....

Criealgumascontasepassecomoargumentoparaoadicionadobanco:

ContaCorrentec1=newContaCorrente();c1.setTitular("Batman");c1.setNumero(1);c1.setAgencia(1000);c1.deposita(100000);banco.adiciona(c1);

ContaPoupancac2=newContaPoupanca();c2.setTitular("Coringa");c2.setNumero(2);c2.setAgencia(1000);c2.deposita(890000);banco.adiciona(c2);

Você pode criar essas contas dentro de um loop e dar a cada um deles valores diferentes dedepósitos:

for(inti=0;i<5;i++){ContaCorrenteconta=newContaCorrente();conta.setTitular("Titular"+i);conta.setNumero(i);conta.setAgencia(1000);conta.deposita(i*1000);banco.adiciona(conta);}

Repare que temos de instanciar ContaCorrente dentro do laço. Se a instanciação de

ContaCorrente ficasseacimado laço,estaríamosadicionadocincovezesamesma instância deContaCorrentenesteBancoeapenasmudandoseudepósitoacadaiteração,quenessecasonãoé

oefeitodesejado.

Opcional:ométodoadicionapodegerarumamensagemdeerroindicandoquandooarrayjáestá

cheio.

7. (opcional)PercorraoatributocontasdasuainstânciadeBancoeimprimaosdadosdetodasas

suascontas.Parafazerisso,vocêpodecriarummétodochamadomostraContasdentrodaclasse

Banco:

publicvoidmostraContas(){for(inti=0;i<this.contas.length;i++){System.out.println("Contanaposição"+i);//preencherparamostraroutrasinformacoesdaconta}}

202 14.5EXERCÍCIOS:ARRAYS

Page 213: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Cuidadoaopreencheressemétodo:alguns índicesdoseuarraypodemnãoconter referência paraumaContaconstruída,istoé,aindasereferiremparanull.Sepreferir,useofornovodojava

5.0.

Aí,atravésdoseumain,depoisdeadicionaralgumascontas,bastafazer:

banco.mostraContas();

8. (opcional) Em vez de mostrar apenas o salário de cada funcionário, você pode usar o métodotoString()decadaContadoseuarray.

9. (opcional)Crie ummétodo para verificar se umadeterminadaConta se encontra ou não como

contadestebanco:

publicbooleancontem(Contaconta){//...}

Vocêvaiprecisar fazerumfor emseuarrayeverificar se a contapassada comoargumento se

encontradentrodoarray.Eviteaomáximousarnúmeroshard-coded,istoé,useo.length.

10. (opcional)Caso o array já esteja cheio nomomento de adicionar uma outra conta, crie um arraynovocomumacapacidademaiorecopieosvaloresdoarrayatual.Istoé,vamosfazerarealocaçãodoselementosdoarrayjáquejavanãotemisso:umarraynasceemorrecomomesmolength.

USANDOOTHISPARAPASSARARGUMENTO

Dentrodeummétodo,vocêpodeusarapalavrathisparareferenciarasimesmoepode

passaressareferênciacomoargumento.

Arrays podem ter mais de uma dimensão. Isto é, em vez de termos uma array de 10 contas,podemosterumaarrayde10por10contasevocêpodeacessaracontanaposiçãodacolunaxelinhay.Naverdade,umaarraybidimensionalemJavaéumaarraydearrays.Pesquisesobreisso.

14.6UMPOUCOMAIS...

14.6UMPOUCOMAIS... 203

Page 214: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Uma array bidimensional não precisa ser retangular, isto é, cada linha pode ter um númerodiferentedecolunas.Como?Porque?

Oqueacontecesecriarmosumaarrayde0elementos?e-1?

OmétodomainrecebeumaarraydeStringscomoargumento.Essaarrayépassadapelousuárioquandoeleinvocaoprograma:

$javaTesteargumento1outromaisoutro

Enossaclasse:

publicclassTeste{publicstaticvoidmain(String[]args){for(Stringargumento:args){

204 14.6UMPOUCOMAIS...

Page 215: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out.println(argumento);}}}

Issoimprimirá:

argumento1outromaisoutro

1. Nosprimeiroscapítulos,vocêdeveterreparadoqueaversãorecursivaparaoproblemadeFibonacciélentaporquetodahoraestamosrecalculandovalores.Façacomqueaversãorecursivasejatãoboaquantoaversãoiterativa.(Dica:usearraysparaisso)

2. Oobjetivodesteexercícioéfixarosconceitosvistos.Sevocêestácomdificuldadeemalgumapartedessecapítulo,aproveiteetreinetudooquevimosatéagoranopequenoprogramaabaixo:

Programa:

Classe: Casa Atributos: cor, totalDePortas, portas[] Métodos: void pinta(String s), intquantasPortasEstaoAbertas(),voidadicionaPorta(Portap),inttotalDePortas()

Crieumacasa,pinte-a.Crietrêsportasecoloque-asnacasaatravésdométodoadicionaPorta,

abraefeche-ascomodesejar.UtilizeométodoquantasPortasEstaoAbertaspara imprimiro

númerodeportas abertas eométodototalDePortas para imprimir o total deportas em sua

casa.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

14.7DESAFIOSOPCIONAIS

Seuslivrosdetecnologiaparecemdoséculopassado?

14.7DESAFIOSOPCIONAIS 205

Page 216: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO15

"Aamizadeéumcontratosegundooqualnoscomprometemosaprestarpequenosfavoresparaqueno-losretribuamcomgrandes."--BarondelaBredeetdeMontesquieu

Aotérminodessecapítulo,vocêserácapazde:

utilizararrays,lists,setsoumapsdependendodanecessidadedoprograma;iterareordenarlistasecoleções;usarmapasparainserçãoebuscadeobjetos.

Comovimosnocapítulodearrays,manipulá-lasébastantetrabalhoso.Essadificuldadeapareceemdiversosmomentos:

nãopodemosredimensionarumarrayemJava;éimpossívelbuscardiretamenteporumdeterminadoelementocujoíndicenãosesabe;nãoconseguimossaberquantasposiçõesdoarrayjáforampopuladassemcriar,paraisso,métodosauxiliares.

Na figura acima, você pode ver um array que antes estava sendo completamente utilizado e que,depois,teveumdeseuselementosremovidos.

Supondoqueosdadosarmazenadosrepresentemcontas,oqueacontecequandoprecisarmosinseriruma nova conta no banco? Precisaremos procurar por um espaço vazio? Guardaremos em algumaestrutura dedados externa, as posiçõesvazias?E se nãohouver espaçovazio?Teríamosde criar umarraymaiorecopiarosdadosdoantigoparaele?

Hámais questões: comoposso saber quantas posições estão sendousadasno array?Vouprecisarsemprepercorreroarrayinteiroparaconseguiressainformação?

COLLECTIONSFRAMEWORK

15.1 ARRAYS SÃO TRABALHOSOS, UTILIZAR ESTRUTURA DEDADOS

206 15COLLECTIONSFRAMEWORK

Page 217: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Alémdessasdificuldadesqueosarraysapresentavam,faltavaumconjuntorobustodeclassesparasupriranecessidadedeestruturasdedadosbásicas,comolistasligadasetabelasdeespalhamento.

Com esses e outros objetivos em mente, o comitê responsável pelo Java criou um conjunto declasseseinterfacesconhecidocomoCollectionsFramework,queresidenopacotejava.utildesdeoJava21.2.

COLLECTIONS

AAPIdeCollectionsérobustaepossuidiversasclassesquerepresentamestruturasdedadosavançadas.

Porexemplo,nãoénecessárioreinventararodaecriarumalistaligada,massimutilizaraquelaqueoJavadisponibiliza.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Umprimeiro recurso que aAPI deCollections traz são listas.Uma lista é uma coleção quepermiteelementosduplicadosemantémumaordenaçãoespecíficaentreoselementos.

Em outras palavras, você tem a garantia de que, quando percorrer a lista, os elementos serãoencontrados em uma ordem pré-determinada, definida na hora da inserção dosmesmos. Ela resolvetodososproblemasquelevantamosemrelaçãoaoarray(busca,remoção, tamanho"infinito",...).Essecódigojáestápronto!

AAPIdeCollectionstrazainterfacejava.util.List,queespecificaoqueumaclassedeve

ser capaz de fazer para ser uma lista. Há diversas implementações disponíveis, cada uma com uma

Agoraéamelhorhoradeaprenderalgonovo

15.2LISTAS:JAVA.UTIL.LIST

15.2LISTAS:JAVA.UTIL.LIST 207

Page 218: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

formadiferentederepresentarumalista.

A implementaçãomaisutilizadada interfaceListéaArrayList, que trabalha comumarray

interno para gerar uma lista. Portanto, ela é mais rápida na pesquisa do que sua concorrente, aLinkedList,queémaisrápidanainserçãoeremoçãodeitensnaspontas.

ARRAYLISTNÃOÉUMARRAY!

É comum confundirem uma ArrayList com um array, porém ela não é um array. O que

ocorreéque,internamente,elausaumarraycomoestruturaparaarmazenarosdados,porémesteatributoestápropriamenteencapsuladoevocênãotemcomoacessá-lo.Repare,também,quevocênãopodeusar[]comumaArrayList,nemacessaratributolength.Nãohárelação!

ParacriarumArrayList,bastachamaroconstrutor:

ArrayListlista=newArrayList();

ÉsemprepossívelabstrairalistaapartirdainterfaceList:

Listlista=newArrayList();

Paracriarumalistadenomes(String),podemosfazer:

Listlista=newArrayList();lista.add("Manoel");lista.add("Joaquim");lista.add("Maria");

AinterfaceListpossuidoismétodosadd,umquerecebeoobjetoaserinseridoeocolocano

finaldalista,eumsegundoquepermiteadicionaroelementoemqualquerposiçãodamesma.Noteque,em momento algum, dizemos qual é o tamanho da lista; podemos acrescentar quantos elementosquisermos,quealistacresceconformefornecessário.

Todalista(naverdade,todaCollection)trabalhadomodomaisgenéricopossível.Istoé,nãohá

uma ArrayList específica para Strings, outra para Números, outra para Datas etc. Todos os

métodostrabalhamcomObject.

Assim,épossívelcriar,porexemplo,umalistadeContasCorrentes:

ContaCorrentec1=newContaCorrente();c1.deposita(100);

ContaCorrentec2=newContaCorrente();c2.deposita(200);

ContaCorrentec3=newContaCorrente();c3.deposita(300);

208 15.2LISTAS:JAVA.UTIL.LIST

Page 219: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Listcontas=newArrayList();contas.add(c1);contas.add(c3);contas.add(c2);

Parasaberquantoselementoshánalista,usamosométodosize():

System.out.println(contas.size());

Háaindaummétodoget(int) que recebe como argumento o índice do elemento que se quer

recuperar.Atravésdele,podemosfazerumforparaiterarnalistadecontas:

for(inti=0;i<contas.size();i++){contas.get(i);//códigonãomuitoútil....}

Mascomofazerparaimprimirosaldodessascontas?PodemosacessarogetSaldo()diretamente

apósfazercontas.get(i)?Nãopodemos; lembre-seque toda lista trabalha semprecomObject.

Assim, a referência devolvida pelo get(i) é do tipo Object , sendo necessário o cast para

ContaCorrentesequisermosacessarogetSaldo():

for(inti=0;i<contas.size();i++){ContaCorrentecc=(ContaCorrente)contas.get(i);System.out.println(cc.getSaldo());}//notequeaordemdoselementosnãoéalterada

Háaindaoutrosmétodos,comoremove()querecebeumobjetoquesedesejaremoverdalista;e

contains(), que recebeumobjeto comoargumento e devolvetrue oufalse, indicando se o

elementoestáounãonalista.

AinterfaceListealgumasclassesqueaimplementampodemservistasnodiagramaaseguir:

15.2LISTAS:JAVA.UTIL.LIST 209

Page 220: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ACESSOALEATÓRIOEPERCORRENDOLISTASCOMGET

Algumaslistas,comoaArrayList,têmacessoaleatórioaosseuselementos:abuscaporum

elemento em uma determinada posição é feita demaneira imediata, sem que a lista inteira sejapercorrida(quechamamosdeacessosequencial).

Nestecaso,oacessoatravésdométodoget(int)émuitorápido.Casocontrário,percorrer

umalistausandoumforcomoessequeacabamosdever,podeserdesastroso.Aopercorrermos

umalista,devemosusarsempreumIteratorouenhancedfor,comoveremos.

Umalistaéumaexcelentealternativaaumarraycomum,jáquetemostodososbenefíciosdearrays,semanecessidadedetomarcuidadocomremoções,faltadeespaçoetc.

A outra implementação muito usada, a LinkedList, fornece métodos adicionais para obter e

removeroprimeiroeúltimoelementoda lista.Ela também temo funcionamento internodiferente,oquepodeimpactarperformance,comoveremosduranteosexercíciosnofinaldocapítulo.

210 15.2LISTAS:JAVA.UTIL.LIST

Page 221: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

VECTOR

Outra implementação é a tradicional classe Vector, presente desde o Java 1.0, que foi

adaptadaparausocomoframeworkdeCollections,comainclusãodenovosmétodos.

Ela deve ser escolhida com cuidado, pois lida de uma maneira diferente com processoscorrendo em paralelo e terá um custo adicional em relação a ArrayList quando não houver

acessosimultâneoaosdados.

Emqualquerlista,épossívelcolocarqualquerObject.Comisso,épossívelmisturarobjetos:

ContaCorrentecc=newContaCorrente();

Listlista=newArrayList();lista.add("Umastring");lista.add(cc);...

Mas e depois, na hora de recuperar esses objetos?Comoométodoget devolveumObject,

precisamosfazerocast.Mascomumalistacomváriosobjetosdetiposdiferentes,issopodenãosertãosimples...

Geralmente, não nos interessa uma lista com vários tipos de objetos misturados; no dia-a-dia,usamoslistascomoaqueladecontascorrentes.NoJava5.0,podemosusarorecursodeGenericspararestringiraslistasaumdeterminadotipodeobjetos(enãoqualquerObject):

List<ContaCorrente>contas=newArrayList<ContaCorrente>();contas.add(c1);contas.add(c3);contas.add(c2);

ReparenousodeumparâmetroaoladodeListeArrayList:eleindicaquenossalistafoicriada

paratrabalharexclusivamentecomobjetosdotipoContaCorrente. Issonos trazumasegurançaem

tempodecompilação:

contas.add("umastring");//issonãocompilamais!!

OusodeGenericstambémeliminaanecessidadedecasting,jáque,seguramente,todososobjetosinseridosnalistaserãodotipoContaCorrente:

for(inti=0;i<contas.size();i++){ContaCorrentecc=contas.get(i);//semcasting!System.out.println(cc.getSaldo());}

15.3LISTASNOJAVA5EJAVA7COMGENERICS

15.3LISTASNOJAVA5EJAVA7COMGENERICS 211

Page 222: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Apartir do Java 7, se você instancia um tipo genérico namesma linha de sua declaração, não énecessáriopassaros tiposnovamente,bastausarnewArrayList<>().É conhecido comooperador

diamante:

List<ContaCorrente>contas=newArrayList<>();

ValeressaltaraimportânciadousodainterfaceList:quandodesenvolvemos,procuramossempre

nosreferiraela,enãoàsimplementaçõesespecíficas.Porexemplo,setemosummétodoquevaibuscarumasériedecontasnobancodedados,poderíamosfazerassim:

classAgencia{publicArrayList<Conta>buscaTodasContas(){ArrayList<Conta>contas=newArrayList<>();

//paracadacontadobancodedados,contas.add

returncontas;}}

Porém,paraqueprecisamosretornarareferênciaespecíficaaumaArrayList?Paraque ser tão

específico?Dessamaneira,odiaqueoptarmospordevolverumaLinkedListemvezdeArrayList,

as pessoas que estão usando o método buscaTodasContas poderão ter problemas, pois estavam

fazendo referência a uma ArrayList. O ideal é sempre trabalhar com a interface mais genérica

possível:

classAgencia{

//modificaçãoapenasnoretorno:publicList<Conta>buscaTodasContas(){ArrayList<Conta>contas=newArrayList<>();

//paracadacontadobancodedados,contas.add

returncontas;}}

ÉomesmocasodepreferirreferenciaraosobjetoscomInputStreamcomofizemosnocapítulo

passado.

Assim como no retorno, é boa prática trabalhar com a interface em todos os lugares possíveis:métodos que precisam receber uma lista de objetos têm List como parâmetro em vez de uma

implementaçãoemespecíficocomoArrayList,deixandoométodomaisflexível:

classAgencia{

publicvoidatualizaContas(List<Conta>contas){//...

15.4AIMPORTÂNCIADASINTERFACESNASCOLEÇÕES

212 15.4AIMPORTÂNCIADASINTERFACESNASCOLEÇÕES

Page 223: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}}

Também declaramos atributos como List em vez de nos comprometer como uma ou outra

implementação.Dessaformaobtemosumbaixoacoplamento:podemostrocaraimplementação,jáqueestamosprogramandoparaainterface!Porexemplo:

classEmpresa{

privateList<Funcionario>empregados=newArrayList<>();

//...}

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Vimos anteriormente que as listas são percorridas de maneira pré-determinada de acordo com ainclusãodositens.Mas,muitasvezes,queremospercorreranossalistademaneiraordenada.

AclasseCollectionstrazummétodoestáticosortquerecebeumListcomoargumentoeo

ordenaporordemcrescente.Porexemplo:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

//reparequeotoStringdeArrayListfoisobrescrito:System.out.println(lista);

Collections.sort(lista);

System.out.println(lista);

Aotestaroexemploacima,vocêobservaráque,primeiro,alistaéimpressanaordemdeinserçãoe,depoisdeinvocarosort,elaéimpressaemordemalfabética.

EditoraCasadoCódigocomlivrosdeumaformadiferente

15.5ORDENAÇÃO:COLLECTIONS.SORT

15.5ORDENAÇÃO:COLLECTIONS.SORT 213

Page 224: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Mastoda listaemJavapodeserdequalquer tipodeobjeto,porexemplo,ContaCorrente.E se

quisermosordenaruma listadeContaCorrente?Emqueordema classeCollections ordenará?

Pelosaldo?Pelonomedocorrentista?

ContaCorrentec1=newContaCorrente();c1.deposita(500);

ContaCorrentec2=newContaCorrente();c2.deposita(200);

ContaCorrentec3=newContaCorrente();c3.deposita(150);

List<ContaCorrente>contas=newArrayList<>();contas.add(c1);contas.add(c3);contas.add(c2);

Collections.sort(contas);//qualseriaocritérioparaestaordenação?

Semprequefalamosemordenação,precisamospensaremumcritériodeordenação,umaformadedeterminar qual elemento vem antes de qual. É necessário instruir o sort sobre como compararnossasContaCorrenteafimdedeterminarumaordemnalista.Paraisto,ométodosortnecessita

que todosseusobjetosda listasejamcomparáveis epossuamummétodoque secomparacomoutraContaCorrente.Comoéqueométodosortteráagarantiadequeasuaclassepossuiessemétodo?

Issoseráfeito,novamente,atravésdeumcontrato,deumainterface!

Vamos fazer com que os elementos da nossa coleção implementem a interfacejava.lang.Comparable,quedefineométodointcompareTo(Object).Estemétododeveretornar

zero,seoobjetocomparadoforigualaesteobjeto,umnúmeronegativo,seesteobjetoformenorqueoobjetodado,eumnúmeropositivo,seesteobjetoformaiorqueoobjetodado.

ParaordenarasContaCorrentesporsaldo,bastaimplementaroComparable:

publicclassContaCorrenteextendsContaimplementsComparable<ContaCorrente>{

//...todoocódigoanteriorficaaqui

publicintcompareTo(ContaCorrenteoutra){if(this.saldo<outra.saldo){return-1;}

if(this.saldo>outra.saldo){return1;}

return0;}}

Com o código anterior, nossa classe tornou-se "comparável": dados dois objetos da classe,

214 15.5ORDENAÇÃO:COLLECTIONS.SORT

Page 225: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

conseguimos dizer se um objeto é maior, menor ou igual ao outro, segundo algum critério por nósdefinido.Nonossocaso,acomparaçãoseráfeitabaseando-senosaldodaconta.

Reparequeocritériodeordenaçãoé totalmenteaberto,definidopeloprogramador.Sequisermosordenarporoutroatributo(ouatéporumacombinaçãodeatributos),bastamodificaraimplementaçãodométodocompareTonaclasse.

QuandochamarmosométodosortdeCollections,elesaberácomofazeraordenaçãodalista;

eleusaráocritérioquedefinimosnométodocompareTo.

OUTRAIMPLEMENTAÇÃO...

Oqueachadaimplementaçãoabaixo?

publicintcompareTo(Contaoutra){returnInteger.compare(this.getNumero(),outra.getNumero());}

Mas,eoexemploanterior,comumalistadeStrings?Porqueaordenaçãofuncionou,naquelecaso,semprecisarmosfazernada?Simples:quemescreveuaclasseString (lembrequeelaéumaclasse

comoqualqueroutra)implementouainterfaceComparableeométodocompareToparaStrings,

fazendo comparação em ordem alfabética. (Consulte a documentação da classe String e veja o

métodocompareTolá).OmesmoacontececomoutrasclassescomoInteger,BigDecimal,Date,

entreoutras.

15.5ORDENAÇÃO:COLLECTIONS.SORT 215

Page 226: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

OUTROSMÉTODOSDACLASSECOLLECTIONS

AclasseCollectionstrazumagrandequantidadedemétodosestáticosúteisnamanipulação

decoleções.

binarySearch(List,Object): Realiza uma busca binária por determinado elemento na

listaordenadaeretornasuaposiçãoouumnúmeronegativo,casonãoencontrado.

max(Collection):Retornaomaiorelementodacoleção.

min(Collection):Retornaomenorelementodacoleção.

reverse(List):Invertealista.

...emuitosoutros.Consulteadocumentaçãoparaveroutrosmétodos.

No Java 8 muitas dessas funcionalidades da Collections podem ser feitas através dos

chamadosStreams,queficaumpoucoforadoescopodeumcursoinicialdeJava.

Existeumaclasseanáloga,ajava.util.Arrays,quefazoperaçõessimilarescomarrays.

Éimportanteconhecê-lasparaevitarescrevercódigojáexistente.

Vamosordenarocampodedestino da teladedetalhesdacontaparaqueascontasapareçamemordemalfabéticadetitular.

1. FaçasuaclasseContaimplementarainterfaceComparable<Conta>.Utilizeocritériodeordenar

pelotitulardaconta.

publicclassContaimplementsComparable<Conta>{...}

DeixeoseumétodocompareToparecidocomeste:

publicclassContaimplementsComparable<Conta>{

//...todoocódigoanteriorficaaqui

publicintcompareTo(ContaoutraConta){returnthis.titular.compareTo(outraConta.titular);}}

15.6EXERCÍCIOS:ORDENAÇÃO

216 15.6EXERCÍCIOS:ORDENAÇÃO

Page 227: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

2. Queremosqueascontasapareçamnocampodedestinoordenadaspelotitular.Vamosentãocriarométodo ordenaLista na classe ManipuladorDeContas. Use o Collections.sort() para

ordenaralistarecuperadadoEvento:

publicclassManipuladorDeContas{

//outrosmétodos

publicvoidordenaLista(Eventoevento){List<Conta>contas=evento.getLista("destino");Collections.sort(contas);}}

Rodeaaplicação,adicionealgumascontaseverifiqueseascontasaparecemordenadaspelonomedotitular,nocampodestino,napartedatransferência.Paraveraordenaçãoénecessárioacessarosdetalhesdeumaconta.

Atençãoespecial:reparequeescrevemosummétodocompareToemnossaclasseenossocódigonunca o invoca!! Isto émuito comum.Reescrevemos (ou implementamos) ummétodo e quemoinvocará será umoutro conjuntode classes (nesse caso, quemestá chamandoocompareTo é o

Collections.sort,queousa comobasepara o algoritmodeordenação). Isso cria um sistema

extremamentecoesoe, aomesmo tempo, combaixoacoplamento: a classeCollections nunca

imaginouqueordenariaobjetosdotipoConta,mas jáqueelessãoComparable,oseumétodo

sortestásatisfeito.

3. OqueteriaacontecidoseaclasseContanãoimplementasseComparable<Conta>mastivesseo

métodocompareTo?

Façaumteste:removatemporariamenteasentençaimplementsComparable<Conta>,nãoremova

ométodocompareToevejaoqueacontece.Bastaterométodo,semassinarainterface?

4. Comoposso inverter a ordemde uma lista?Comoposso embaralhar todos os elementos de umalista?Comopossorotacionaroselementosdeumalista?

InvestigueadocumentaçãodaclasseCollectionsdentrodopacotejava.util.

5. (opcional)CrieumanovaclasseTestaListaquecriaumaArrayListeinserenovascontascom

saldosaleatóriosusandoumlaço(for).Adivinheonomedaclasseparacolocarsaldosaleatórios?

Random. Do pacote java.util . Consulte sua documentação para usá-la (utilize o método

nextInt()passandoonúmeromáximoasersorteado).

6. ModifiqueaclasseTestaListaparautilizarumaLinkedListemvezdeArrayList:

List<Conta>contas=newLinkedList<Conta>();

15.6EXERCÍCIOS:ORDENAÇÃO 217

Page 228: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Precisamos alterar mais algum código para que essa substituição funcione? Rode o programa.Algumadiferença?

7. (opcional)Imprimaareferênciaparaessalista.OtoStringdeumaArrayList/LinkedListé

reescrito?

System.out.println(contas);

Umconjunto(Set)funcionadeformaanálogaaosconjuntosdamatemática,eleéumacoleçãoque

nãopermiteelementosduplicados.

Outracaracterísticafundamentaldeleéofatodequeaordememqueoselementossãoarmazenadospodenãoseraordemnaqualelesforaminseridosnoconjunto.Ainterfacenãodefinecomodeveserestecomportamento.Talordemvariadeimplementaçãoparaimplementação.

15.7CONJUNTO:JAVA.UTIL.SET

218 15.7CONJUNTO:JAVA.UTIL.SET

Page 229: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Um conjunto é representado pela interface Set e tem como suas principais implementações as

classesHashSet,LinkedHashSeteTreeSet.

Ocódigoaseguircriaumconjuntoeadicionadiversoselementos,ealgunsrepetidos:

Set<String>cargos=newHashSet<>();

cargos.add("Gerente");cargos.add("Diretor");cargos.add("Presidente");cargos.add("Secretária");cargos.add("Funcionário");cargos.add("Diretor");//repetido!

//imprimenatelatodososelementosSystem.out.println(cargos);

Aqui,osegundoDiretornãoseráadicionadoeométodoaddlheretornaráfalse.

O uso de um Set pode parecer desvantajoso, já que ele não armazena a ordem, e não aceita

elementos repetidos. Não hámétodos que trabalham com índices, como o get(int) que as listas

possuem.AgrandevantagemdoSetéqueexistemimplementações,comoaHashSet, quepossui

umaperformanceincomparávelcomasListsquandousadoparapesquisa (métodocontains por

exemplo).Veremosessaenormediferençaduranteosexercícios.

ORDEMDEUMSET

Seriapossívelusarumaoutraimplementaçãodeconjuntos,comoumTreeSet,queinsereos

elementosdetalformaque,quandoforempercorridos,elesapareçamemumaordemdefinidapelométodo de comparação entre seus elementos. Esse método é definido pela interfacejava.lang.Comparable.Ou,ainda,podesepassarumComparatorparaseuconstrutor.

JáoLinkedHashSetmantémaordemdeinserçãodoselementos.

AntesdoJava5,nãopodíamosutilizargenerics,eusávamosoSetde formaqueele trabalhava

comObject,havendonecessidadedecastings.

15.7CONJUNTO:JAVA.UTIL.SET 219

Page 230: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

AscoleçõestêmcomobaseainterfaceCollection,quedefinemétodosparaadicionareremover

umelemento,everificarseeleestánacoleção,entreoutrasoperações,comomostraatabelaaseguir:

Umacoleçãopode implementardiretamentea interfaceCollection,porémnormalmente seusa

umadasduassubinterfacesmaisfamosas:justamenteSeteList.

A interface Set, como previamente vista, define um conjunto de elementos únicos enquanto a

interfaceListpermiteelementosduplicados,alémdemanteraordemaqualelesforamadicionados.

A busca em umSet pode sermais rápida do que em um objeto do tipoList, pois diversas

implementaçõesutilizam-sede tabelas de espalhamento (hash tables), realizando a busca para tempolinear(O(1)).

A interfaceMap faz parte do framework,mas não estendeCollection. (veremosMap mais

JáconheceoscursosonlineAlura?

15.8PRINCIPAISINTERFACES:JAVA.UTIL.COLLECTION

220 15.8PRINCIPAISINTERFACES:JAVA.UTIL.COLLECTION

Page 231: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

adiante).

NoJava5,temosoutrainterfacefilhadeCollection:aQueue,quedefinemétodosdeentradae

desaídaecujocritérioserádefinidopelasua implementação(porexemploLIFO,FIFOouaindaumheapondecadaelementopossuisuachavedeprioridade).

Comopercorreroselementosdeumacoleção?Seforumalista,podemossempreutilizarumlaçofor,invocandoométodogetparacadaelemento.Maseseacoleçãonãopermitirindexação?

Por exemplo, um Set não possui um método para pegar o primeiro, o segundo ou o quinto

elementodoconjunto,jáqueumconjuntonãopossuioconceitode"ordem"

Podemosusaroenhanced-for (o"foreach")doJava5parapercorrerqualquerCollection semnos preocupar com isso. Internamente o compilador vai fazer com que seja usado o Iterator da

Collectiondadaparapercorreracoleção.Repare:

Set<String>conjunto=newHashSet<>();

conjunto.add("java");conjunto.add("vraptor");conjunto.add("scala");

for(Stringpalavra:conjunto){System.out.println(palavra);}

15.9PERCORRENDOCOLEÇÕESNOJAVA5

15.9PERCORRENDOCOLEÇÕESNOJAVA5 221

Page 232: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Emqueordemoselementosserãoacessados?

Numa lista, os elementos aparecerão de acordo com o índice em que foram inseridos, isto é, deacordo com o que foi pré-determinado. Em um conjunto, a ordem depende da implementação dainterfaceSet:vocêmuitasvezesnãovaisaberaocertoemqueordemosobjetosserãopercorridos.

PorqueoSeté,então,tãoimportanteeusado?

Paraperceberseumitemjáexisteemumalista,émuitomaisrápidousaralgumasimplementaçõesdeSetdoqueumList, eosTreeSets já vêmordenadosde acordo comas características que

desejarmos!SempreconsidereusarumSetsenãohouveranecessidadedeguardaroselementosem

determinadaordemebuscá-losatravésdeumíndice.

Noeclipse,vocêpodeescreverforeach e darctrl+espaço, que ele vai gerar o esqueletodesseenhancedfor!Muitoútil!

Antes do Java 5 introduzir o novo enhanced-for, iterações em coleções eram feitas com oIterator . Toda coleção fornece acesso a um iterator, um objeto que implementa a interface

Iterator,queconheceinternamenteacoleçãoedáacessoatodososseuselementos,comoafigura

abaixomostra.

Aindahoje(depoisdoJava5)podemosusaroIterator,masomaiscomuméusaroenhanced-

for.E,naverdade,oenhanced-foréapenasumaçúcarsintáticoqueusaiteratorportrásdospanos.

Primeiro criamos um Iterator que entra na coleção. A cada chamada do método next, o

Iterator retorna o próximo objeto do conjunto. Um iterator pode ser obtido com o método

iterator()deCollection,porexemplonumalistadeString:

15.10 PARA SABER MAIS: ITERANDO SOBRE COLEÇÕES COMJAVA.UTIL.ITERATOR

222 15.10PARASABERMAIS:ITERANDOSOBRECOLEÇÕESCOMJAVA.UTIL.ITERATOR

Page 233: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Iterator<String>i=lista.iterator();

AinterfaceIteratorpossuidoismétodosprincipais:hasNext()(comretornobooleano),indica

seaindaexisteumelementoaserpercorrido;next(),retornaopróximoobjeto.

Voltandoaoexemplodoconjuntodestrings,vamospercorreroconjunto:

Set<String>conjunto=newHashSet<>();conjunto.add("item1");conjunto.add("item2");conjunto.add("item3");

//retornaoiteratorIterator<String>i=conjunto.iterator();while(i.hasNext()){//recebeapalavraStringpalavra=i.next();System.out.println(palavra);}

Owhile anterior só termina quando todos os elementos do conjunto forem percorridos, isto é,

quandoométodohasNextmencionarquenãoexistemmaisitens.

LISTITERATOR

Umalistafornece,alémdeacessoaumIterator,umListIterator,queoferecerecursos

adicionais,específicosparalistas.

UsandooListIterator,vocêpode,porexemplo,adicionarumelementonalistaouvoltar

paraoelementoquefoi"iterado"anteriormente.

USARITERATOREMVEZDOENHANCED-FOR?

OIteratorpodesimaindaserútil.Alémde iterarnacoleçãocomofazoenhanced-for,o

Iterator consegue remover elementos da coleção durante a iteração de uma forma elegante,

atravésdométodoremove.

15.10PARASABERMAIS:ITERANDOSOBRECOLEÇÕESCOMJAVA.UTIL.ITERATOR 223

Page 234: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Muitas vezes queremos buscar rapidamente um objeto dado alguma informação sobre ele. Umexemploseria,dadaaplacadocarro,obtertodososdadosdocarro.Poderíamosutilizarumalistaparaissoepercorrer todososseuselementos,mas issopodeserpéssimoparaaperformance,mesmoparalistasnãomuitograndes.Aquientraomapa.

Ummapaécompostoporumconjuntodeassociaçõesentreumobjetochaveaumobjetovalor.Éequivalenteaoconceitodedicionário,usadoemváriaslinguagens.Algumaslinguagens,comoPerlouPHP,possuemumsuportemaisdiretoamapas,ondesãoconhecidoscomomatrizes/arraysassociativas.

java.util.Map é um mapa, pois é possível usá-lo para mapear uma chave a um valor, por

exemplo: mapeie à chave "empresa" o valor "Caelum", ou então mapeie à chave "rua" ao valor"Vergueiro".Semelhanteaassociaçõesdepalavrasquepodemosfazeremumdicionário.

VocêpodetambémfazerocursodatadessaapostilanaCaelum

15.11MAPAS-JAVA.UTIL.MAP

224 15.11MAPAS-JAVA.UTIL.MAP

Page 235: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Ométodo put(Object, Object) da interface Map recebe a chave e o valor de uma nova

associação. Para saber o que está associado a um determinado objeto-chave, passa-se esse objeto nométodoget(Object).Semdúvidaessassãoasduasoperaçõesprincipaisemaisfrequentesrealizadas

sobreummapa.

Observeoexemplo:criamosduascontascorrenteseascolocamosemummapaassociando-asaosseusdonos.

ContaCorrentec1=newContaCorrente();c1.deposita(10000);

ContaCorrentec2=newContaCorrente();c2.deposita(3000);

//criaomapaMap<String,ContaCorrente>mapaDeContas=newHashMap<>();

//adicionaduaschaveseseusrespectivosvaloresmapaDeContas.put("diretor",c1);mapaDeContas.put("gerente",c2);

//qualacontadodiretor?(semcasting!)ContaCorrentecontaDoDiretor=mapaDeContas.get("diretor");System.out.println(contaDoDiretor.getSaldo());

Ummapaémuitousadopara"indexar"objetosdeacordocomdeterminadocritério,parapodermosbuscar esse objetos rapidamente. Ummapa costuma aparecer juntamente com outras coleções, parapoderrealizaressasbuscas!

Ele,assimcomoascoleções,trabalhadiretamentecomObjects(tantonachavequantonovalor),

o que tornaria necessário o casting nomomento que recuperar elementos.Usandoos generics, comofizemosaqui,nãoprecisamosmaisdocasting.

SuasprincipaisimplementaçõessãooHashMap,oTreeMapeoHashtable.

Apesardomapa fazerpartedo framework, elenãoestende a interfaceCollection, por ter um

comportamentobemdiferente.Porém,ascoleçõesinternasdeummapa(adechaveseadevalores,verFigura7)sãoacessíveispormétodosdefinidosnainterfaceMap.

15.11MAPAS-JAVA.UTIL.MAP 225

Page 236: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

OmétodokeySet()retornaumSetcomaschavesdaquelemapaeométodovalues()retorna

aCollectioncomtodososvaloresqueforamassociadosaalgumadaschaves.

UmmapaimportanteéatradicionalclasseProperties,quemapeiastringseémuitoutilizadapara

aconfiguraçãodeaplicações.

APropertiespossui,também,métodosparaleregravaromapeamentocombaseemumarquivo

texto,facilitandomuitoasuapersistência.

Propertiesconfig=newProperties();

config.setProperty("database.login","scott");config.setProperty("database.password","tiger");config.setProperty("database.url","jdbc:mysql:/localhost/teste");

//muitaslinhasdepois...

Stringlogin=config.getProperty("database.login");Stringpassword=config.getProperty("database.password");Stringurl=config.getProperty("database.url");DriverManager.getConnection(url,login,password);

ReparequenãohouveanecessidadedocastingparaStringnomomentoderecuperarosobjetos

associados. Isto porque a classe Properties foi desenhada com o propósito de trabalhar com a

15.12PARASABERMAIS:PROPERTIES

226 15.12PARASABERMAIS:PROPERTIES

Page 237: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

associaçãoentreStrings.

Muitas das coleções do java guardam os objetos dentro de tabelas de hash. Essas tabelas sãoutilizadasparaqueapesquisadeumobjetosejafeitademaneirarápida.

Como funciona? Cada objeto é "classificado" pelo seu hashCode e, com isso, conseguimos

espalharcadaobjetoagrupando-ospelohashCode.Quandobuscamosdeterminadoobjeto, sóvamos

procurar entre os elementos que estão no grupo daquele hashCode. Dentro desse grupo, vamos

testandooobjetoprocuradocomocandidatousandoequals().

Paraque issofuncionedireito,ométodohashCode de cadaobjetodeve retornaromesmovalor

paradoisobjetos,seelessãoconsideradosequals.Emoutraspalavras:

a.equals(b)implicaa.hashCode()==b.hashCode()

Implementar hashCode de tal maneira que ele retorne valores diferentes para dois objetos

consideradosequalsquebraocontratodeObjecteresultaráemcollectionsqueusamespalhamento

(comoHashSet,HashMapeHashtable),nãoachandoobjetosiguaisdentrodeumamesmacoleção.

EQUALSEHASHCODENOECLIPSE

O Eclipse é capaz de gerar uma implementação correta de equals e hashcode baseado nosatributosquevocêqueiracomparar.BastairnomenuSourceedepoisemGeneratehashcode()andequals().

15.13PARASABERMAIS:EQUALSEHASHCODE

15.13PARASABERMAIS:EQUALSEHASHCODE 227

Page 238: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

AscoleçõesdoJavaoferecemgrandeflexibilidadeaousuário.Aperdadeperformanceemrelaçãoàutilizaçãodearrayséirrelevante,masdeve-setomaralgumasprecauções:

Grandepartedas coleçõesusam, internamente, umarraypara armazenaros seusdados.Quandoessearraynãoémaissuficiente,écriadaummaioreoconteúdodaantigaécopiado.Esteprocessopodeacontecermuitasvezes,nocasodevocêterumacoleçãoquecrescemuito.Vocêdeve,então,criarumacoleçãojácomumacapacidadegrande,paraevitaroexcessoderedimensionamento.

Evite usar coleções que guardam os elementos pela sua ordem de comparação quando não hánecessidade.UmTreeSetgastacomputacionalmenteO(log(n)) para inserir (ele utiliza uma

árvorerubro-negracomoimplementação),enquantooHashSetgastaapenasO(1).

NãoiteresobreumaListutilizandoumforde0atélist.size()eusandoget(int)para

receberosobjetos.Enquantoissopareceatraente,algumasimplementaçõesdaListnãosãode

acesso aleatório como a LinkedList , fazendo esse código ter uma péssima performance

computacional.(useIterator)

1. Crieumcódigoqueinsira30milnúmerosnumaArrayListepesquise-os.Vamosusarummétodo

deSystemparacronometrarotempogasto:

publicclassTestaPerformance{

publicstaticvoidmain(String[]args){System.out.println("Iniciando...");Collection<Integer>teste=newArrayList<>();

Seuslivrosdetecnologiaparecemdoséculopassado?

15.14PARASABERMAIS:BOASPRÁTICAS

15.15EXERCÍCIOS:COLLECTIONS

228 15.14PARASABERMAIS:BOASPRÁTICAS

Page 239: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

longinicio=System.currentTimeMillis();

inttotal=30000;

for(inti=0;i<total;i++){teste.add(i);}

for(inti=0;i<total;i++){teste.contains(i);}

longfim=System.currentTimeMillis();longtempo=fim-inicio;System.out.println("Tempogasto:"+tempo);}}

TroqueaArrayListporumHashSeteverifiqueotempoquevaidemorar:

Collection<Integer>teste=newHashSet<>();

Oqueélento?Ainserçãode30milelementosouas30milbuscas?Descubracomputandootempogastoemcadaforseparadamente.

Adiferençaémaisquegritante.Sevocêpassarde30milparaumnúmeromaior,como50ou100mil,veráqueissoinviabilizaporcompletoousodeumaList,nocasoemquequeremosutilizá-la

essencialmenteempesquisas.

2. (conceitual,importante)Repareque,sevocêdeclararacoleçãoedernewassim:

Collection<Integer>teste=newArrayList<>();

emvezde:

ArrayList<Integer>teste=newArrayList<>();

É garantido que vai ter de alterar só essa linha para substituir a implementação porHashSet.

Estamosaquiusandoopolimorfismoparanosprotegerquemudançasde implementaçãovenhamnos obrigar a alterar muito código. Mais uma vez: programe voltado a interface, e não àimplementação!

Esse é um excelente exemplo de bom uso de interfaces, afinal, de que importa como a coleçãofunciona? O que queremos é uma coleção qualquer, isso é suficiente para os nossos propósitos!Nosso código está com baixoacoplamento em relação a estrutura de dados utilizada: podemostrocá-lafacilmente.

Esseéumcódigoextremamenteeleganteeflexível.Comotempovocêvairepararqueaspessoastentamprogramarsempresereferindoaessasinterfacesmenosespecíficas,namedidadopossível:métodos costumam receber e devolver Collections,Lists e Sets em vez de referenciar

diretamente uma implementação. É o mesmo que ocorre com o uso de InputStream e

15.15EXERCÍCIOS:COLLECTIONS 229

Page 240: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

OutputStream:elessãoosuficiente,nãoháporqueforçarousodealgomaisespecífico.

Obviamente,algumasvezesnãoconseguimostrabalhardessaformaeprecisamosusarumainterfacemaisespecíficaoumesmonosreferiraoobjetopelasuaimplementaçãoparapoderchamaralgunsmétodos. Por exemplo, TreeSet tem mais métodos que os definidos em Set, assim como

LinkedListemrelaçãoàList.

DêumexemplodeumcasoemquenãopoderíamosnosreferiraumacoleçãodeelementoscomoCollection,masnecessariamenteporinterfacesmaisespecíficascomoListouSet.

3. FaçatestescomoMap,comovistonessecapítulo:

publicclassTestaMapa{

publicstaticvoidmain(String[]args){Contac1=newContaCorrente();c1.deposita(10000);

Contac2=newContaCorrente();c2.deposita(3000);

//criaomapaMapmapaDeContas=newHashMap();

//adicionaduaschaveseseusvaloresmapaDeContas.put("diretor",c1);mapaDeContas.put("gerente",c2);

//qualacontadodiretor?ContacontaDoDiretor=(Conta)mapaDeContas.get("diretor");System.out.println(contaDoDiretor.getSaldo());}}

Depois,altereocódigoparausarogenericsenãohaveranecessidadedocasting,alémdagarantiadequenossomapaestaráseguroemrelaçãoatipagemusada.

VocêpodeutilizaroquickfixdoEclipseparaqueeleconserteissoparavocê:nalinhaemquevocêestáchamandooput,useoctrl+1.Depoisdemaisumquickfix(descubra!)seucódigodeve

ficarcomosegue:

//criaomapaMap<String,Conta>mapaDeContas=newHashMap<>();

Queopçãodoctrl+1vocêescolheuparaqueeleadicionasseogenericsparavocê?

4. (opcional)Assimcomonoexercício1, crieumacomparaçãoentreArrayList eLinkedList,

para ver qual é a mais rápida para se adicionar elementos na primeira posição (list.add(0,

elemento)),comoporexemplo:

publicclassTestaPerformanceDeAdicionarNaPrimeiraPosicao{publicstaticvoidmain(String[]args){System.out.println("Iniciando...");

230 15.15EXERCÍCIOS:COLLECTIONS

Page 241: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

longinicio=System.currentTimeMillis();

//trocardepoisporArrayListList<Integer>teste=newLinkedList<>();

for(inti=0;i<30000;i++){teste.add(0,i);}

longfim=System.currentTimeMillis();doubletempo=(fim-inicio)/1000.0;System.out.println("Tempogasto:"+tempo);}}

Seguindo o mesmo raciocínio, você pode ver qual é a mais rápida para se percorrer usando oget(indice) (sabemosqueocorreto seriautilizaroenhancedfor ouoIterator). Para isso,

insira30milelementosedepoispercorra-osusandocadaimplementaçãodeList.

Perceba que aqui o nosso intuito não é que você aprenda qual é o mais rápido, o importante éperceberquepodemostirarproveitodopolimorfismoparanoscomprometerapenascomainterface.Depois,quandonecessário,podemostrocareescolherumaimplementaçãomaisadequadaasnossasnecessidades.

Qualdasduaslistasfoimaisrápidaparaadicionarelementosàprimeiraposição?

5. (opcional) Crie a classe Banco (caso não tenha sido criada anteriormente) no pacote

br.com.caelum.contas.modeloquepossuiumaListdeContachamadacontas.Repareque

numalistadeConta,vocêpodecolocartantoContaCorrentequantoContaPoupancaporcausa

dopolimorfismo.

Crie ummétodo void adiciona(Conta c), ummétodo Conta pega(int x) e outro int

pegaQuantidadeDeContas().Basta usar a sua lista e delegar essas chamadaspara osmétodos e

coleçõesqueestudamos.

ComoficouaclasseBanco?

6. (opcional)NoBanco,crieummétodoContabuscaPorTitular(Stringnome)queprocurapor

umaContacujotitularsejaequalsaonomeDoTitulardado.

Vocêpode implementaressemétodocomumfor na sua lista deConta, porémnão temuma

performanceeficiente.

Adicionando um atributo privado do tipo Map<String,Conta> terá um impacto significativo.

Toda vez que o método adiciona(Conta c) for invocado, você deve invocar

.put(c.getTitular(),c)noseumapa.Dessamaneira,quandoalguéminvocarométodoConta

buscaPorTitular(String nomeDoTitular), basta você fazer o get no seu mapa, passando

15.15EXERCÍCIOS:COLLECTIONS 231

Page 242: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

nomeDoTitularcomoargumento!

Note, apenas, que isso é só um exercício!Dessa forma você não poderá ter dois clientes com omesmonomenessebanco,oquesabemosquenãoélegal.

ComoficariasuaclasseBancocomesseMap?

7. (opcional, avançado) Crie o método hashCode para a sua conta, de forma que ele respeite o

equalsdequeduascontassãoequalsquandotemomesmonúmeroeagência.Felizmentepara

nós, o próprio Eclipse já vem com um criador de equals e hashCode que os faz de forma

consistente.

NaclasseConta,useoctrl+3ecomeceaescreverhashCodeparaacharaopçãodegerá-los.

Então,selecioneosatributosnumeroeagenciaemandegerarohashCodeeoequals.

Comoficouocódigogerado?

8. (opcional, avançado) Crie uma classe de teste e verifique se sua classe Conta funciona agora

corretamenteemumHashSet,istoé,queelanãoguardacontascomnúmeroeagênciarepetidos.

Depois,removaométodohashCode.Continuafuncionando?

DominarousoeofuncionamentodohashCodeéfundamentalparaobomprogramador.

1. Gere todosos números entre 1 e 1000 e ordene emordemdecrescente utilizandoumTreeSet.

Comoficouseucódigo?

2. Geretodososnúmerosentre1e1000eordeneemordemdecrescenteutilizandoumArrayList.

Comoficouseucódigo?

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

15.16DESAFIOS

Agoraéamelhorhoradeaprenderalgonovo

232 15.16DESAFIOS

Page 243: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

E se precisarmos ordernar uma lista com outro critério de comparação? Se precisarmos alterar aprópriaclasseemudarseumétodocompareTo, teremos apenasuma formade comparaçãopor vez.

Precisamosdemais!

É possível definir outros critérios de ordenação usando a interface do java.util chamada

Comparator . Existe um método sort em Collections que recebe, além da List , um

Comparatordefinindoumcritériodeordenaçãoespecífico.ÉpossívelterváriosComparatorscom

critériosdiferentesparausarquandofornecessário.

VamoscriarumComparatorqueserveparaordernarStringsdeacordocomseutamanho.

classComparadorPorTamanhoimplementsComparator<String>{publicintcompare(Strings1,Strings2){if(s1.length()<s2.length())return-1;if(s2.length()<s1.length())return1;return0;}}

Repare que, diferente de Comparable , o método aqui se chama compare e recebe dois

argumentos,jáquequemoimplementanãoéopróprioobjeto.

Podemosdeixá-lomaiscurto,tomandoproveitodométodoestáticoauxiliarInteger.compareque

comparadoisinteiros:

classComparadorPorTamanhoimplementsComparator<String>{publicintcompare(Strings1,Strings2){returnInteger.compare(s1.length(),s2.length());}}

Depois, dentro do nosso código, teríamos uma chamada a Collections.sort passando o

comparadortambém:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

//invocandoosortpassandoocomparadorComparadorPorTamanhocomparador=newComparadorPorTamanho();Collections.sort(lista,comparador);

System.out.println(lista);

Comoavariáveltemporáriacomparadoréutilizadaapenasaí,écomumescrevermosdiretamente

Collections.sort(lista,newComparadorPorTamanho()).

15.17 PARA SABER MAIS: COMPARATORS, CLASSES ANÔNIMAS,JAVA8EOLAMBDA

15.17PARASABERMAIS:COMPARATORS,CLASSESANÔNIMAS,JAVA8EOLAMBDA 233

Page 244: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Repareque a classeComparadorPorTamanho é bempequena.É comumhaver a necessidade de

criarvárioscritériosdecomparação,emuitasvezeselessãoutilizadosapenasnumúnicopontodonossoprograma.

Háumaformadeescreveressaclasseeinstanciá-lanumaúnicainstrução.Vocêfazissodandonew

emComparator.Mascomo,sedissemosqueumainterfacenãopodeserinstanciada?Realmentenew

Comparator() não compila. Mas vai compilar se você abrir chaves e implementar tudo o que é

necessário.Vejaocódigo:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

Comparator<String>comparador=newComparator<String>(){publicintcompare(Strings1,Strings2){returnInteger.compare(s1.length(),s2.length());}};Collections.sort(lista,comparador);

System.out.println(lista);

Asintaxeérealmenteesdrúxula!Numaúnicalinhanósdefinimosumaclasseeainstanciamos!Umaclassequenemmesmonometem.Poressemotivoorecursoéchamadodeclasseanônima.Eleaparececomcertafrequência,emespecialparanãoprecisarimplementarinterfacesqueocódigodosmétodosseriammuitocurtosenão-reutilizáveis.

Há ainda como diminuir ainda mais o código, evitando a criação da variável temporáriacomparadoreinstanciandoainterfacedentrodainvocaçãoparaosort:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

Collections.sort(lista,newComparator<String>(){publicintcompare(Strings1,Strings2){returnInteger.compare(s1.length(),s2.length());}});

System.out.println(lista);

VocêpodefazerodownloaddoJava8aqui:

https://jdk8.java.net/download.html

EscrevendoumComparatorcomclasseanônima

EscrevendoumComparatorcomlambdanoJava8

234 15.17PARASABERMAIS:COMPARATORS,CLASSESANÔNIMAS,JAVA8EOLAMBDA

Page 245: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

O Eclipse já possui atualizações para compatibilidade com a nova versão, mas ele pode serrelativamenteinstável.Vocêpodeutilizaralinhadecomando,comofizemosnocomeçodocurso,paraessestestes,casoachenecessário.

ApartirdessanovaversãodoJavaháumaformamaissimplesdeobteressemesmoComparator.

Repare:

Collections.sort(lista,(s1,s2)->Integer.compare(s1.length(),s2.length()));

Ocódigo(s1,s2)->Integer.compare(s1.length(),l2.length())geraráumainstânciade

ComparatorqueocomparedevolveInteger.compare(s1.length,l2.length).Atémesmoo

returnnãoénecessário,jáquesótemosumainstruçãoapóso->.Esseéorecursodelambdado

Java8.

Uma outra novidade do Java 8 é a possibilidade de declarar métodos concretos dentro de umainterface,oschamadosdefaultmethods.Atéo Java7nãoexistiasort em listas.Colocar umnovo

métodoabstratoemuma interfacepode terconsequênciasdrásticas: todomundoquea implementavaparadecompilar!Mascolocarummétododefaultnãotemessemesmoimpactodevastador, jáqueasclassesqueimplementamainterface'herdam'essemétodo.Entãovocêpodefazer:

lista.sort((s1,s2)->Integer.compare(s1.length(),s2.length()));

Háoutrosmétodosnascoleçõesqueutilizamdolambdaparaseremmaissucintos.

UmdeleséoforEach.Vocêpodefazerlista.forEach(s->System.out.println(s)).

OremoveIféoutrodeles.Porexemplo,podemosescreverlista.removeIf(c->c.getSaldo()

<0).OremoveIfrecebecomoargumentoumobjetoqueimplementeainterfacePredicate,que

possuiapenasummétodo,querecebeumelementedevolveboolean.Porpossuirapenasummétodo

abstrato também chamamos essa interface é uma interface funcional. Omesmo ocorre ao invocar oforEach,querecebeumargumentoqueimplementaainterfacefuncionalConsumer.

TrabalharcomlambdasnoJava8vaimuitoalém.Hádiversosdetalheserecursosquenãoveremosnesseprimeirocurso.Casotenhacuriosidadeequeirasabermais,vejanoblog:

http://blog.caelum.com.br/o-minimo-que-voce-deve-saber-de-java-8/

Mais?Methodreferences,streamsecollectors

15.17PARASABERMAIS:COMPARATORS,CLASSESANÔNIMAS,JAVA8EOLAMBDA 235

Page 246: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO16

"Abenevolênciaésobretudoumvíciodoorgulhoenãoumavirtudedaalma." --DoantienAlphonseFrançois(MarquêsdeSade)

Aotérminodessecapítulo,vocêserácapazde:

usarasclasseswrappers(comoInteger)eboxing;

lereescreverbytes,caractereseStringsde/paraaentradaesaídapadrão;lereescreverbytes,caractereseStringsde/paraarquivos;utilizarbuffersparaagilizaraleituraeescritaatravésdefluxos;usarScannerePrintStream.

VamospassaraconhecerAPIsdoJava.java.ioejava.utilpossuemasclassesquevocêmais

comumentevaiusar,nãoimportandoseseuaplicativoédesktop,web,oumesmoparacelulares.

Apesardeserimportanteconhecernomesemétodosdasclassesmaisutilizadas,ointeressanteaquiéquevocêenxerguequetodososconceitospreviamenteestudadossãoaplicadosatodahoranasclassesdabibliotecapadrão.

Nãosepreocupeemdecorarnomes.Atenha-seementendercomoessasclassesestãorelacionadasecomoelasestãotirandoproveitodousodeinterfaces,polimorfismo,classesabstrataseencapsulamento.Lembre-sedeestarcomadocumentação(javadoc)abertaduranteocontatocomessespacotes.

Veremos também threads e sockets em capítulos posteriores, que ajudarão a condensar nossoconhecimento, tendo em vista que no exercício de sockets utilizaremos todos conceitos aprendidos,juntamentecomasváriasAPIs.

PACOTEJAVA.IO

16.1CONHECENDOUMAAPI

236 16PACOTEJAVA.IO

Page 247: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

AssimcomotodoorestodasbibliotecasemJava,apartedecontroledeentradaesaídadedados(conhecidocomoio)éorientadaaobjetoseusaosprincipaisconceitosmostradosatéagora:interfaces,classesabstratasepolimorfismo.

Aideiaatrásdopolimorfismonopacotejava.ioédeutilizarfluxosdeentrada(InputStream)e

desaída(OutputStream)paratodaequalqueroperação,sejaelarelativaaumarquivo,aumcampoblobdobancodedados,aumaconexãoremotaviasockets,ouatémesmoàsentradaesaídapadrãodeumprograma(normalmenteotecladoeoconsole).

AsclassesabstratasInputStreameOutputStreamdefinem,respectivamente,ocomportamento

padrãodosfluxosemJava:emumfluxodeentrada,épossívellerbytese,nofluxodesaída,escreverbytes.

A grande vantagem dessa abstração pode ser mostrada em um método qualquer que utiliza umOutputStreamrecebidocomoargumentoparaescreveremumfluxodesaída.Paraondeométodoestá

escrevendo?Nãosesabeenãoimporta:quandoosistemaprecisarescreveremumarquivoouemumasocket,bastachamaromesmométodo,jáqueeleaceitaqualquerfilhadeOutputStream!

Paralerumbytedeumarquivo,vamosusaroleitordearquivo,oFileInputStream.Paraum

FileInputStreamconseguirlerumbyte,eleprecisasaberdeondeeledeveráler.Essainformaçãoé

tãoimportantequequemescreveuessaclasseobrigavocêapassaronomedoarquivopeloconstrutor:semissooobjetonãopodeserconstruído.

classTestaEntrada{

EditoraCasadoCódigocomlivrosdeumaformadiferente

16.2ORIENTAÇÃOAOBJETOSNOJAVA.IO

16.3INPUTSTREAM,INPUTSTREAMREADEREBUFFEREDREADER

16.2ORIENTAÇÃOAOBJETOSNOJAVA.IO 237

Page 248: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");intb=is.read();}}

A classe InputStream é abstrata e FileInputStream uma de suas filhas concretas.

FileInputStream vai procurar o arquivo no diretório em que a JVM fora invocada (no caso do

Eclipse,vaiserapartirdedentrododiretóriodoprojeto).Alternativamentevocêpodeusarumcaminhoabsoluto.

Quandotrabalhamoscomjava.io,diversosmétodoslançamIOException,queéumaexception

do tipo checked - o que nos obriga a tratá-la ou declará-la.Nos exemplos aqui, estamos declarandoIOExceptionatravésdaclausulathrowsdomainapenasparafacilitaroexemplo.Casoaexception

ocorra,aJVMvaiparar,mostrandoastacktrace.Estanãoéumaboapráticaemumaaplicaçãoreal:tratesuasexceptionsparasuaaplicaçãopoderabortarelegantemente.

InputStream tem diversas outras filhas, como ObjectInputStream , AudioInputStream ,

ByteArrayInputStream,entreoutras.

Para recuperarumcaractere,precisamos traduzirosbytescomoencodingdadoparao respectivocódigo unicode, isso pode usar um oumais bytes. Escrever esse decodificador émuito complicado,quemfazissoporvocêéaclasseInputStreamReader.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);intc=isr.read();}}

OconstrutordeInputStreamReaderpodereceberoencodingaserutilizadocomoparâmetro,se

desejado,talcomoUTF-8ouISO-8859-1.

ENCODINGS

Devidoagrandequantidadedeaplicativosinternacionalizadosdehojeemdia,éimprescindívelqueumbomprogramadorentendabemoquesãooscharacterencodingseoUnicode.OblogdaCaelumpossuiumbomartigoarespeito:

http://blog.caelum.com.br/2006/10/22/entendendo-unicode-e-os-character-encodings/

InputStreamReader é filhada classe abstrataReader, quepossui diversas outras filhas - são

classesquemanipulamchars.

238 16.3INPUTSTREAM,INPUTSTREAMREADEREBUFFEREDREADER

Page 249: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ApesardaclasseabstrataReader jáajudarnotrabalhodemanipulaçãodecaracteres,aindaseria

difícilpegarumaString.AclasseBufferedReaderéumReaderquerecebeoutroReaderpelo

construtoreconcatenaosdiversoscharsparaformarumaStringatravésdométodoreadLine:

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);Strings=br.readLine();}}

Como o próprio nome diz, essa classe lê doReader por pedaços (usando o buffer) para evitar

realizarmuitas chamadasao sistemaoperacional.Vocêpodeaté configuraro tamanhodobufferpeloconstrutor.

Éessaacomposiçãodeclassesqueestáacontecendo:

Essepadrãodecomposiçãoébastanteutilizadoeconhecido.ÉoDecoratorPattern.

Aqui,lemosapenasaprimeiralinhadoarquivo.OmétodoreadLinedevolvealinhaquefoilidae

muda o cursor para a próxima linha. Caso ele chegue ao fim do Reader (no nosso caso, fim do

arquivo),elevaidevolvernull.Então,comumsimpleslaço,podemosleroarquivoporinteiro:

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);

Strings=br.readLine();//primeiralinha

while(s!=null){System.out.println(s);s=br.readLine();}

br.close();}}

16.4LENDOSTRINGSDOTECLADO

16.4LENDOSTRINGSDOTECLADO 239

Page 250: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Com um passe de mágica, passamos a ler do teclado em vez de um arquivo, utilizando oSystem.in,queéumareferênciaaumInputStreamoqual,porsuavez,lêdaentradapadrão.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=System.in;InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);Strings=br.readLine();

while(s!=null){System.out.println(s);s=br.readLine();}}}

Apenasmodificamosaquemavariávelisestásereferindo.Podemosreceberargumentosdotipo

InputStream e ter esse tipo de abstração: não importa exatamente de onde estamos lendo esse

punhadodebytes,desdequeagenterecebaainformaçãoqueestamosquerendo.Comonafigura:

Repare que a ponta da direita poderia ser qualquer InputStream, seja ObjectInputStream,

AudioInputStream,ByteArrayInputStream, ou a nossa FileInputStream. Polimorfismo! Ou

vocêmesmopodecriarumafilhadeInputStream,sedesejar.

Por isso émuito comummétodos recebereme retornaremInputStream, em vez de suas filhas

específicas. Com isso, elas desacoplam as informações e escondem a implementação, facilitando amudançaemanutençãodocódigo.Reparequeissovaiaoencontrodetudooqueaprendemosduranteoscapítulosqueapresentaramclassesabstratas,interfaces,polimorfismoeencapsulamento.

240 16.4LENDOSTRINGSDOTECLADO

Page 251: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Comovocêpodeimaginar,escreveremumarquivoéomesmoprocesso:

classTestaSaida{publicstaticvoidmain(String[]args)throwsIOException{OutputStreamos=newFileOutputStream("saida.txt");OutputStreamWriterosw=newOutputStreamWriter(os);BufferedWriterbw=newBufferedWriter(osw);

bw.write("caelum");

bw.close();}}

Lembre-sededarrefresh(cliquedadireitanonomedoprojeto,refresh)noseuprojetodoEclipseparaqueoarquivocriadoapareça.OFileOutputStream pode receber umbooleano como segundo

parâmetro,paraindicarsevocêquerreescreveroarquivooumanteroquejáestavaescrito(append).

OmétodowritedoBufferedWriternãoinsereo(s)caractere(s)dequebradelinha.Paraisso,

vocêpodechamarométodonewLine.

JáconheceoscursosonlineAlura?

16.5AANALOGIAPARAAESCRITA:OUTPUTSTREAM

16.5AANALOGIAPARAAESCRITA:OUTPUTSTREAM 241

Page 252: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

FECHANDOOARQUIVOCOMOFINALLYEOTRY-WITH-RESOURCES

Éimportantesemprefecharoarquivo.Vocêpodefazer issochamandodiretamenteométodo close do FileInputStream / OutputStream , ou ainda chamando o close do

BufferedReader/Writer.Nesseúltimocaso,ocloseserácascateadoparaosobjetososquais

oBufferedReader/Writer utiliza para realizar a leitura/escrita, além dele fazer o flush dosbuffersnocasodaescrita.

Écomumefundamentalqueocloseestejadentrodeumblocofinally.Seumarquivofor

esquecidoabertoea referênciaparaele forperdida,podeserqueele seja fechadopelogarbagecollector,queveremosmaisafrente,porcausadofinalize.Masnãoébomvocêseprendera

isso. Se você esquecer de fechar o arquivo, no caso de um programa minúsculo como esse, oprogramavaiterminarantesqueotaldogarbagecollectorteajude,resultandoemumarquivonãoescrito(osbytesficaramnobufferdoBufferedWriter).Problemassimilarespodemacontecer

comleitoresquenãoforemfechados.

No Java 7 há a estrutura try-with-resources, que já fará o finally cuidar dos recursos

declarados dentro do try(), invocando close. Pra isso, os recursos devem implementar a

interfacejava.lang.AutoCloseable, que é o caso dos Readers,Writers e Streams estudados

aqui:

try(BufferedReaderbr=newBufferedReader(newFile("arquivo.txt"))){//comexceçãoounão,oclose()dobrserainvocado}

ApartirdoJava5,temosaclassejava.util.Scanner,quefacilitabastanteotrabalhodelerde

umInputStream.Alémdisso,aclassePrintStreampossuiumconstrutorquejárecebeonomede

umarquivocomoargumento.Dessaforma,aleituradotecladocomsaídaparaumarquivoficoumuitosimples:

Scanners=newScanner(System.in);PrintStreamps=newPrintStream("arquivo.txt");while(s.hasNextLine()){ps.println(s.nextLine());}

Nenhumdosmétodos lançaIOException:PrintStream lança FileNotFoundException se

vocêoconstruirpassandoumaString.EssaexceçãoéfilhadeIOExceptioneindicaqueoarquivo

nãofoiencontrado.OScannerconsideraráquechegouaofimseumaIOExceptionforlançada,mas

16.6UMAMANEIRAMAISFÁCIL:SCANNEREPRINTSTREAM

242 16.6UMAMANEIRAMAISFÁCIL:SCANNEREPRINTSTREAM

Page 253: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

o PrintStream simplesmente engole exceptions desse tipo. Ambos possuem métodos para você

verificarsealgumproblemaocorreu.

AclasseScanner édopacotejava.util.Ela possuimétodosmuitoúteis para trabalhar com

Strings, em especial, diversos métodos já preparados para pegar números e palavras já formatadasatravésdeexpressõesregulares.Ficafácilparsearumarquivocomqualquerformatodado.

SYSTEM.OUT

Comovimosnocapítulopassado,oatributooutdaclasseSystemédotipoPrintStream

(e,portanto,éumOutputStream).

EOF

Quando rodar sua aplicação, para encerrar a entrada de dados do teclado, é necessárioenviarmosumsinaldefimdestream.ÉofamosoEOF,istoé,endoffile.

NoLinux/Mac/Solaris/Unixvocêfazissocomoctrl+D.NoWindows,useoctrl+Z.

Existemduasclasseschamadasjava.io.FileReaderejava.io.FileWriter.Elassãoatalhos

paraaleituraeescritadearquivos.

Odo { .. } while(condicao); é uma alternativa para se construir um laço. Pesquise-o e

utilize-onocódigoparalerumarquivo,elevaificarmaissucinto(vocênãoprecisaráleraprimeiralinhaforadolaço).

16.7UMPOUCOMAIS...

16.7UMPOUCOMAIS... 243

Page 254: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Anteriormente, vimos que conseguimos ler e escrever dados emumarquivo no Java utilizando aclasseScanner. Por padrão, quando fazemos essas operações, estamos trabalhando sempre comos

dadosemformadeString.Maseseprecisássemoslerouescrevernúmerosinteirosemumarquivo?

ComofaríamosparatransformaressesnúmerosemStringevice-versa?

Cuidado!Usamosaquiotermo"transformar",porémoqueocorrenãoéumatransformaçãoentreostiposesimumaformadeconseguirmosumStringdadoumintevice-versa.Ojeitomaissimples

detransformarumnúmeroemStringéconcatená-lodaseguintemaneira:

inti=100;Strings=""+i;System.out.println(s);

doubled=1.2;Strings2=""+d;System.out.println(s2);

Paraformataronúmerodeumamaneiradiferente,comvírgulaenúmerodecasasdecimaisdevemosutilizaroutrasclassesdeajuda(NumberFormat,Formatter).

ParatransformarumaStringemnúmero,utilizamosasclassesdeajudaparaostiposprimitivos

correspondentes. Por exemplo, para transformar a String s em um número inteiro utilizamos o

métodoestáticodaclasseInteger:

Strings="101";inti=Integer.parseInt(s);

As classes Double, Short, Long , Float etc contêm o mesmo tipo de método, como

parseDoubleeparseFloatqueretornamumdoubleefloatrespectivamente.

Essas classes também sãomuitoutilizadaspara fazer owrapping (embrulho) de tiposprimitivos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

16.8INTEGERECLASSESWRAPPERS(BOX)

244 16.8INTEGERECLASSESWRAPPERS(BOX)

Page 255: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

como objetos, pois referências e tipos primitivos são incompatíveis. Imagine que precisamos passarcomoargumentouminteiroparaonossoguardadordeobjetos.UminteironãoéumObject, como

fazer?

inti=5;Integerx=newInteger(i);guardador.adiciona(x);

E,dadoumInteger,podemospegarointqueestádentrodele(desembrulhá-lo):

inti=5;Integerx=newInteger(i);intnumeroDeVolta=x.intValue();

Esse processo de wrapping e unwrapping é entediante. O Java 5.0 em diante traz um recursochamadodeautoboxing,quefazissosozinhoparavocê,custandolegibilidade:

Integerx=5;inty=x;

NoJava1.4essecódigoéinválido.NoJava5.0emdianteelecompilaperfeitamente.Éimportanteressaltar que isso não quer dizer que tipos primitivos e referências sejam do mesmo tipo, isso ésimplesmenteum"açúcarsintático"(syntaxsugar)parafacilitaracodificação.

Vocêpodefazertodosostiposdeoperaçõesmatemáticascomoswrappers,porémcorreoriscodetomarumNullPointerException.

Você pode fazer o autoboxing diretamente paraObject também, possibilitando passar um tipo

primitivoparaummétodoquereceberObjectcomoargumento:

Objecto=5;

NaclasseMath,existeumasériedemétodosestáticosquefazemoperaçõescomnúmeroscomo,

por exemplo, arredondar(round), tirar o valor absoluto (abs), tirar a raiz(sqrt), calcular o

seno(sin)eoutros.

doubled=4.6;longi=Math.round(d);

intx=-4;inty=Math.abs(x);

Consulteadocumentaçãoparaveragrandequantidadedemétodosdiferentes.

NoJava5.0,podemostirarproveitodoimportstaticaqui:

16.9AUTOBOXINGNOJAVA5.0

16.10PARASABERMAIS:JAVA.LANG.MATH

16.9AUTOBOXINGNOJAVA5.0 245

Page 256: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

importstaticjava.lang.Math.*;

Issoeliminaanecessidadedeusaronomedaclasse,sobocustodelegibilidade:

doubled=4.6;longi=round(d);intx=-4;inty=abs(x);

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Vamossalvarascontascadastradasemumarquivoparanãoprecisarficaradicionandoascontasatodomomento.

1. NaclasseManipuladorDeContas,crieométodosalvaDadosquerecebeumEvento de onde

obteremosalistadecontas:

publicvoidsalvaDados(Eventoevento){List<Conta>contas=evento.getLista("listaContas");//aquisalvaremosascontasemarquivo}

2. Para não colocarmos todo o código de gerenciamento de arquivos dentro da classeManipuladorDeContas,vamoscriarumanovaclassecujaresponsabilidadeserálidarcomaescrita

/ leitura de arquivos. Crie a classe RepositorioDeContas dentro do pacote

br.com.caelum.contasedeclareométodosalvaquedeveráreceberalistadecontasaserem

guardadas.Nestemétodovocêdevepercorreralistadecontasesalvá-lasseparandoasinformaçõesdetipo,numero,agencia,titularesaldocomvírgulas.Ocódigoficaráparecidocom:

publicclassRepositorioDeContas{

publicvoidsalva(List<Conta>contas){PrintStreamstream=newPrintStream("contas.txt");for(Contaconta:contas){

Seuslivrosdetecnologiaparecemdoséculopassado?

16.11EXERCÍCIOS:JAVAI/O

246 16.11EXERCÍCIOS:JAVAI/O

Page 257: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

stream.println(conta.getTipo()+","+conta.getNumero()+","+conta.getAgencia()+","+conta.getTitular()+","+conta.getSaldo());}stream.close();}}

O compilador vai reclamar que você não está tratando algumas exceções (comojava.io.FileNotFoundException).Utilize o devidotry/catch e relance a exceção como

RuntimeException.UtilizeoquickfixdoEclipseparafacilitar(ctrl+1).

Vale lembrarquedeixar todasasexceptionspassaremdespercebidasnãoéumaboaprática!Vocêpodeusaraqui,poisestamosfocandoapenasnoaprendizadodautilizaçãodojava.io.

Quandotrabalhamoscomrecursosquefalamcomaparteexternaànossaaplicação,éprecisoqueavisemosquandoacabarmosdeusaressesrecursos.Porisso,éimportantíssimolembrardefecharoscanaiscomoexteriorqueabrimosutilizandoométodoclose!

3. Voltando à classe ManipuladorDeContas, vamos completar o método salvaDados para que

utilizeanossanovaclasseRepositorioDeContascriada.

publicvoidsalvaDados(Eventoevento){List<Conta>contas=evento.getLista("listaContas");RepositorioDeContasrepositorio=newRepositorioDeContas();repositorio.salva(contas);}

Rodesuaaplicação,cadastrealgumascontasevejaseapareceumarquivochamadocontas.txt

dentrododiretóriosrcdeseuprojeto.TalvezsejanecessáriodarumF5neleparaqueoarquivo

apareça.

4. (Opcional,Difícil)Vamosfazercomquealémdesalvarosdadosemumarquivo,nossaaplicaçãotambém consiga carregar as informações das contas para já exibir na tela. Para que a aplicaçãofuncione, é necessário que a nossa classe ManipuladorDeContas possua um método chamado

carregaDados que devolva uma List<Conta>. Vamos fazer o mesmo que anteriormente e

encapsularalógicadecarregamentodentrodaclasseRepositorioDeContas:

publicList<Conta>carregaDados(){RepositorioDeContasrepositorio=newRepositorioDeContas();returnrepositorio.carrega();}

Faça o código referente ao método carrega que devolve uma List dentro da classe

RepositorioDeContasutilizandoaclasseScanner.Paraobterosvaloresdecadaatributovocê

podeutilizarométodosplitdaString.Lembre-sequeosatributosdascontassãocarregados

naseguinteordem:tipo,numero,agencia,titularesaldo.Exemplo:

Stringlinha=scanner.nextLine();

16.11EXERCÍCIOS:JAVAI/O 247

Page 258: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

String[]valores=linha.split(",");Stringtipo=valores[0];

Alémdisso,acontadeveserinstanciadadeacordocomoconteúdodotipoobtido.Tambémfique

atentopois os dados lidosvirão sempre lidos em formadeString e para alguns atributos será

necessáriotransformarodadonostiposprimitivoscorrespondentes.Porexemplo:

StringnumeroTexto=valores[1];intnumero=Integer.parseInt(numeroTexto);

5. (opcional) A classe Scanner é muito poderosa! Consulte seu javadoc para saber sobre o

delimitereosoutrosmétodosnext.

6. (opcional) Crie uma classe TestaInteger e vamos fazer comparações com Integers dentro do

main:

Integerx1=newInteger(10);Integerx2=newInteger(10);

if(x1==x2){System.out.println("igual");}else{System.out.println("diferente");}

Esetestarmoscomoequals?Oquepodemosconcluir?

7. (opcional)Umdoublenãoestásendosuficienteparaguardaraquantidadedecasasnecessáriasem

umaaplicação.Precisoguardarumnúmerodecimalmuitogrande!Oquepoderiausar?

Odouble tambémtemproblemasdeprecisãoaofazercontas,porcausadearredondamentosda

aritméticadepontoflutuantedefinidopelaIEEE754:

http://en.wikipedia.org/wiki/IEEE_754

Elenãodeveserusadosevocêprecisarealmentedemuitaprecisão(casosqueenvolvamdinheiro,porexemplo).

Consulteadocumentação,tenteadivinharondevocêpodeencontrarumtipoqueteajudariapararesolveressescasosevejacomoéintuitivo!Qualéaclassequeresolveriaessesproblemas?

Lembre-se:noJavahámuitojápronto.Sejanabibliotecapadrão,sejaembibliotecasopen sourcequevocêpodeencontrarpelainternet.

Aplicarbemosconceitosdeorientaçãoaobjetosésempreumagrandedúvida.Semprequeremosencapsular direito, favorecer a flexibilidade, desacoplar classes, escrever código elegante e de fácil

16.12 DISCUSSÃO EM AULA: DESIGN PATTERNS E O TEMPLATEMETHOD

248 16.12DISCUSSÃOEMAULA:DESIGNPATTERNSEOTEMPLATEMETHOD

Page 259: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

manutenção.EouvimosfalarqueaOrientaçãoaObjetosajudaemtudoisso.

Mas,ondeusarherançadeformasaudável?Comousarinterfaces?Ondeopolimorfismomeajuda?Comoencapsulardireito?Classesabstratassãousadasemquesituações?

Muitos anos atrás, grandes nomes domundo da orientação a objetos perceberam que criar bonsdesigns orientados a objetos era um grande desafio para muitas pessoas. Perceberam que muitosproblemas de OO apareciam recorrentemente em vários projetos; e que as pessoas já tinham certassoluçõesparaessesproblemasclássicos(nemsempremuitoelegantes).

O que fizeram foi criar soluções padrões para problemas comuns na orientação a objetos, echamaramissodeDesignPatterns, ouPadrõesdeProjeto.O conceito vinhada arquitetura onde eramuitocomumteressetipodesolução.E,em1994,ganhougrandepopularidadenacomputaçãocomolivroDesignPatterns:ElementsofReusableObject-OrientedSoftware,umcatálogocomváriasdessassoluções escrito por Erich Gamma, Ralph Johnson, Richard Helm e John Vlissides (a Gangue dosQuatro,GoF).

DesignPatterns tornou-sereferênciaabsolutanobomusodaorientaçãoaobjetos.Outrospadrõessurgiram depois, em outras literaturas igualmente consagradas. O conhecimento dessas técnicas éimprescindívelparaobomprogramador.

DiscutacomoinstrutorcomoDesignPatternsajudamaresolverproblemasdemodelagememsistemas orientados a objetos. Veja como Design Patterns são aplicados em muitos lugares dopróprioJava.

OinstrutorcomentarádoTemplateMethodemostraráocódigofontedométodoread()daclasse

java.io.InputStream:

publicintread(byteb[],intoff,intlen)throwsIOException{if(b==null){thrownewNullPointerException();}elseif(off<0||len<0||len>b.length-off){thrownewIndexOutOfBoundsException();}elseif(len==0){return0;}

intc=read();if(c==-1){return-1;}

b[off]=(byte)c;

inti=1;try{for(;i<len;i++){c=read();if(c==-1){break;}

16.12DISCUSSÃOEMAULA:DESIGNPATTERNSEOTEMPLATEMETHOD 249

Page 260: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

b[off+i]=(byte)c;}}catch(IOExceptionee){}returni;}

Discuta em aula como esse método aplica conceitos importantes da orientação a objetos epromoveflexibilidadeeextensibilidade.

250 16.12DISCUSSÃOEMAULA:DESIGNPATTERNSEOTEMPLATEMETHOD

Page 261: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO17

"Aprimeiracoisaaentenderéquevocênãoentende."--SorenAabyeKierkegaard

Ondecontinuarao terminarosexercíciosde 'JavaeOrientaçãoaObjetos'?Aquiháumpostcomsugestõesdecomoiniciarnacarreira:

http://blog.caelum.com.br/como-posso-aprender-java-e-iniciar-na-carreira/

Evocêpodeseguirnessescursoseáreas:

Umdos principais usos do Java é rodar aplicaçõesweb. Entram aqui tecnologias comoServlets,JSPseferramentasfamosasdomercado,comooStruts.

ACaelum oferece o curso FJ-21, onde você pode estudar os tópicos necessários para começar atrabalharcomJavanawebusandoasmelhorespráticas,designpatternsetecnologiasdomercado.Essaapostilatambémestádisponívelparadownload.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

A melhor maneira para fixar tudo o que foi visto nos capítulos anteriores é planejar e montarpequenos sistemas. Pense na modelagem de suas classes, como e onde usar herança, polimorfismo,

EAGORA?

17.1WEB

Agoraéamelhorhoradeaprenderalgonovo

17.2PRATICANDOJAVAEUSANDOBIBLIOTECAS

17EAGORA? 251

Page 262: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

encapsulamentoeoutrosconceitos.PratiqueousodasAPIsmaisúteisdoJava integrando-asaoseussistemas.

OcursoFJ-22 éum laboratórioque alémdedemonstrarousodiversasAPIs eboaspráticas, vaimostrardiversosdesignpatternseseuscasosdeuso.

Diversosprogramadorescomomínimooumáximodeconhecimentosereúnemonlineparaatrocadedúvidas,informaçõeseideiassobreprojetos,bibliotecasemuitomais.Sãoosgruposdeusuáriosdejava.

UmdosmaisimportanteseconhecidosnoBrasiléoGUJ:

http://www.guj.com.br

O'FalandoemJava'nãopáraporaqui.ACaelumofereceumagrandevariedadedecursosquevocêpodeseguir.Algunsdosmaisrequisitados:

FJ-21:JavaparadesenvolvimentoWeb

FJ-22:LaboratórioJavacomTestes,JSF,WebServiceseDesignPatterns

FJ-25:PersistênciacomJPA,HibernateeEJBlite

FJ-26:LaboratórioWebcomJSFeCDI

FJ-57:DesenvolvimentomóvelcomGoogleAndroid

FJ-91:ArquiteturaeDesigndeProjetosJava

Consulte mais informações no nosso site e entre em contato conosco. Conheça nosso mapa decursos:

http://www.caelum.com.br/mapa-dos-cursos/

17.3GRUPOSDEUSUÁRIOS

17.4PRÓXIMOSCURSOS

252 17.3GRUPOSDEUSUÁRIOS

Page 263: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

EditoraCasadoCódigocomlivrosdeumaformadiferente

17.4PRÓXIMOSCURSOS 253

Page 264: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO18

"Oúnicolugarondeosucessovemantesdotrabalhoénodicionário."--AlbertEinstein

Aotérminodessecapítulo,vocêserácapazde:

executartarefassimultaneamente;colocartarefasparaaguardaratéqueumdeterminadoeventoocorra;entenderofuncionamentodoGarbageCollector.

Emváriassituações,precisamos"rodarduascoisasaomesmo tempo". ImagineumprogramaquegeraumrelatóriomuitograndeemPDF.Éumprocessodemoradoe,paradaralgumasatisfaçãoparaousuário, queremosmostrar umabarra deprogresso.Queremos entãogerar oPDFeaomesmo tempoatualizarabarrinha.

Pensandoumpoucomaisamplamente,quandousamosocomputadortambémfazemosváriascoisassimultaneamente:queremosnavegarnainterneteaomesmotempoouvirmúsica.

Anecessidadedesefazerváriascoisassimultaneamente,aomesmotempo,paralelamente,aparecefrequentemente na computação. Para vários programas distintos, normalmente o próprio sistemaoperacionalgerenciaissoatravésdeváriosprocessosemparalelo.

Em um programa só (um processo só), se queremos executar coisas em paralelo, normalmentefalamosdeThreads.

Em Java, usamos a classe Thread do pacote java.lang para criarmos linhas de execução

paralelas.AclasseThreadrecebecomoargumentoumobjetocomocódigoquedesejamosrodar.Por

exemplo,noprogramadePDFebarradeprogresso:

publicclassGeraPDF{

APÊNDICE-PROGRAMAÇÃOCONCORRENTEETHREADS

18.1THREADS

"Duastarefasaomesmotempo"

ThreadsemJava

254 18APÊNDICE-PROGRAMAÇÃOCONCORRENTEETHREADS

Page 265: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicvoidrodar(){//lógicaparageraropdf...}}

publicclassBarraDeProgresso{publicvoidrodar(){//mostrabarradeprogressoevaiatualizandoela...}}

E,nométodomain,criamososobjetosepassamosparaaclasseThread.Ométodostart é

responsávelporiniciaraexecuçãodaThread:

publicclassMeuPrograma{publicstaticvoidmain(String[]args){

GeraPDFgerapdf=newGeraPDF();ThreadthreadDoPdf=newThread(gerapdf);threadDoPdf.start();

BarraDeProgressobarraDeProgresso=newBarraDeProgresso();ThreadthreadDaBarra=newThread(barraDeProgresso);threadDaBarra.start();

}}

Ocódigoacima,porém,nãocompilará.ComoaclasseThread sabequedevechamarométodo

roda?Comoelasabequenomedemétododaremosequeeladevechamaressemétodoespecial?Falta

naverdadeumcontratoentreasnossasclassesaseremexecutadaseaclasseThread.

Esse contrato existe e é feito pela interface Runnable : devemos dizer que nossa classe é

"executável"equesegueessecontrato.NainterfaceRunnable,háapenasummétodochamadorun.

Bastaimplementá-lo,"assinar"ocontratoeaclasseThreadjásaberáexecutarnossaclasse.

publicclassGeraPDFimplementsRunnable{publicvoidrun(){//lógicaparageraropdf...}}

publicclassBarraDeProgressoimplementsRunnable{publicvoidrun(){//mostrabarradeprogressoevaiatualizandoela...}}

AclasseThread recebe no construtor umobjeto que éumRunnable, e seumétodostart

chamaométodorundanossaclasse.ReparequeaclasseThreadnãosabequaléotipoespecíficoda

nossaclasse;paraela,bastasaberqueaclassesegueocontratoestabelecidoepossuiométodorun.

Éobomusodeinterfaces,contratosepolimorfismonaprática!

18.1THREADS 255

Page 266: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ESTENDENDOACLASSETHREAD

A classe Thread implementa Runnable. Então, você pode criar uma subclasse dela e

reescreverorunque,naclasseThread,nãofaznada:

publicclassGeraPDFextendsThread{publicvoidrun(){//...}}

E,comonossaclasseéumaThread,podemosusarostartdiretamente:

GeraPDFgera=newGeraPDF();gera.start();

Apesar de ser um código mais simples, você está usando herança apenas por "preguiça"(herdamosummontedemétodosmasusamosapenasorun),enãoporpolimorfismo,queseriaa

grandevantagem.PrefiraimplementarRunnableaherdardeThread.

DORMINDO

Para que a thread atual durma basta chamar ométodo a seguir, por exemplo, para dormir 3segundos:

javaThread.sleep(3*1000);

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

256 18.1THREADS

Page 267: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Vejaaclasseaseguir:

publicclassProgramaimplementsRunnable{

privateintid;//colocargetteresetterproatributoid

publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa"+id+"valor:"+i);}}}

Éumaclasseque implementaRunnable e,nométodorun, apenas imprimedezmil números.

Vamosusá-lasduasvezesparacriarduasthreadseimprimirosnúmerosduasvezessimultaneamente:

publicclassTeste{publicstaticvoidmain(String[]args){

Programap1=newPrograma();p1.setId(1);

Threadt1=newThread(p1);t1.start();

Programap2=newPrograma();p2.setId(2);

Threadt2=newThread(p2);t2.start();

}}

Serodarmosesseprograma,qualseráasaída?Deumamiledepoisdeumamil?Provavelmentenão, senão seria sequencial. Ele imprimirá 0 de t1, 0 de t2, 1 de t1, 1 de t2, 2 de t1, 2 de t2 e etc?Exatamenteintercalado?

Naverdade,nãosabemosexatamentequaléasaída.Rodeoprogramaváriasvezeseobserve:emcadaexecuçãoasaídaéumpoucodiferente.

Oproblemaéquenocomputadorexisteapenasumprocessadorcapazdeexecutarcoisas.Equandoqueremosexecutarváriascoisasaomesmotempo,eoprocessadorsóconseguefazerumacoisadecadavez?Entraemcenaoescalonadordethreads.

O escalonador (scheduler), sabendoque apenasuma coisa pode ser executadade cadavez, pegatodasas threadsqueprecisamserexecutadasefazoprocessadorficaralternandoaexecuçãodecadauma delas. A ideia é executar um pouco de cada thread e fazer essa troca tão rapidamente que aimpressãoqueficaéqueascoisasestãosendofeitasaomesmotempo.

18.2ESCALONADORETROCASDECONTEXTO

18.2ESCALONADORETROCASDECONTEXTO 257

Page 268: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Oescalonadoréresponsávelporescolherqualapróximathreadaserexecutadaefazeratrocadecontexto (contextswitch).Eleprimeirosalvaoestadodaexecuçãoda threadatualparadepoispoderretomar a execução da mesma. Aí ele restaura o estado da thread que vai ser executada e faz oprocessadorcontinuaraexecuçãodesta.Depoisdeumcertotempo,estathreadétiradadoprocessador,seuestado(ocontexto)ésalvoeoutrathreadécolocadaemexecução.Atrocadecontextoéjustamenteas operações de salvar o contexto da thread atual e restaurar o da thread que vai ser executada emseguida.

Quando fazer a troca de contexto, por quanto tempo a thread vai rodar e qual vai ser a próximathread a ser executada, são escolhas do escalonador. Nós não controlamos essas escolhas (emborapossamosdar"dicas"aoescalonador).Porissoquenuncasabemosaocertoaordememqueprogramasparalelossãoexecutados.

Vocêpodepensarqueéruimnãosaberaordem.Maspercebaqueseaordemimportaparavocê,seé importantequedeterminadacoisasejafeitaantesdeoutra,entãonãoestamosfalandodeexecuçõesparalelas,massimdeumprogramasequencialnormal(ondeumacoisaéfeitadepoisdaoutra,emumasequência).

Todo esse processo é feito automaticamente pelo escalonador do Java (e,mais amplamente, peloescalonador do sistema operacional). Para nós, programadores das threads, é como se as coisasestivessemsendoexecutadasaomesmotempo.

EEMMAISDEUMPROCESSADOR?

AVMdoJavaeamaioriadosSOsmodernosconseguefazerproveitodesistemascomváriosprocessadoresoumulti-core.Adiferençaéqueagora temosmaisdeumprocessadorexecutandocoisaseteremos,sim,execuçõesverdadeiramenteparalelas.

MasonúmerodeprocessosnoSOeonúmerodeThreadsparalelascostumamsertãograndesque, mesmo com vários processadores, temos as trocas de contexto. A diferença é que oescalonadortemdoisoumaisprocessadoresparaexecutarsuasthreads.Masdificilmenteteráumamáquinacommaisprocessadoresquethreadsparalelasexecutando.

OGarbageCollector(coletordelixo,lixeiro)funcionacomoumaThreadresponsávelporjogarforatodososobjetosquenãoestãosendoreferenciadospornenhumoutroobjeto-sejademaneiradiretaouindireta.

Considereocódigo:

18.3GARBAGECOLLECTOR

258 18.3GARBAGECOLLECTOR

Page 269: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Contaconta1=newContaCorrente();Contaconta2=newContaCorrente();

Atéestemomento,sabemosquetemos2objetosemmemória.Aqui,oGarbageCollectornãopodeeliminarnenhumdosobjetos,poisaindatemalguémsereferindoaelesdealgumaforma.

Podemos, então, executar uma linha que nos faça perder a referência para um dos dois objetoscriados,como,porexemplo,oseguintecódigo:

conta2=conta1;

Quantosobjetostemosemmemória?

Perdemosareferênciaparaumdosobjetosqueforamcriados.Esseobjetojánãoémaisacessível.Temos,então,apenasumobjetoemmemória?Nãopodemosafirmarisso!ComooGarbageCollectoréumaThread,vocênãotemgarantiadequandoelevairodar.Vocêsósabeque,emalgummomentonofuturo,aquelamemóriavaiserliberada.

Algumaspessoascostumamatribuirnullaumavariável,comointuitodeacelerarapassagemdo

GarbageCollectorporaqueleobjeto:

for(inti=0;i<100;i++){Listx=newArrayList();//fazalgumascoisascomaarraylistx=null;}

Isso rarissimamente é necessário. O Garbage Collector age apenas sobre objetos, nunca sobrevariáveis.Nessecaso,avariávelxnãoexistirámaisacadaiteração,deixandoaArrayList criada

semnenhumareferênciaparaela.

SYSTEM.GC()

Você nunca consegue forçar oGarbageCollector,mas chamando ométodo estáticogc da

classeSystem, você está sugerindo que a VirtualMachine rode o Garbage Collector naquele

momento.Sesuasugestãovaiseraceitaounão,istodependedeJVMparaJVM,evocênãotemgarantias.Evite o uso destemétodo.Você não deve basear sua aplicação emquando oGarbageCollectorvairodarounão.

18.3GARBAGECOLLECTOR 259

Page 270: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

FINALIZER

A classe Object define também ummétodo finalize, que você pode reescrever. Esse

método será chamado no instante antes do Garbage Collector coletar este objeto. Não é umdestrutor, você não sabe em quemomento ele será chamado. Algumas pessoas o utilizam paraliberarrecursos"caros"comoconexões,threadserecursosnativos.Issodeveserutilizadoapenasporsegurança:oidealéliberaressesrecursosomaisrápidopossível,semdependerdapassagemdoGarbageCollector.

1. Testeoexemplodestecapítuloparaimprimirnúmerosemparalelo.

EscrevaaclassePrograma:

publicclassProgramaimplementsRunnable{

privateintid;//colocargetteresetterproatributoid

publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa"+id+"valor:"+i);}}}

EscrevaaclassedeTeste:

publicclassTeste{publicstaticvoidmain(String[]args){

Programap1=newPrograma();p1.setId(1);

Threadt1=newThread(p1);t1.start();

Programap2=newPrograma();p2.setId(2);

Threadt2=newThread(p2);t2.start();

}}

Rode várias vezes a classeTeste e observe os diferentes resultados em cada execução. O que

muda?

18.4EXERCÍCIOS

260 18.4EXERCÍCIOS

Page 271: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

É comum aparecer uma classe anônima junto com uma thread. Vimos como usá-la com oComparator.VamosvercomousaremumRunnable.

ConsidereumRunnablesimples,queapenasmandaimprimiralgonasaídapadrão:

publicclassPrograma1implementsRunnable{publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa1valor:"+i);}}}

Noseumain,vocêfaz:

Runnabler=newPrograma1();Threadt=newThread(r);t.start();

Emvezde criar essa classePrograma1, podemosutilizar o recursode classe anônima.Ela nos

permitedarnewnumainterface,desdequeimplementemosseusmétodos.Comisso,podemoscolocar

diretamentenomain:

Runnabler=newRunnable(){publicvoidrun(){for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}};Threadt=newThread(r);t.start();

Seuslivrosdetecnologiaparecemdoséculopassado?

18.5EASCLASSESANÔNIMAS?

18.5EASCLASSESANÔNIMAS? 261

Page 272: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

LIMITAÇÕESDASCLASSESANÔNIMAS

O uso de classes anônimas tem limitações. Não podemos declarar um construtor. Comoestamosinstanciandoumainterface,entãonãoconseguimospassarumparâmetroparaela.Comoentão passar o id como argumento? Você pode, de dentro de uma classe anônima, acessar

atributos da classe dentro da qual foi declarada! Também pode acessar as variáveis locais dométodo,desdequeelessejamfinal.

Dá para ir mais longe com o Java 8, utilizando o lambda. Como Runnable é uma interface

funcional(contémapenasummétodoabstrato),elapodeserfacilmenteescritadessaforma:

Runnabler=()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);};Threadt=newThread(r);t.start();

A sintaxe pode ser um pouco estranha.Como não há parâmetros a serem recebidos pelométodorun, usamoso() para indicar isso.Vale lembrar,mais umavez, queno lambdanãoprecisamos

escreveronomedométodoqueestamos implementando,nonossocasoorun. Isso é possível pois

existeapenasummétodoabstratonainterface.

Querdeixarocódigomaisenxutoainda?PodemospassarolambdadiretamenteparaoconstrutordeThread,semcriarumavariáveltemporária!Elogoemseguidachamarostart:

newThread(()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}).start();

Obviamente o uso excessivo de lambdas e classes anônimas pode causar uma certa falta delegibilidade.Vocêdeve lembrarqueusamosessesrecursosparaescrevercódigosmais legíveis,enãoapenas para poupar algumas linhas de código.Caso nossa implementação do lambda venha a ser deváriaslinhas,éumfortesinaldequedeveríamosterumaclasseapartesomenteparaela.

EcomlambdadoJava8?

262 18.5EASCLASSESANÔNIMAS?

Page 273: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO19

"Olhoporolho,eomundoacabarácego."--MohandasGandhi

Conectando-seamáquinasremotas.

Nestecapítulo,vocêvaiconheceraAPIdeSocketsdojavapelopacotejava.net.

Mais útil que conhecer a API, é você perceber que estamos usando, aqui, todos os conceitos ebibliotecas aprendidas durante os outros capítulos. Repare, também, que é relativamente simplesaprenderautilizarumaAPI,agoraquetemostodososconceitosnecessáriosparatal.

Lembre-sedefazeresseapêndicecomojavadocabertoaoseulado.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

Da necessidade de dois computadores se comunicarem, surgiram diversos protocolos quepermitissemtaltrocadeinformação:oprotocoloquevamosusaraquiéoTCP(TransmissionControlProtocol).

AtravésdoTCP,épossívelcriarumfluxoentredoiscomputadores-comoémostradonodiagramaabaixo:

APÊNDICE-SOCKETS

19.1MOTIVAÇÃO:UMAAPIQUEUSAOSCONCEITOSAPRENDIDOS

VocêpodetambémfazerocursodatadessaapostilanaCaelum

19.2PROTOCOLO

19APÊNDICE-SOCKETS 263

Page 274: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Épossível conectarmais de um cliente aomesmo servidor, como é o caso de diversos banco dedados,servidoresWeb,etc.

Ao escrever um programa em Java que se comunique com outra aplicação, não é necessário sepreocupar com um nível tão baixo quanto o protocolo.As classes que trabalham com eles já foramdisponibilizadasparaseremusadaspornósnopacotejava.net.

A vantagemde se usarTCP, emvez de criar nosso próprio protocolo de bytes, é que oTCPvaigarantir a entrega dos pacotes que transferirmos e criar um protocolo base para isto é algo bemcomplicado.

Acabamosdemencionarquediversoscomputadorespodemseconectaraumsó,mas,narealidade,émuito comum encontrarmáquinas clientes com uma só conexão física. Então, como é possível seconectaradoispontos?Comoépossívelserconectadopordiversospontos?

Todasasaplicaçõesqueestãoenviandoe recebendodados fazem issoatravésdamesmaconexãofísica, mas o computador consegue discernir, durante a chegada de novos dados, quais informaçõespertencemaqualaplicação.Mascomo?

19.3PORTA

264 19.3PORTA

Page 275: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AssimcomoexisteoIPparaidentificarumamáquina,aportaéasoluçãoparaidentificardiversasaplicaçõesemumamáquina.Estaportaéumnúmerode2bytes,variade0a65535.Setodasasportasdeumamáquinaestiveremocupadas,nãoépossívelseconectaraelaenquantonenhumaforliberada.

Ao configurar um servidor para rodar na porta 80 (padrão http), é possível se conectar a esseservidoratravésdessaportaque, juntocomo ip,vai formaroendereçodaaplicação.Porexemplo,oservidorwebdacaelum.com.brpodeserrepresentadopor:caelum.com.br:80

Masseumclienteseconectaaumprogramarodandonaporta80deumservidor,enquantoelenãosedesconectardessaporta,seráimpossívelqueoutrapessoaseconecte?

Acontece que, ao efetuar e aceitar a conexão, o servidor redireciona o cliente de uma porta paraoutra,liberandonovamentesuaportainicialepermitindoqueoutrosclientesseconectemnovamente.

EmJava,issodeveserfeitoatravésdethreadseoprocessodeaceitaraconexãodeveserrodadoomaisrápidopossível.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

19.4SOCKET

Seuslivrosdetecnologiaparecemdoséculopassado?

19.4SOCKET 265

Page 276: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Iniciandoummodelodeservidordechat,oserviçodocomputadorquefuncionacomobasedeve,primeiro,abrirumaportaeficarouvindoatéalguémtentarseconectar.

importjava.net.*;

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");//acontinuaçãodoservidordeveserescritaaqui

}}

Seoobjetoforrealmentecriado,significaqueaporta12345estavafechadaefoiaberta.Seoutroprogramapossuiocontroledestaportanesteinstante,énormalqueonossoexemplonãofuncione,poiselenãoconsegueutilizarumaportaquejáestáemuso.

Após abrir a porta, precisamos esperar por um cliente através do método accept da

ServerSocket.Assimqueumclienteseconectar,oprogramacontinuará,porissodizemosqueesse

métodoéblocante,seguraathreadatéquealgoonotifique.

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());//imprimeoipdocliente

Porfim,bastalertodasasinformaçõesqueoclientenosenviar:

Scannerscanner=newScanner(cliente.getInputStream());

while(scanner.hasNextLine()){System.out.println(scanner.nextLine());}

Fechamosasconexões,começandopelofluxo:

in.close();cliente.close();servidor.close();

Oresultadoéaclasseaseguir:

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

Scanners=newScanner(cliente.getInputStream());

19.5SERVIDOR

266 19.5SERVIDOR

Page 277: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

while(s.hasNextLine()){System.out.println(s.nextLine());}

s.close();servidor.close();cliente.close();}}

Anossatarefaécriarumprogramaclientequeenviemensagensparaoservidor...oclienteéaindamaissimplesdoqueoservidor.

Ocódigo a seguir é aparteprincipal e tenta se conectar aum servidorno IP127.0.0.1 (máquinalocal)eporta12345:

Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Queremoslerosdadosdocliente,daentradapadrão(teclado):

Scannerteclado=newScanner(System.in);while(teclado.hasNextLine()){//lêalinhaefazalgocomela}

Bastaleraslinhasqueousuáriodigitaratravésdobufferdeentrada(in),ejogá-lasnobufferde

saída:

PrintStreamsaida=newPrintStream(cliente.getOutputStream());Scannerteclado=newScanner(System.in);while(teclado.hasNextLine()){saida.println(teclado.nextLine());}saida.close();teclado.close();

Reparequeusamososconceitodejava.io aqui novamente, para leitura do teclado e enviode

mensagensparaoservidor.ParaasclassesScannerePrintStream,tantofazdeondequeselêou

escreveosdados:oimportanteéqueessestreamsejaumInputStream/OutputStream.Éopoder

dasinterfaces,dopolimorfismo,aparecendonovamente.

Nossoprogramafinal:

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Scannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());

19.6CLIENTE

19.6CLIENTE 267

Page 278: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();cliente.close();}}

Paratestarosistema,precisamosrodarprimeirooservidore,logodepois,ocliente.Tudooquefordigitadonoclienteseráenviadoparaoservidor.

MULTITHREADING

Para que o servidor seja capaz de trabalhar comdois clientes aomesmo tempo é necessáriocriarumathreadlogoapósexecutarométodoaccept.

A threadcriadaserá responsávelpelo tratamentodessaconexão,enquantoo laçodoservidordisponibilizaráaportaparaumanovaconexão:

while(true){

Socketcliente=servidor.accept();

//criaumobjetoquevaitrataraconexãoTratamentoClasstratamento=newTratamentoClass(cliente);

//criaathreademcimadesteobjetoThreadt=newThread(tratamento);

//iniciaathreadt.start();

}

19.7IMAGEMGERAL

268 19.7IMAGEMGERAL

Page 279: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AsocketdoclientetemumInputStream,querecebedoOutputStreamdoservidor,e temum

OutputStream,quetransferetudoparaoInputStreamdoservidor.Muitoparecidocomumtelefone!

Reparequeclienteeservidorsãorótulosqueindicamumestado.Ummicro(oumelhor,umaJVM)podeserservidornumcaso,maspodeserclienteemoutrocaso.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Crieumprojetosockets.

Vamosfazerumpequenosistemaemquetudoqueédigitadonomicroclienteacabaaparecendonomicroservidor.Istoé,apenasumacomunicaçãounidirecional.

CrieaclasseServidorcomovimosnessecapítulo.AbusedosrecursosdoEclipseparanãoterde

escrevermuito!

packagebr.com.caelum.chat;

importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Scanner;

Agoraéamelhorhoradeaprenderalgonovo

19.8EXERCÍCIOS:SOCKETS

19.8EXERCÍCIOS:SOCKETS 269

Page 280: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

Scannerentrada=newScanner(cliente.getInputStream());while(entrada.hasNextLine()){System.out.println(entrada.nextLine());}

entrada.close();servidor.close();}}

2. CrieaclasseClientecomovistaanteriormente:

packagebr.com.caelum.chat;

importjava.io.IOException;importjava.io.PrintStream;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.Scanner;

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Scannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());

while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();}}

Utilizedosquickfixesecontrolespaçoparaosimportseothrows.

3. Rode a classeServidor: repare no console doEclipse que o programa fica esperando.Rode a

classeCliente: a conexão deve ser feita e o Eclipse devemostrar os dois consoles para você

(existeumpequenoíconenaviewdeConsoleparavocêalternarentreeles).

Digitemensagensnoclienteevejaseelasaparecemcorretamentenoservidor.

4. Testeseuprogramacomumcolegadocurso,usandocomunicaçãoremotaentreasduasmáquinas.Combinementresiquemvairodaroclienteequemvairodaroservidor.Quemforrodarocliente

270 19.8EXERCÍCIOS:SOCKETS

Page 281: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

deve editar o IP na classe para indicar o endereço da outramáquina (verifique também se estãoacessandoamesmaporta).

DESCOBRINDOOIPDAMÁQUINA

NoWindows,abraoconsoleedigiteipconfigparasaberqualéoseuIP.NoLinux(ounoBSD,Mac,Solaris),vánoconsoleedigiteifconfig.

5. (opcional)Esevocêquisesse,emvezdeenviartudooqueoclientedigitou,transferirumarquivotextodomicrodoclienteparaservidor?Seriadifícil?

Abusedopolimorfismo!Façaoclientelerdeumarquivochamadoarquivo.txt (crie-o!)efaça

comqueoservidorgravetudoquerecebenumarquivoquechamarecebido.txt.

Quandooservidoraceitaumclientecomachamadaaoaccept, ele poderia chamarnovamente

estemétodo para aceitar um novo cliente. E, se queremos aceitar vários clientes, simultâneos, bastachamaroacceptváriasvezesetratarcadaclienteemsuaprópriaThread(senãoométodoaccept

nãoseráinvocadonovamente!).

UmesboçodesoluçãoparaaclasseServidor:

ServerSocketservidor=newServerSocket(12345);

//servidorficaeternamenteaceitandoclientes...while(true){Socketcliente=servidor.accept();//disparaumaThreadquetrataesseclienteejáesperaopróximo}

[TODO:serialegalessasoluçãoparcialparaapenasessaparte!]

Agora que vários clientes podemmandar mensagens, gostaríamos que os clientes recebessem asmensagensenviadaspelasoutraspessoas.Aoinvésdoservidorsimplesmenteescreverasmensagensnoconsole,eledevemandarcadamensagemparatodososclientesconectados.

Precisamosmanterumalistadeclientesconectadose,quandochegarumamensagem(dequalquercliente),percorremosessalistaemandamosparatodos.

UseumListparaguardarosPrintStreamsdosclientes.Logodepoisqueoservidoraceitarum

19.9DESAFIO:MÚLTIPLOSCLIENTES

19.10DESAFIO:BROADCASTDASMENSAGENS

19.9DESAFIO:MÚLTIPLOSCLIENTES 271

Page 282: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

cliente novo, crie umPrintStream usando o OutputStream dele e adicione na lista. E, quando

receberumamensagemnova,enviaparatodosnalista.

Umesboço:

Adicionandonalista:

while(true){Socketcliente=servidor.accept();this.lista.add(newPrintStream(cliente.getOutputStream()));

//disparaumaThreadquetrataesseclienteejáesperaopróximo}

Métodoquedistribuiasmensagens:

voiddistribuiMensagem(Stringmsg){for(PrintStreamcliente:lista){cliente.println(msg);}}

Masnossoclientetambémrecebemensagens.EntãoprecisamosfazercomqueoCliente,alémdelermensagensdo tecladoeenviarparaoservidor,simultaneamente tambémpossarecebermensagensdeoutrosclientesenviadaspeloservidor.

Ouseja,precisamosdeumasegundaThreadnaclasseClientequeficarecebendomensagensdo

InputStreamdoservidoreimprimindonoconsole.

Umesboço:

Scannerservidor=newScanner(cliente.getInputStream());while(servidor.hasNextLine()){System.out.println(servidor.nextLine());}

Lembre que você precisará de no mínimo 2 threads para o cliente e 2 para o servidor. Entãoprovavelmentevocêvaiterqueescrever4classes.

Melhoriaspossíveis:

Faça como a primeira linha enviada pelo cliente seja sempre o nick dele. E quando o servidorenviaramensagem,façaeleenviaronickdecadaclienteantesdamensagem.

Equandoumclientedesconectar?Comoretirá-lodalista?

É difícil fazer o envio de arquivos pelo nosso sistema de chats? Sabendo que a leitura de umarquivo é feita pelo FileInputStream , seria difícil mandar esse InputStream pelo

OutputStreamdaconexãoderede?

272 19.10DESAFIO:BROADCASTDASMENSAGENS

Page 283: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Umasoluçãoparaosistemadechatcliente-servidorcommúltiplosclientespropostonosdesafiosacima. Repare que a solução não está nem um pouco elegante: o main já faz tudo, além de não

tratarmosasexceptions.OcódigovisaapenasmostrarousodeumaAPI.Éumapéssimapráticacolocartodaafuncionalidadedoseuprogramanomainetambémdejogarexceçõesparatrás.

Nestalistagem,faltamosdevidosimports.

Primeiro, as duas classes para o cliente. Repare que a única mudança grande é a classe nova,Recebedor:

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{//disparaclientenewCliente("127.0.0.1",12345).executa();}

privateStringhost;privateintporta;

publicCliente(Stringhost,intporta){this.host=host;this.porta=porta;}

publicvoidexecuta()throwsUnknownHostException,IOException{Socketcliente=newSocket(this.host,this.porta);System.out.println("Oclienteseconectouaoservidor!");

//threadpararecebermensagensdoservidorRecebedorr=newRecebedor(cliente.getInputStream());newThread(r).start();

//lêmsgsdotecladoemandaproservidor

EditoraCasadoCódigocomlivrosdeumaformadiferente

19.11SOLUÇÃODOSISTEMADECHAT

19.11SOLUÇÃODOSISTEMADECHAT 273

Page 284: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Scannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();cliente.close();}}

publicclassRecebedorimplementsRunnable{

privateInputStreamservidor;

publicRecebedor(InputStreamservidor){this.servidor=servidor;}

publicvoidrun(){//recebemsgsdoservidoreimprimenatelaScanners=newScanner(this.servidor);while(s.hasNextLine()){System.out.println(s.nextLine());}}}

JáoServidorsofreubastantemodificações.AclasseTrataClienteéaresponsávelporcuidarde

cadaclienteconectadonosistema:

publicclassServidor{

publicstaticvoidmain(String[]args)throwsIOException{//iniciaoservidornewServidor(12345).executa();}

privateintporta;privateList<PrintStream>clientes;

publicServidor(intporta){this.porta=porta;this.clientes=newArrayList<PrintStream>();}

publicvoidexecuta()throwsIOException{ServerSocketservidor=newServerSocket(this.porta);System.out.println("Porta12345aberta!");

while(true){//aceitaumclienteSocketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

//adicionasaidadoclienteàlistaPrintStreamps=newPrintStream(cliente.getOutputStream());this.clientes.add(ps);

274 19.11SOLUÇÃODOSISTEMADECHAT

Page 285: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

//criatratadordeclientenumanovathreadTrataClientetc=newTrataCliente(cliente.getInputStream(),this);newThread(tc).start();}

}

publicvoiddistribuiMensagem(Stringmsg){//enviamsgparatodomundofor(PrintStreamcliente:this.clientes){cliente.println(msg);}}}

publicclassTrataClienteimplementsRunnable{

privateInputStreamcliente;privateServidorservidor;

publicTrataCliente(InputStreamcliente,Servidorservidor){this.cliente=cliente;this.servidor=servidor;}

publicvoidrun(){//quandochegarumamsg,distribuipratodosScanners=newScanner(this.cliente);while(s.hasNextLine()){servidor.distribuiMensagem(s.nextLine());}s.close();}}

19.11SOLUÇÃODOSISTEMADECHAT 275

Page 286: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO20

"Quempoucopensa,engana-semuito."--LeonardodaVinci

OusodeThreadscomeçaaficarinteressanteecomplicadoquandoprecisamoscompartilharobjetosentreváriasThreads.

Imagineaseguintesituação:temosumBancocommilhõesdeContasBancárias.Clientessacamedepositam dinheiro continuamente, 24 horas por dia.No primeiro dia de cadamês, oBanco precisaatualizar o saldo de todas as Contas de acordo com uma taxa específica. Para isso, ele utiliza oAtualizadorDeContasquevimosanteriormente.

OAtualizadorDeContas,basicamente,pegaumaaumacadaumadasmilhõesdecontasechama

seumétodoatualiza.Aatualizaçãodemilhõesdecontaséumprocessodemorado,quedurahoras;é

inviávelpararobancoportantotempoatéqueasatualizaçõestenhamcompletado.Éprecisoexecutarasatualizaçõesparalelamenteàsatividades,dedepósitosesaques,normaisdobanco.

Ouseja,teremosváriasthreadsrodandoparalelamente.Emumathread,pegamostodasascontasevamoschamandoométodoatualizadecadauma.Emoutra,podemosestarsacandooudepositando

dinheiro.Estamoscompartilhandoobjetosentremúltiplasthreads(ascontas,nonossocaso).

Imagineaseguintepossibilidade(mesmoquemuitoremota):noexatoinstanteemqueoatualizadorestáatualizandoumaContaX,oclientedonodestaContaresolveefetuarumsaque.Comosabemos,aotrabalhar comThreads, o escalonador podeparar uma certaThread a qualquer instante para executaroutra,evocênãotemcontrolesobreisso.

VejaessaclasseConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){

APÊNDICE-PROBLEMASCOMCONCORRÊNCIA

20.1THREADSACESSANDODADOSCOMPARTILHADOS

276 20APÊNDICE-PROBLEMASCOMCONCORRÊNCIA

Page 287: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

doublesaldoAtualizado=this.saldo*(1+taxa);this.saldo=saldoAtualizado;}

publicvoiddeposita(doublevalor){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}

ImagineumaContacomsaldode100reais.Umclienteentranaagênciaefazumdepósitode1000reais.IssodisparaumaThreadnobancoquechamaométododeposita();elecomeçacalculandoo

novoSaldo que passa a ser 1100 (linha 13). Só que por algum motivo que desconhecemos, o

escalonadorpáraessathread.

Nesteexatoinstante,elecomeçaaexecutarumaoutraThreadquechamaométodoatualiza da

mesmaConta,porexemplo,comtaxade1%. IssoquerdizerqueonovoSaldo passa a valer 101

reais(linha8).E,nesseinstanteoescalonadortrocadeThreadsnovamente.Eleexecutaalinha14naThreadquefaziaodepósito;osaldopassaavaler1100.Acabandoodeposita,oescalonadorvoltapraThreaddoatualizaeexecutaalinha9,fazendoosaldovaler101reais.

Resultado:odepósitodemilreaisfoitotalmenteignoradoeseuClienteficarápoucofelizcomisso.Percebaquenãoépossíveldetectaresseerro, jáque todoocódigo foiexecutadoperfeitamente, semproblemas.Oproblema,aqui,foioacessosimultâneodeduasThreadsaomesmoobjeto.

EoerrosóocorreuporqueoescalonadorparounossasThreadsnaquelesexatos lugares.Podeserquenossocódigofiquerodando1anosemdarproblemaalgumeemumbelodiaoescalonadorresolvealternar nossas Threads daquela forma. Não sabemos como o escalonador se comporta! Temos queprotegernossocódigocontraessetipodeproblema.Dizemosqueessaclassenãoéthreadsafe,issoé,nãoestáprontaparaterumainstânciautilizadaentreváriasthreadsconcorrentemente.

OquequeríamoseraquenãofossepossívelalguématualizaraContaenquantooutrapessoaestá

depositandoumdinheiro.QueríamosqueumaThreadnãopudessemexer emumaConta enquanto

outraThreadestámexendonela.Nãohácomoimpediroescalonadordefazertalescolha.Então,oquefazer?

20.1THREADSACESSANDODADOSCOMPARTILHADOS 277

Page 288: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Umaideiaseriacriarumatravae,nomomentoemqueumaThreadentrasseemumdessesmétodos,ela trancariaaentradacomumachave.Dessamaneira,mesmoquesendocolocadade lado,nenhumaoutraThreadpoderiaentrarnessesmétodos,poisachaveestariacomaoutraThread.

Essaideiaéchamadaderegiãocrítica.Éumpedaçodecódigoquedefinimoscomocríticoequenãopodeserexecutadoporduasthreadsaomesmotempo.Apenasumathreadporvezconsegueentraremalgumaregiãocrítica.

PodemosfazerissoemJava.Podemosusarqualquerobjetocomoumlock(trava,chave),parapodersincronizar emcimadesseobjeto, isto é, se umaThread entrar emumblocoque foi definido comosincronizadoporesse lock,apenasumaThreadpoderáestar ládentroaomesmo tempo,poisachaveestarácomela.

Apalavrachavesynchronizeddáessacaracterísticaaumblocodecódigoerecebequaléoobjeto

queseráusadocomochave.AchavesóédevolvidanomomentoemqueaThreadquetinhaessachavesair do bloco, seja por return ou disparo de uma exceção (ou ainda na utilização do método

wait())..

Queremos,então,bloquearoacessosimultâneoaumamesmaConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){synchronized(this){doublesaldoAtualizado=this.saldo*(1+taxa);this.saldo=saldoAtualizado;

JáconheceoscursosonlineAlura?

20.2CONTROLANDOOACESSOCONCORRENTE

278 20.2CONTROLANDOOACESSOCONCORRENTE

Page 289: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

}}

publicvoiddeposita(doublevalor){synchronized(this){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}}

Observeousodosblocossynchronized dentrodosdoismétodos.Eles bloqueiamumaThread

utilizandoomesmoobjetoConta,othis.

Essesmétodossãomutuamenteexclusivosesóexecutamdemaneiraatômica.Threadsquetentampegarumlockquejáestápego,ficarãoemumconjuntoespecialesperandopelaliberaçãodolock(nãonecessariamentenumafila).

SINCRONIZANDOOBLOCOINTEIRO

Écomumsempresincronizarmosummétodointeiro,normalmenteutilizandoothis.

publicvoidmetodo(){synchronized(this){//conteúdodometodo}}

Para estemesmo efeito, existe uma sintaxemais simples, onde o synchronized pode ser

usadocomomodificadordométodo:

publicsynchronizedvoidmetodo(){//conteúdodometodo}

MAISSOBRELOCKS,MONITORESECONCORRÊNCIA

Se ométodo for estático, será sincronizado usando o lock do objeto que representa a classe(NomeDaClasse.class).

Alémdisso,opacotejava.util.concurrent,conhecidocomoJUC,entrounoJava5.0parafacilitarumasériedetrabalhoscomunsquecostumamapareceremumaaplicaçãoconcorrente.

Essepacoteajudaatémesmocriarthreadsepooldethreads,atravésdosExecutors.

20.2CONTROLANDOOACESSOCONCORRENTE 279

Page 290: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Duas collectionsmuito famosas são Vector e Hashtable, a diferença delas com suas irmãs

ArrayListeHashMapéqueasprimeirassãothreadsafe.

Vocêpodeseperguntarporquenãousamossempreessasclassesthreadsafe.Adquirirumlocktemumcusto,ecasoumobjetonãováserusadoentrediferentesthreads,nãoháporqueusaressasclassesqueconsomemmaisrecursos.Masnemsempreéfácilenxergarsedevemossincronizarumbloco,ousedevemosutilizarblocossincronizados.

Antigamenteocustodeseusarlockseraaltíssimo,hojeemdiaissocustapoucoparaaJVM,masnãoémotivoparavocêsincronizartudosemnecessidade.

Você pode mudar a prioridade de cada uma de suas Threads, mas isto também é apenas umasugestãoaoescalonador.

ExisteummétodostopnasThreads,porquenãoéboapráticachamá-lo?

Umtópicomaisavançadoéautilizaçãodewait,notifiyenotifyAllparaqueasThreads

comuniquem-sedeeventosocorridos,indicandoquepodemounãopodemavançardeacordocomcondições

O pacote java.util.concurrent foi adicionado no Java 5 para facilitar o trabalho na

programaçãoconcorrente.Elepossuiumasériedeprimitivasparaquevocênãotenhadetrabalhardiretamentecomwaitenotify,alémdeterdiversascoleçõesthreadsafe.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoJavaeOrientaçãoaObjetos

20.3VECTOREHASHTABLE

20.4UMPOUCOMAIS...

VocêpodetambémfazerocursodatadessaapostilanaCaelum

20.5EXERCÍCIOSAVANÇADOSDEPROGRAMAÇÃOCONCORRENTE

280 20.3VECTOREHASHTABLE

Page 291: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Exercícios só recomendados se você já tinha algum conhecimento prévio de programaçãoconcorrente,locks,etc.

1. Vamos enxergar o problema ao se usar uma classe que não é thread-safe: a ArrayList por

exemplo.

Imaginequetemosumobjetoqueguardatodasasmensagensqueumaaplicaçãodechatrecebeu.Vamosusar umaArrayList<String> para armazená-las.Nossa aplicação émulti-thread, então

diferentesthreadsvãoinserirdiferentesmensagensparaseremregistradas.Nãoimportaaordemqueelassejamguardadas,desdequeelasumdiasejam!

Vamosusaraseguinteclasseparaadicionarasqueries:

publicclassProduzMensagensimplementsRunnable{privateintcomeco;privateintfim;privateCollection<String>mensagens;

publicProduzMensagens(intcomeco,intfim,Collection<String>mensagens){this.comeco=comeco;this.fim=fim;this.mensagens=mensagens;}

publicvoidrun(){for(inti=comeco;i<fim;i++){mensagens.add("Mensagem"+i);}}}

Vamos criar três threads que rodem esse código, todas adicionando as mensagens na mesmaArrayList.Emoutraspalavras,teremosthreadscompartilhandoeacessandoummesmoobjeto:é

aquiquemoraoperigo.

publicclassRegistroDeMensagens{

publicstaticvoidmain(String[]args)throwsInterruptedException{Collection<String>mensagens=newArrayList<String>();

Threadt1=newThread(newProduzMensagens(0,10000,mensagens));Threadt2=newThread(newProduzMensagens(10000,20000,mensagens));Threadt3=newThread(newProduzMensagens(20000,30000,mensagens));

t1.start();t2.start();t3.start();

//fazcomqueathreadquerodaomainaguardeofimdessast1.join();t2.join();t3.join();

ELOCKS

20.5EXERCÍCIOSAVANÇADOSDEPROGRAMAÇÃOCONCORRENTEELOCKS 281

Page 292: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

System.out.println("Threadsprodutorasdemensagensfinalizadas!");

//verificasetodasasmensagensforamguardadasfor(inti=0;i<15000;i++){if(!mensagens.contains("Mensagem"+i)){thrownewIllegalStateException("nãoencontreiamensagem:"+i);}}

//verificasealgumamensagemficounulaif(mensagens.contains(null)){thrownewIllegalStateException("nãodeviaternullaquidentro!");}

System.out.println("Fimdaexecucaocomsucesso");}}

Rodealgumasvezes.Oqueacontece?

2. Testeocódigoanterior,masusandosynchronizedaoadicionarnacoleção:

publicvoidrun(){for(inti=comeco;i<fim;i++){synchronized(mensagens){mensagens.add("Mensagem"+i);}}}

3. SemusarosynchronizedtestecomaclasseVector,queéumaCollectioneéthread-safe.

Oquemudou?OlheocódigodométodoaddnaclasseVector.Oquetemdediferentenele?

4. Novamentesemusarosynchronized,testeusarHashSeteLinkedList,emvezdeVector.

Façaváriostestes,poisasthreadsvãoseentrelaçarcadavezdeumamaneiradiferente,podendoounãoterumefeitoinesperado.

NocapítulodeSocketsusaremosthreadsparasolucionarumproblemarealdeexecuçõesparalelas.

282 20.5EXERCÍCIOSAVANÇADOSDEPROGRAMAÇÃOCONCORRENTEELOCKS

Page 293: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO21

"Quempoucopensa,engana-semuito."--LeonardodaVinci

Comovimos antes, aVMé apenasumaespecificaçãoedevemosbaixaruma implementação.HámuitasempresasqueimplementamumaVM,comoaprópriaOracle,aIBM,aApacheeoutros.

AdaOracleé amaisusadaepossuiversõesparaWindows,LinuxeSolaris.VocêpodebaixaroSDKacessando:

http://www.oracle.com/technetwork/java/

NestapáginadaOracle,vocêdeveescolheroJavaSE,dentrodostopdownloads.Depois,escolhaoJDKeseusistemaoperacional.

CadadistribuiçãoLinuxtemsuaprópriaformadeinstalação.AlgumasjátrazemoJavajunto,outraspossibilitamquevocêinstalepelosrepositóriosoficiaiseemalgunscasosvocêprecisabaixardiretodaOracleeconfigurartudomanualmente.

NoUbuntu,adistribuiçãousadanaCaelum,ainstalaçãoébastantesimples.Bastairnoterminaledigitar:

sudoadd-apt-repositoryppa:webupd8team/javasudoapt-getupdatesudoapt-getinstalloracle-java8-installer

Casoprefirautilizaroopenjdk,adistribuiçãoopensource,bastafazer

sudoapt-getinstallopenjdk-7-jdk

Porenquantoelepossuiapenasaversão7.Nolinuxfedora,vocêfariacomsu-c"yuminstall

java-1.7.0-openjdk".

SevocêjátiveroutrasversõesinstaladasnoseuUbuntu,podeutilizarsudoupdate-alternatives

--configjavaparaescolherentreelas.

Umainstalaçãomaisbraçal,semusarrepositório ,podeserfeitabaixandooinstaladornoprópriosite daOracle. É umtar.gz que possui um.bin que deve ser executado. Depois, é necessário

APÊNDICE-INSTALAÇÃODOJAVA

21.1INSTALANDONOUBUNTUEEMOUTROSLINUX

21APÊNDICE-INSTALAÇÃODOJAVA 283

Page 294: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

apontarJAVA_HOMEparaessediretórioeadicionarJAVA_HOME/binnoseuPATH.

Conheça aCasa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Coma curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

OMacOSXjátrazoJavainstaladojuntocomosistemaoperacionalatéaversão10.6.Asversõesmaisnovas,doLionemdiante,o instaladordoMacvaiperguntarsevocêdesejabaixá-loquandoforrodarsuaprimeiraaplicaçãoJava,comooEclipse.

AversãoparaoJava8podeserbaixadanomesmosite:

http://www.oracle.com/technetwork/java/

Para instalar o JDK no Windows, primeiro baixe-o no site da Oracle. É um simples arquivoexecutávelquecontémoWizarddeinstalação:

http://www.oracle.com/technetwork/java/

Seuslivrosdetecnologiaparecemdoséculopassado?

21.2NOMACOSX

21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS

284 21.2NOMACOSX

Page 295: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Dêumcliqueduplonoarquivojdk-<versão>-windows-i586-p.exeeespereatéeleentrarno

wizarddeinstalação.

Aceite os próximos dois passos clicando em Next. Após um tempo, o instalador pedirá paraescolheremquediretórioinstalaroSDK.Podeserondeelejáoferececomopadrão.Anotequalfoiodiretórioescolhido,vamosutilizaressecaminhomaisadiante.Acópiadearquivosiniciará:

Instalação

21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS 285

Page 296: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Oinstalador instalará tambémo JavaFX2.Após isso,você serádirecionadoàumapáginaondevocêpode,opcionalmente,criarumacontanaOraclepararegistrarsuainstalação.

Precisamosconfiguraralgumasvariáveisdeambienteapósainstalação,paraqueocompiladorsejaacessívelvia linhade comando.CasovocêváutilizardiretamenteoEclipse, provavelmentenão seránecessáriorealizaressespassos.

CliquecomobotãodireitoemcimadoíconeComputadoreselecioneaopçãoPropriedades.

Escolha a aba "Configurações Avançadas de Sistema" e depois clique no botão "Variáveis deAmbiente"

Configurandooambiente

286 21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS

Page 297: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Nestatela,vocêverá,napartedecima,asvariáveisdeambientedousuáriocorrentee,embaixo,asvariáveisdeambientedocomputador(servemparatodososusuários).CliquenobotãoNovo...dapartedebaixo.

EmNome da Variável digite JAVA_HOME e, em valor da variável, digite o caminho que você

utilizou na instalação do Java. Provavelmente será algo como: C:\Program

Files\Java\jdk1.8.0_03:

CliqueemOk.

Nãovamoscriaroutravariável,massimalterar.Paraisso,procureavariávelPATH,ouPath(dá

21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS 287

Page 298: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

nomesmo),ecliquenobotãodebaixo"Editar".

Nãoaltereonomedavariável!Deixecomoestáeadicionenofinaldovalor;%JAVA_HOME%\bin,

não esqueça do ponto-e-vírgula - assim, você está adicionandomais umcaminho à sua variávelPath.

Abraoprompt,indoemIniciar,Executaredigitecmd.

No console, digite javac-version. O comando deve mostrar a versão do Java Compiler e

algumasopções.

VocêpodeseguirparaainstalaçãodoEclipse,conformevistonoseucapítulo,ouutilizarumeditordetextosimplescomooblocodenotasparaosprimeiroscapítulosdeapostila.

Qualquerdúvida,nãohesitedepostá-lanoGrupodeUsuáriosJava:

http://www.guj.com.br.

288 21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS

Page 299: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

CAPÍTULO22

"Olhoporolho,eomundoacabarácego."--MohandasGandhi

Debugging(emportuguês,depuraçãooudepurar)éumprocessodereduzirouencontrarbugsnoseusistema. De uma forma geral, debugging não é uma tarefa fácil de ser executada.Muitas variaçõespodem atrapalhar esse processo, por exemplo, a linguagem que estamos utilizando e ferramentasdisponíveisparafazermosdebuggingdeumcódigo.

OJavaemsifacilitamuitonesteprocesso,poisnosfornecemaneirasdesabermosseocódigoestáerrado, por exemplo as exceptions. Em linguagens de baixo nível saber onde o bug estava eraextremamentecomplicado.Oquetambémfacilitanossotrabalhosãoasferramentasdedebug.Veremosqueelassãonecessáriasnoscasosquenossostestesdeunidadedeloggingnãoforamsuficientesparaencontrararazãodeumproblema.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design,Infra,Front-Ende

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

No curso utilizamos o Eclipse como IDE para desenvolvermos nosso código. Como foi ditoferramentasdedebuggingfacilitammuitonossotrabalho,oEclipseéumadasIDEsmaispoderosasdomercadoenosforneceumaferramentaquetornaoprocessoextremamentesimples.

APÊNDICE-DEBUGGING

22.1OQUEÉDEBUGAR

Agoraéamelhorhoradeaprenderalgonovo

22.2DEBUGANDONOECLIPSE

22APÊNDICE-DEBUGGING 289

Page 300: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

O primeiro recurso que temos que conhecer quando começamos a debugar no Eclipse são osbreakpoints. Eles são pontos de partida em nosso código para iniciarmos o processo de debug. Porexemplo, no código abaixo, imagine que desejamos debugar o comportamento dométodosaca da

classeConta,maisespecificamentedoifqueverifica se saldoémenorqueovalora ser sacado.

Colocaríamosobreakpointexatamentenalinhaif(this.saldo<valor){:

publicclassConta{

privatedoublesaldo;

publicbooleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo=this.saldo-valor;returntrue;}}}

Mascomofaçoisso?Muitosimples,bastaclicarnalinhaquedesejaadicionarobreakpoint,depoisclicarnomenuRun->ToogleBreakpoint.

Esseéotipomaisclássicodebreakpoint,veremosalgunsoutrosaolongodocapítulo.

Agora que já adicionamos o breakpoint que é o ponto de partida, vamos debugar nosso código.Precisamosrodarnossocódigo,ouseja,chamarométodosacaparaqueobreakpointsejaencontrado.

Teremosumcódigosimilaraoseguinte:

publicclassTestaConta{

290 22.2DEBUGANDONOECLIPSE

Page 301: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicstaticvoidmain(String[]args){Contaconta=newConta();conta.saca(200);}}

O processo normal para executarmos esse código seria clicar no menuRun -> Run As -> JavaApplication. Porém para rodar o nosso código emmododebug e ativar nosso breakpoint, devemosrodarocodigonomenuRun->DebugAs->JavaApplication.Quandoumbreakpointforencontradonocódigoqueestásendoexecutado,oeclipseexibiráumaperspectivaespecíficadedebug,apontandoparaalinhaquetemobreakpoint.

Temos várias informações disponíveis nessa perspectiva, algumas são essenciais e básicas paratrabalharmos com debug no nosso dia-a-dia, outras não tão relevantes e só usamos em casosmuitoespecíficos.

Dentro da perspectiva de debug, temos uma aba chamada Variables. São exibidas todas as

variáveisencontradasdentrodocódigoquevocêestádebugando.Porexemplo,nodebugquefizemosserãoexibidasasvariáveisdométodosaca,nestecaso,valor.Alémdosatributosde instânciado

objeto.

22.3PERSPECTIVADEDEBUG

22.3PERSPECTIVADEDEBUG 291

Page 302: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Podemosexibirmaisinformaçõessobreasvariáveis,bastaadicionarmosascolunasquedesejamosnatabelaexibida.

Épossíveltambémadicionarmosconstantesevariáveisestáticasdaclassequeestásendodebugada.

NaabaBreakpoints sãoexibidos todososbreakpointsqueseuworkspacepossui.Masporque

isso é importante? É importante porque podemos ver todos os pontos de debug presentes e melhor,podemosdesabilitá-losumaumoutodosdeumasóvez.Vocêpodeatémesmopedirparaexportarosbreakpoints.

Paradesabilitarouhabilitar todosbreakpointsbastaclicarmosno íconeSkipAllBreakpoints. Sequisermosdesabilitarumaum,bastadesmarcarocheckboxeobreakpointserádesativado.Àsvezes,encontrarocódigoondeobreakpointfoicolocadopodesercomplicado,naabaBreakpointsissofica

bemfácildefazer,bastadarumduplocliquenobreakpointeoeclipseautomaticamentenosmostraaclasse"dona"dele.

Quandoestamosdebugandocódigo,muitasvezeséinteressantesaberovalordealgumaexpressãooumétodo.Porexemplo,umacondiçãodentrodeumif,this.saldo>valor.Essevalornãoestáem

292 22.3PERSPECTIVADEDEBUG

Page 303: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

umavariável,eleestáemumaexpressão,oquepodetornarsaberovalordelacomplicado.Afeaturede Expressions descomplica esse processo para nós. Na perspectiva de Debug temos a aba

Expressions.Bastaclicarcomodireitodentrodaaba,eclicaremAddExpression:

Eoresultadodaexpressãoéexibido.

TemosoutraabaimportantechamadadeDebug.Dentreasfunçõesdelaestão:

Threads -Exibe as threads que estão sendo executadas, emelhor,mostra qual thread efetuou achamada para ométodo onde está o debug.Além dissomostra a pilha de execução, o que nospermitevoltarachamadadeummétodoBarradenavegação-Quepermitealterarmososcaminhosqueodebugseguirá.

Alistaaseguirmostraralgumasteclasebotõesquealteramocaminhonaturaldosnosssdebug:

F5-Vaiparaopróximopassodoseuprograma.Seopróximopassoforummétodo,eleentraránocódigoassociado;F6-Tambémvaiparaopróximopasso,porémseopróximopassoforummétodo,elenãoentraránocódigoassociado;F7-Voltaráemostraráométodoquefezachamadaparaocódigoqueestásendodebugado.NonossocasovoltaráparaométodomaindaclasseTestaConta;

22.3PERSPECTIVADEDEBUG 293

Page 304: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

F8 -Vaiparaopróximobreakpoint,senenhumforencontrado,oprogramaseguiráseufluxodeexecuçãonormal.

VocêtambémpodeusarosbotõesqueestãopresentesnaabaDebug.

Depoisquecolocamosumbreakpointemalgumpontodonossocódigo,podemoscolocaralgumaspropriedadesnele,porexemplo,usaralgumacondiçãopararestringirquandoobreakpointseráativadoemtempodeexecução.PodemosrestringirnapropriedadeHitCountqueobreakpointsóseráativadoquandoalinhaemqueeleencontra-seforexecutada'X'vezes.

Como na imagem acima o breakpoint só será ativado quando a linha de código em que ele seencontraforexecutada'2'vezes.Podemostambémcolocaralgumaexpressãocondicional,umif,por

22.4DEBUGAVANÇADO

294 22.4DEBUGAVANÇADO

Page 305: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

exemplo.

O breakpoint, neste caso, somente será ativado quando o argumentovalor que foi passado ao

métodosacaformaiorque100.Oimportanteaquiénotarmosquedevemosretornarsempreumvalorbooleano,senãoofizermos,teremosumerroemtempodeexecução.EssapropriedadeéválidaquandoqueremoscolocaraquelesfamososSystem.out.println("entrounoiftal")paraefeitode log,

podemosfazerissocolocandoologdentrodaexpressãocondicionalnaspropriedadesdobreakpoint.

O display é uma das partes mais interessantes do debug do eclipse, ele provê uma maneira deexecutarmos qualquer código que quisermos quando estamos em debugging. Criar uma classe,instanciar objetos dessa classe, utilizar if's, for's, while's, todos os recursos do Java, além de poderutilizarasvariáveis,métodos,constantesdaclassequeestamosdebugando.

Umexemploclássicoéquandoestamosemdebuggingequeremossaberoretornodealgummétododoqualnãotemosacesso,oquefaríamosantesseriacolocarumamontoadodeSystem.out.println,

poluindoextremamentenossocódigo.Nodisplayoque fazemosé efetuar a chamadadessecódigoeautomaticamenteosresultadossãoexibidos.

Para vermos um efeito real disso, vamos alterar umpouco o comportamento da classeConta, demodoqueagoraosaldoparasaquetenhaqueserosaldorealmaisovalordolimite.Nossocódigoficaassim:

publicclassConta{

22.4DEBUGAVANÇADO 295

Page 306: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

privatedoublesaldoReal;privatedoublelimite;

publicConta(doublelimite){this.limite=limite;}

publicbooleansaca(doublevalor){if(!isSaldoSuficiente(valor)){returnfalse;}else{this.saldoReal=this.saldoReal-valor;returntrue;}}

privatebooleanisSaldoSuficiente(doublevalor){return(this.saldoReal+this.limite)>valor;}}

Reparequeoifqueverificaseosaldoésuficienteparaefetuarmososaquechamaummétodo

isSaldoSuficiente,oquepodeserumproblemaquandoestamosdebugando,afinalacondiçãodo

iféummétodo.SeutilizarmosodisplaypodemosfazerachamadadométodoisSaldoSuficiente,

verseuresultadoeomelhor,nãoafetamosodebug,apenasqueremosveroresultadodométodo,porexemplo.

ParaexibirmosaabaDisplayébemsimples.TecleCtrl+3,digiteDisplay e aaba seráexibida.Quandorodarmosnossocódigoemmododebug,podemosirnodisplay,digitarmosumachamadaparaométodo isSaldoSuficiente, executamos esse código que foi digitado selecionando-o dentro do

displayeteclandoCtrl+Shift+Deoresultadoseráimpresso,assimcomonaimagemabaixo:

Muitasvezesqueremos"seguir"algumavariáveldeinstância,ouseja,qualquerchamadaparaessavariável(leituraouescrita)queremossernotificadosdisso.Podemosusarowatchpoint,quefaránossoprogramaentraremmododebug,quandoqualqueralteraçãonavariávelqueestamosseguindoocorrer,oprogramaentraráemdebugexatamentena linhaquefezaalteração.Paracolocarmosumwatchpoint,bastadarumduplocliquenoatributodeinstânciaquedesejacolocá-lo.

296 22.4DEBUGAVANÇADO

Page 307: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Épossívelalteraressecomportamentopadrão,edefinirsevocêquerqueowatchpointsejaativadoparaleituraousomenteparaescrita.

A idéiadesse tipodebreakpointé fazernossoprogramaentraremdebugquandoalgumaexceçãoespecífica ocorrer. Quando definirmos essa exceção no Exception Breakpoint e a mesma ocorrer,automaticamente nosso programa entra em debug na linha que gerou aquela exceção. Por exemplo,vamosalterarocodigodaclasseTestaContaparaqueamesmatenhaumaNullPointerException:

22.4DEBUGAVANÇADO 297

Page 308: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

publicclassTestaConta{publicstaticvoidmain(String[]args){Contaconta=null;conta.saca(10);}}

Quando rodarmos o código acima, teremos uma NullPointerException. Pode ser útil nesses

casosdebugaresaberondeaexceçãoestáocorrendodefato,emquallinhamaisespecificamente.Parafazermos isso podemos criar um Exception Breakpoint, que debugará códigos que eventualmentelancemumaNullPointerException,porexemplo.BastaabrirmosaabaBreakpointseclicarmosnoíconeabaixo:

Seráabertaumajanelaondepodemosbuscarporumaexceçãoespecífica.

Podemosdefinir umbreakpoint que é ativadoou antes oudepois queométodo é chamado.Paradefinirmosele,bastaestaremqualquerpartedométodoquedesejamosdebugar,clicarnomenuRun->

298 22.4DEBUGAVANÇADO

Page 309: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

ToogleMethodBreakpoint.Podemoseditaraspropriedadesdessebreakpointdizendosequeremosqueele seja ativado antes(default) ou depois da execução do método. Basta acessar as propriedades domethodbreakpointealterá-las.

Éutilquandodesejamosqueumbreakpointsejaativadoquandoumaclasseespecíficaforcarregadapelaprimeiravez,chamamosessebreakpointdeClassBreakpoint.BastaclicarmosnomenuRun ->Add Class Load Breakpoint, uma janela será aberta e basta digitarmos o nome da classe eadicionarmos:

22.4DEBUGAVANÇADO 299

Page 310: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelumeobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Um dos principais hábitos que nós desenvolvedores devemos evitar é a questão da otimizaçãoprematura,ouseja,quandodesenvolvemosumaaplicaçãoparaumcliente,devemosnospreocuparematenderorequisitosfuncionaisdemaneiramaisrápidaemaissimplespossível.Opassoseguinteérefatorar seu código para que ele sejamelhorado e para que no futuro possa se adaptar as possíveismudanças.

Aregraé:"Deixeosproblemasdofuturo,paraseremresolvidosnofuturo".

EditoraCasadoCódigocomlivrosdeumaformadiferente

22.5PROFILING

300 22.5PROFILING

Page 311: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

Umadas ferramentasquenosauxiliamnaquestãodenãootimizarnossocódigoprematuramente,sãoas ferramentasdeprofiling,que tornamaparentes,porexemplo,osproblemasdememóriaecpu,quepodemfazercomqueotimizemosnossocódigo.Atualmentedevidoastécnicasqueutilizamosparaentregaralgodevalorparaocliente,focamosprincipalmentenaqualidade,aspectosfuncionais,testes,etc.Porém,muitosproblemasquenão fazempartedos requisitos funcionaispodemacontecer apenasquandoaaplicaçãoestáemprodução,nestepontoasferramentasdeprofilingtambémnosajudam.

JuntamentecomoEclipsetemosaopçãodeinstalareutilizarumaferramentadeprofilingconhecidacomoEclipseTPTP(EclipseTest&PerformanceToolsPlatform),quenosforneceopçõesparaisolareidentificarproblemasdeperformance,taiscomo:memória(memoryleak),recursoseprocessamento.OTPTPnospermiteanalisardesimplesaplicaçõesjavaatéaplicaçõesquerodamemmúltiplasmáquinaseemmúltiplasplataformas.

ALTERNATIVASAOTPTP

Existem algumas alternativas ao TPTP, os mais conhecidos são Netbeans Profiler(http://profiler.netbeans.org/) que é gratuito, e o JProfiler (http://www.ej-technologies.com/products/jprofiler/overview.html)queépago.

O TPTP não vem por padrão junto com o Eclipse. Portanto, para utilizarmos é necessário ainstalaçãodomesmo.Podemosfazeroprocessodeinstalaçãodeduasmaneiras.AprimeiraemaisfáciléutilizandooUpdateSitedoEclipsequeresolveaspossíveisdependênciasenospossibilitaescolherquaisfeaturesqueremosinstalar.ParainstalaroTPTPatravésdesserecurso,bastairnomenu:Help->InstallNewSoftware,umajanelaseráaberta,bastaclicaremAdd...epreenchê-laconformeaimagemaseguir:

Basta adicionar as ferramentas do TPTP em nosso eclipse, para isto, selecione o repositório que

22.6PROFILINGNOECLIPSETPTP

22.6PROFILINGNOECLIPSETPTP 301

Page 312: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

acabamosdeadicionareaversãodoTPTPquequeremosinstalar,nestecaso,aversão4.6.2.

INSTALANDOPELOZIP

VocêtemaopçãodeinstalaroTPTPbaixandoozipdoprojetoecolocandomanualmentenodiretório de instalação do seu eclipse. Mais informações no link:http://www.eclipse.org/tptp/home/downloads/4.6.0/documents/installguide/InstallGuide46.html

Umproblemaquepodeaconteceremaplicaçõesequemuitaspessoasnãoconhecemafundo,éaquestãodopooldeStringsquepodeeventualmenteficarmuitogrande.EsteproblemapodesercausadoporqueobjetosdotipoStringsãoimutáveis,sendoassim,sefizermosconcatenaçõesdeStringsmuitasvezes,cadaumadessasconcatenaçõesproduziráumanovaString,queautomaticamenteserácolocadanopooldaJVM.

A alternativa neste caso, seria trabalhar com objetos do tipo StringBuilder ou StringBuffer que

302 22.6PROFILINGNOECLIPSETPTP

Page 313: uso comercial deste material, por favor, consulte a Caelum ...€¦ · 35 60 76 3.6 O if e o else 26 3.7 O While 28 3.8 O For 28 3.9 Controlando loops 29 3.10 Escopo das variáveis

funcionam como Strings,mas que não produzem Strings novas em caso de uma concatenação.MascomomedirotamanhodonossopooldeString?

O TPTP possui uma aba de estatísticas que nosmostra o tempo que ummétodo levou para serexecutado,quantoprocessamentoessemétodogastou,quantodememóriafoigastocomcadamétodo.VamosanalisaralgumasdessasestatísticascriandoumcódigoqueconcateneváriasStrings,demaneiraquesobrecarregueopool,gerebastanteprocessamentoeconsumodememória.

publicclassTeste{

publicstaticvoidmain(String[]args){for(inti=0;i<1000000;i++){Stringx="a"+i;System.out.println(x);}}

}

Paraanalisarmosoresultadodocódigo,vamosrodarocódigodomainatravésdomenuRun->

ProfileAs->JavaApplication.

VERSÕES

Infelizmente o TPTP funciona somente no Windows. Versões para MacOS e Linux sãoprometidas, mas até hoje estão em desenvolvimento. Uma alternativa paga para esses outrossistemasoperacionaiséoJProfiler.

22.6PROFILINGNOECLIPSETPTP 303