FJ-11 Java e Orientação a Objetos

Preview:

Citation preview

.

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

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

Essa apostila é constantemente atualizada edisponibilizadano sitedaCaelum.Sempre consulteositeparanovasversõ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 eutilizaçãoparaministrar treinamentos são absolutamente vedadas.Parausocomercialdestematerial,porfavor,consulteaCaelumpreviamente.

SOBREESTAAPOSTILA

2233

55679

10101112121315151617171819

202023242425

Sumário

1ComoAprenderJava1.1Oqueérealmenteimportante?1.2Sobreosexercícios1.3Tirandodúvidaseindoalém

2OqueéJava2.1Java2.2UmabrevehistóriadoJava2.3MáquinaVirtual2.4Javalento?HotspoteJIT2.5VersõesdoJavaeaconfusãodoJava22.6JVM?JRE?JDK?Oquedevobaixar?2.7OndeusareosobjetivosdoJava2.8Especificaçãoversusimplementação2.9ComooFJ-11estáorganizado2.10Compilandooprimeiroprograma2.11Executandoseuprimeiroprograma2.12Oqueaconteceu?2.13Parasabermais:comoéobytecode?2.14Exercícios:ModificandooHelloWorld2.15Oquepodedarerrado?2.16Umpoucomais...2.17Exercíciosadicionais

3VariáveisprimitivaseControledefluxo3.1Declarandoeusandovariáveis3.2Tiposprimitivosevalores3.3Exercícios:Variáveisetiposprimitivos3.4Discussãoemaula:convençõesdecódigoecódigolegível3.5Castingepromoção

SumárioCaelum

272929303132333335

363638404042434548505254545959

61616466697072747476

7777

3.6Oifeoelse3.7OWhile3.8OFor3.9Controlandoloops3.10Escopodasvariáveis3.11Umblocodentrodooutro3.12Parasabermais3.13Exercícios:Fixaçãodesintaxe3.14Desafios:Fibonacci

4Orientaçãoaobjetosbásica4.1Motivação:problemasdoparadigmaprocedural4.2Criandoumtipo4.3UmaclasseemJava4.4Criandoeusandoumobjeto4.5Métodos4.6Métodoscomretorno4.7Objetossãoacessadosporreferências4.8Ométodotransfere()4.9Continuandocomatributos4.10Parasabermais:UmaFábricadeCarros4.11Umpoucomais...4.12Exercícios:OrientaçãoaObjetos4.13Desafios4.14Fixandooconhecimento

5Modificadoresdeacessoeatributosdeclasse5.1Controlandooacesso5.2Encapsulamento5.3GetterseSetters5.4Construtores5.5Anecessidadedeumconstrutor5.6Atributosdeclasse5.7Umpoucomais...5.8Exercícios:Encapsulamento,construtoresestatic5.9Desafios

6EclipseIDE6.1OEclipse

CaelumSumário

7879818587888992

939394959798

100

102102104106107110111111113120

123123127128129131133133138

139139

6.2ApresentandooEclipse6.3ViewsePerspective6.4Criandoumprojetonovo6.5Criandoomain6.6Executandoomain6.7Pequenostruques6.8Exercícios:Eclipse6.9Discussãoemaula:Refactoring

7Pacotes-Organizandosuasclassesebibliotecas7.1Organização7.2Diretórios7.3Import7.4Acessoaosatributos,construtoresemétodos7.5UsandooEclipsecompacotes7.6Exercícios:Pacotes

8Ferramentas:jarejavadoc8.1Arquivos,bibliotecaseversões8.2GerandooJARpeloEclipse8.3Javadoc8.4GerandooJavadoc8.5Exercícios:JareJavadoc8.6Importandoumjarexterno8.7Exercícios:Importandoumjar8.8Manipulandoacontapelainterfacegráfica8.9Exercícios:Mostrandoosdadosdacontanatela

9Herança,reescritaepolimorfismo9.1Repetindocódigo?9.2Reescritademétodo9.3Invocandoométodoreescrito9.4Polimorfismo9.5Umoutroexemplo9.6Umpoucomais...9.7Exercícios:HerançaePolimorfismo9.8Discussõesemaula:Alternativasaoatributoprotected

10ClassesAbstratas10.1Repetindomaiscódigo?

SumárioCaelum

141142144146146

148148152156157158161162

164164166170171174175176177179179180182182

184184184185186190191194195

10.2Classeabstrata10.3Métodosabstratos10.4Aumentandooexemplo10.5Parasabermais...10.6Exercícios:ClassesAbstratas

11Interfaces11.1Aumentandonossoexemplo11.2Interfaces11.3Dificuldadenoaprendizadodeinterfaces11.4Exemplointeressante:conexõescomobancodedados11.5Exercícios:Interfaces11.6Exercíciosavançadosopcionais11.7Discussão:favoreçacomposiçãoemrelaçãoàherança

12Exceçõesecontroledeerros12.1Motivação12.2Exercícioparacomeçarcomosconceitos12.3ExceçõesdeRuntimemaiscomuns12.4Outrotipodeexceção:CheckedExceptions12.5UmpoucodagrandefamíliaThrowable12.6Maisdeumerro12.7Lançandoexceções12.8Oquecolocardentrodotry?12.9Criandoseuprópriotipodeexceção12.10Parasabermais:finally12.11Exercícios:Exceções12.12Desafios12.13Discussãoemaula:catchethrowsemException

13Opacotejava.lang13.1Pacotejava.lang13.2UmpoucosobreaclasseSystem13.3java.lang.Object13.4Métodosdojava.lang.Object:equalsetoString13.5Exercícios:java.lang.Object13.6java.lang.String13.7Exercícios:java.lang.String13.8Desafio

CaelumSumário

195

197197198199200201204206

207207208212213214217219221222223225227228229229233233

237237238238240242243244245

13.9Discussãoemaula:OquevocêprecisafazeremJava?

14Umpoucodearrays14.1Oproblema14.2Arraysdereferências14.3Percorrendoumaarray14.4PercorrendoumaarraynoJava5.014.5Exercícios:Arrays14.6Umpoucomais...14.7DesafiosOpcionais

15Collectionsframework15.1Arrayssãotrabalhosos,utilizarestruturadedados15.2Listas:java.util.List15.3ListasnoJava5eJava7comGenerics15.4Aimportânciadasinterfacesnascoleções15.5Ordenação:Collections.sort15.6Exercícios:Ordenação15.7Conjunto:java.util.Set15.8Principaisinterfaces:java.util.Collection15.9PercorrendocoleçõesnoJava515.10Parasabermais:Iterandosobrecoleçõescomjava.util.Iterator15.11Mapas-java.util.Map15.12Parasabermais:Properties15.13Parasabermais:EqualseHashCode15.14Parasabermais:Boaspráticas15.15Exercícios:Collections15.16Desafios15.17Parasabermais:Comparators,classesanônimas,Java8eolambda

16Pacotejava.io16.1ConhecendoumaAPI16.2Orientaçãoaobjetosnojava.io16.3InputStream,InputStreamReadereBufferedReader16.4LendoStringsdoteclado16.5Aanalogiaparaaescrita:OutputStream16.6Umamaneiramaisfácil:ScannerePrintStream16.7Umpoucomais...16.8Integereclasseswrappers(box)

SumárioCaelum

245246247249

251251251252252

254254257259260261

264264264265266267268270271273273274

278278280281282282

285285286

16.9AutoboxingnoJava5.016.10Parasabermais:java.lang.Math16.11Exercícios:JavaI/O16.12Discussãoemaula:DesignPatternseoTemplateMethod

17Eagora?17.1Web17.2PraticandoJavaeusandobibliotecas17.3GruposdeUsuários17.4Próximoscursos

18Apêndice-ProgramaçãoConcorrenteeThreads18.1Threads18.2Escalonadoretrocasdecontexto18.3GarbageCollector18.4Exercícios18.5Easclassesanônimas?

19Apêndice-Sockets19.1Motivação:umaAPIqueusaosconceitosaprendidos19.2Protocolo19.3Porta19.4Socket19.5Servidor19.6Cliente19.7Imagemgeral19.8Exercícios:Sockets19.9Desafio:MúltiplosClientes19.10Desafio:broadcastdasmensagens19.11Soluçãodosistemadechat

20Apêndice-Problemascomconcorrência20.1Threadsacessandodadoscompartilhados20.2Controlandooacessoconcorrente20.3VectoreHashtable20.4Umpoucomais...20.5Exercíciosavançadosdeprogramaçãoconcorrenteelocks

21Apêndice-InstalaçãodoJava21.1InstalandonoUbuntueemoutrosLinux21.2NoMacOSX

CaelumSumário

286

291291291294300309309

21.3InstalaçãodoJDKemambienteWindows

22Apêndice-Debugging22.1Oqueédebugar22.2DebugandonoEclipse22.3Perspectivadedebug22.4Debugavançado22.5Profiling22.6ProfilingnoEclipseTPTP

Versão:21.5.22

SumárioCaelum

.

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éprimordialaprenderno 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,quedevesertratadaseriamente:todososexercíciossãomuito importantes e os desafios podem ser feitos quando o curso terminar. De qualquer maneirarecomendamosaosalunosestudarememcasa,epraticarembastantecódigoevariações.

OCURSO

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

COMOAPRENDERJAVA

1.1OQUEÉREALMENTEIMPORTANTE?

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%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.Eles focammaisnoproblemacomputacionalquenalinguagem,porémsãoumaexcelenteformadetreinarasintaxee,principalmente,familiarizar o aluno com a 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

ACaelumfornecemuitosoutroscursosJava,comdestaqueparaoFJ-21quetrazaaplicaçãodoJavanaweb.

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

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

JáconheceoscursosonlineAlura?

1.2SOBREOSEXERCÍCIOS

1.3TIRANDODÚVIDASEINDOALÉM

.

Alura:

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

.

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? falta debibliotecas? ter de reescrever parte docó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, como tvs, videocassetes, aspiradores, liquidificadores e outros.Apesar disso a linguagemteveseulançamentofocadonousoemclientesweb(browsers)pararodarpequenasaplicações(applets).Hoje emdia essenãoéograndemercadodo Java: apesarde ter sido idealizadocomumpropósito elanç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

.

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

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

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

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

Aideianãodeucerto.Tentaramfechardiversoscontratoscomgrandes fabricantesdeeletrônicos,comoPanasonic,masnãohouveêxitodevidoaoconflitode interesses e custos.Hoje, sabemosqueoJavadominaomercadodeaplicaçõesparacelularescommaisde2.5bilhõesdedispositivoscompatí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 seria grandevantagempoderprogramarnumaúnicalinguagem, independente da plataforma. Foi aí que o Java 1.0 foi lançado: focado em transformar obrowser de apenas um cliente magro (thin client ou terminal burro) em uma aplicação que possa

SaberinglêsémuitoimportanteemTI

2.2UMABREVEHISTÓRIADOJAVA

.

tambémrealizaroperaçõesavançadas,enãoapenasrenderizarhtml.

OsappletsdeixaramdeserofocodaSun,enemaOraclenuncateveinteresse.Écuriosonotarqueatecnologia 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.AOraclesemprefoi,juntocomaIBM,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áriocompilarumavez

2.3MÁQUINAVIRTUAL

.

paraWindows,outraparaoLinux,eassimpordiante,casoagentequeiraqueessenossosoftwarepossaserutilizadoemváriasplataformas.EsseéocasodeaplicativoscomooOpenOffice,Firefoxeoutros.

Como foi dito anteriormente, na maioria 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 de má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.

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çãodessalinguagem,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 em vista que isso vaiprovavelmentemelhoraraperformancedasuaaplicação.EssecompiladoréoJIT:JustinTimeCompiler,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ácomperformanceadequadaeotimizarmaisumpoucoaqueletrecho,ouaindamudaraestratégiadeotimização.ÉporessemotivoqueasJVMsmaisrecentesemalgunscasoschegamaganhardecódigosCcompiladoscomoGCC3.x.

2.4JAVALENTO?HOTSPOTEJIT

.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Java1.0e1.1sãoasversõesmuitoantigasdoJava,mas já traziambibliotecas importantescomooJDBCeojava.io.

Com o Java 1.2 houve um aumento grande no tamanho da API, e foi nesse momento em quetrocaramanomenclaturadeJavaparaJava2,comoobjetivodediminuiraconfusãoquehaviaentreJavaeJavascript.Mas lembre-se,nãoháversão"Java2.0",o2 foi incorporadoaonome, 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 = Java Runtime Environment, ambiente de execução Java, formado pela JVM ebibliotecas, tudoquevocêprecisaparaexecutarumaaplicação Java.Masnósprecisamosdemais.JDK=JavaDevelopmentKit:Nós,desenvolvedores,faremosodownloaddoJDKdoJavaSE

AprendasedivertindonaAluraStart!

2.5VERSÕESDOJAVAEACONFUSÃODOJAVA2

2.6JVM?JRE?JDK?OQUEDEVOBAIXAR?

.

(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çãodoJDKparamaioresdetalhes.

Nodecorrerdocurso,vocêpodeacharqueoJavatemmenorprodutividadequandocomparadacomalinguagemquevocêestáacostumado.

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

Ofocodaplataformaéoutro:aplicaçõesdemédioagrandeporte,ondeotimededesenvolvedorestemváriaspessoasesemprepodeviramudarecrescer.NãotenhadúvidasquecriaraprimeiraversãodeumaaplicaçãousandoJava,mesmoutilizandoIDEseferramentaspoderosas,serámaistrabalhosoquemuitas linguagens script ou de alta produtividade. Porém, comuma linguagemorientada a objetos emaduracomooJava,seráextremamentemaisfácilerápidofazeralteraçõesnosistema,desdequevocêsigaasboaspráticaserecomendaçõessobredesignorientadoaobjetos.

Alémdisso, a quantidade enormede bibliotecas gratuitas para realizar osmais diversos trabalhos(tais como relatórios, gráficos, sistemas de busca, geração de código de barra,manipulação deXML,tocadores de vídeo, manipuladores de texto, persistência transparente, impressão, etc) é um pontofortíssimoparaadoçãodoJava:vocêpodecriarumaaplicaçãosofisticada,usandodiversosrecursos,semprecisarcomprarumcomponenteespecífico,quecostumasercaro.OecossistemadoJavaéenorme.

Cada linguagemtemseuespaç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.

Apesardisto,aSunempenhou-seemtentarpopularizarousodoJavaemaplicaçõesdesktop,mesmocom o fracomarketshare do Swing/AWT/SWT em relação às tecnologias concorrentes (em especialMicrosoft.NET).AatualtentativaéoJavaFX,ondeaOracleteminvestidobastante.

2.7ONDEUSAREOSOBJETIVOSDOJAVA

.

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a 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.QuandofazemosodownloadnositedaOracle,oquevemjuntoéaOracleJVM.Emoutraspalavras,existemoutrasJVMsdisponíveis,comoaJRockitdaBEA(tambémadquiridapelaOracle),aJ9daIBM,entreoutras.

Esseéoutroponto interessanteparaasempresas.CasonãoestejamgostandodealgumdetalhedaJVMdaOracleouprefiramtrabalharcomoutraempresa,pagandoporsuporte,elaspodemtrocardeJVMcomagarantiaabsolutadequetodoosistemacontinuará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çopode serumpouco frustrante: exemplos simples, controlede fluxocomoif,for,whileecriaçãodepequenosprogramasquenemaomenoscaptamdadosdoteclado.Apesardeissotudosernecessário,ésónos20%finaisdocursoqueutilizaremosbibliotecaspara,nofinal,criarmosumchat 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

.

Depois desse capítulo no qual o Java, a JVM e primeiros conceitos são passados, veremos oscomandosbásicosdojavaparacontroledefluxoeutilizaçãodevariáveisdotipoprimitivo.Criaremosclassespara testar essepequenoaprendizado, semsaberexatamenteoqueéuma classe. Issodificultaaindamais a curva de aprendizado, porém cada conceito será introduzido nomomento consideradomaisapropriadopelosinstrutores.

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,dandotodaafundaçãopara,então,passarmosaestudarasprincipaisemaisutilizadasAPIsdoJavaSE.

AsAPIsestudadasserãojava.utilejava.io.Todaselasusameabusamdosconceitosvistosnodecorrerdocurso,ajudandoasedimentá-los.Juntamente,temososconceitosbásicosdousodeThreads,eosproblemaseperigosdaprogramaçãoconcorrentequandodadossãocompartilhados.

Resumindo: o objetivo do curso é apresentar o Java ao mesmo tempo que os fundamentos daorientaçãoaobjetossãointroduzidos.Bateremosmuitonopontodedizerqueoimportanteécomoasclasses se relacionamequal éopapelde cadauma, enão emcomoelas realizamas suasobrigaçõ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

.

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

NOTAÇÃO

Todososcódigosapresentadosnaapostilaestãoformatadoscomrecursosvisuaisparaauxiliaraleituraecompreensãodosmesmos.Quandofordigitaroscódigosnocomputador,trateoscó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 bytecodecorrespondenteaoseucó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.

.

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!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

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

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

Agoraéamelhorhoraderespirarmaistecnologia!

2.11EXECUTANDOSEUPRIMEIROPROGRAMA

2.12OQUEACONTECEU?

.

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ção Javacomeç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údoentreaspassejacolocadonatela.

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?

.

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,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. Altereseuprogramaparaimprimirumamensagemdiferente.2. AltereseuprogramaparaimprimirduaslinhasdetextousandoduaslinhasdecódigoSystem.out.3. Sabendoqueoscaracteres\n representamumaquebrade linhas, imprimaduas linhasde texto

usandoumaúnicalinhadecódigoSystem.out.

Muitos errospodemocorrernomomentoquevocê rodar seuprimeirocódigo.Vamosveralgunsdeles:

Código:

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

Erro:

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

Esseéoerrodecompilaçãomaiscomum:aqueleondeumpontoevírgula foraesquecido.Repare

EditoraCasadoCódigocomlivrosdeumaformadiferente

2.14EXERCÍCIOS:MODIFICANDOOHELLOWORLD

2.15OQUEPODEDARERRADO?

.

queocompiladoréexplícitoemdizerquealinha4éacomproblemas.Outroserrosdecompilaçãopodemocorrersevocêescreveupalavraschaves(asquecolocamosemnegrito)emmaiúsculas,esqueceudeabrirefecharas{},etc.

Duranteaexecução,outroserrospodemaparecer:

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

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

Se tentar acessar uma classe no diretório ou classpath errado, ou se o nome estiver errado,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...

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. UmarquivofonteJavadevesempreteraextensão.java,ouocompiladororejeitará.Alémdisso,existemalgumasoutras regrasnahoradedar onomedeumarquivo Java.Experimente gravar ocódigodestecapítulocomOutroNome.javaoualgosimilar.

Compileeverifiqueonomedoarquivogerado.Comoexecutarasuaaplicação?

JáconheceoscursosonlineAlura?

2.17EXERCÍCIOSADICIONAIS

.

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, quepassa a existir apartirdaquela linha.Ela édo tipoint,queguardaumnúmerointeiro.Apartirdaí,vocêpodeusá-la,primeiramenteatribuindovalores.

Alinhaaseguiréatraduçãode:"idadedevevalerquinze".

idade=15;

COMENTÁRIOSEMJAVA

Parafazerumcomentárioemjava,vocêpodeusaro//paracomentaratéofinaldalinha,ouentãousaro/**/paracomentaroqueestiverentreeles.

/*comentáriodaqui,ateaqui*/

//umalinhadecomentáriosobreaidadeintidade;

VARIÁVEISPRIMITIVASECONTROLEDEFLUXO

3.1DECLARANDOEUSANDOVARIÁVEIS

.

Além de atribuir, você pode utilizar esse valor. O código a seguir declara novamente a variávelidadecomvalor15eimprimeseuvalornasaídapadrãoatravésdachamadaaSystem.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 comvalordeidademaisum.

//calculaaidadenoanoseguinteintidadeNoAnoQueVem;idadeNoAnoQueVem=idade+1;

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

intidade=15;

Vocêpodeusarosoperadores+,-,/eparaoperarcomnúmeros,sendoelesresponsáveispelaadição,subtração, divisão e multiplicação, respectivamente. Além desses operadores básicos, há o operador %(módulo)quenadamaiséqueo*restodeumadivisãointeira.Vejaalgunsexemplos:

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

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

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

.

COMORODARESSESCÓDIGOS?

Vocêdevecolocaressestrechosdecódigodentrodoblocomainquevimosnocapítuloanterior.Isto é, isso deve ficar nomiolo doprograma.Use bastanteSystem.out.println, dessa formavocêpodeveralgumresultado,casocontrário,aoexecutaraaplicação,nadaaparecerá.

Porexemplo,paraimprimiraidade eaidadeNoAnoQueVem podemos escrever o seguinteprogramadeexemplo:

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úmerocompontoflutuante(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 reservadasdo Java.É comumqueumboolean seja determinadoatravé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';System.out.println(letra);

.

Variáveisdotipocharsãopoucousadasnodiaadia.VeremosmaisafrenteousodasStrings,queusamosconstantemente,porémestasnãosãodefinidasporumtipoprimitivo.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

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.Quandoipassaavaler6,seráquejtambémmudadevalor?Não,poisovalordeumtipoprimitivosempreécopiado.

Apesardalinha2fazerj=i,apartirdessemomentoessasvariáveisnãotemrelaçãonenhuma:oqueacontececomuma,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.

SaberinglêsémuitoimportanteemTI

3.2TIPOSPRIMITIVOSEVALORES

.

1. Naempresaondetrabalhamos,hátabelascomoquantofoigastoemcadamês.Parafecharobalançodoprimeirotrimestre,precisamossomarogastototal.Sabendoque,emJaneiro,foramgastos15000reais,emFevereiro,23000reaiseemMarço,17000reais,façaumprogramaquecalculeeimprimaogastototalnotrimestre.Sigaessespassos:

Crie uma classe chamada BalancoTrimestral com um bloco main, como nos exemplosanteriores;Dentrodomain(omiolodoprograma),declareumavariávelinteirachamadagastosJaneiroeinicialize-acom15000;Crie também as variáveis gastosFevereiro e gastosMarco, inicializando-as com 23000 e17000,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 a mé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.3EXERCÍCIOS:VARIÁVEISETIPOSPRIMITIVOS

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

.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Algunsvaloressãoincompatíveissevocêtentarfazerumaatribuiçãodireta.Enquantoumnúmerorealcostumaserrepresentadoemumavariáveldotipodouble,tentaratribuireleaumavariávelintnão funciona porque é um código que diz: "i deve valerd",mas não se sabe sed 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ãotemcomosaberquevalorestarádentro desse double no momento da execução. Esse valor pode ter sido digitado pelo usuário, eninguémvaigarantirqueessaconversãoocorrasemperdadevalores.

Jánocasoaseguir,éocontrário:

inti=5;doubled2=i;

Ocódigoacimacompilasemproblemas,jáqueumdoublepodeguardarumnúmerocomousempontoflutuante.Todososinteirosrepresentadosporumavariáveldotipointpodemserguardadosemumavariáveldouble,entãonãoexistemproblemasnocódigoacima.

AprendasedivertindonaAluraStart!

3.5CASTINGEPROMOÇÃO

.

Às vezes, precisamos que um número quebrado seja arredondado e armazenado num númerointeiro.Para fazer issosemquehajaoerrodecompilação,éprecisoordenarqueonúmeroquebradosejamoldado(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,parafazerissofuncionarpodemosescreveroseguinte:

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,nahoradefazerascontas.

Atécastingcomvariáveisdotipocharpodemocorrer.Oúnicotipoprimitivoquenãopodeseratribuídoanenhumoutrotipoéoboolean.

.

CASTINGSPOSSÍVEIS

Abaixoestãorelacionados todososcastspossíveisna linguagemJava,mostrandoaconversãodeumvalorparaoutro.AindicaçãoImpl.querdizerqueaquelecastéimplícitoeautomático,ouseja, vocênãoprecisa indicaro cast explicitamente (lembrandoqueo tipobooleannãopode serconvertidoparanenhumoutrotipo).

TAMANHODOSTIPOS

Natabelaabaixo,estãoostamanhosdecadatipoprimitivodoJava.

AsintaxedoifnoJavaéaseguinte:

if(condicaoBooleana){codigo;}

3.6OIFEOELSE

.

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

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

Alémdisso,vocêpodeusaracláusulaelseparaindicarocomportamentoquedeveserexecutadonocasodaexpressãobooleanaserfalsa:

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

Você pode concatenar expressões booleanas através dos operadores ló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 ! . Esseoperadortransformaoresultadodeumaexpressã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");}

.

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<18passeaserfalsa.Eissoocorreráexatamentenomomentoemqueidade==18,oquenãoofaráimprimir18.

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

Jáowhileacimaimprimede0a9.

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

CasadoCódigo,LivrosdeTecnologia.

Outrocomandodeloopextremamenteutilizadoéofor.Aideiaéamesmadowhile:fazerumtrechode código ser repetido enquantouma condição continuar verdadeira.Mas alémdisso, oforisola tambémumespaçopara inicializaçãodevariáveiseomodificadordessasvariáveis. Isso fazcomquefiquemmaislegíveis,asvariáveisquesãorelacionadasaoloop:

for(inicializacao;condicao;incremento){codigo;}

3.7OWHILE

Seuslivrosdetecnologiaparecemdoséculopassado?

3.8OFOR

.

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ódigodofor indicaclaramentequeavariáveli serve,emespecial,paracontrolaraquantidadedelaçosexecutados.Quandousarofor?Quandousarowhile?Dependedogostoedaocasiã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ósincremento),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;}}

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

3.9CONTROLANDOLOOPS

.

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

Oescopoda variável é onomedado ao trechode código emque aquela variável existe e onde é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:

if(algumBooleano){inti=5;}else{

3.10ESCOPODASVARIÁVEIS

.

inti=10;}System.out.println(i);//cuidado!

Aquiavariávelinãoexisteforadoifedoelse!Sevocêdeclararavariávelantesdoif,vaihaveroutroerrodecompilação:dentrodoifedoelseavariávelestásendoredeclarada!Entãoocó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,gerandoumerrodecompilação.Sevocêrealmentequeracessarocontadordepoisdoloopterminar,precisadealgocomo:

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

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Umblocotambémpodeserdeclaradodentrodeoutro.Istoé,umifdentrodeumfor,ouumfordentrodeumfor,algocomo:

Agoraéamelhorhoraderespirarmaistecnologia!

3.11UMBLOCODENTRODOOUTRO

.

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

Vimos apenas os comandos mais usados para controle de fluxo. O Java ainda possui odo..whileeoswitch.Pesquisesobreelesedigaquandoéinteressanteusarcadaumdeles.

Algumasvezes,temosvárioslaçosencadeados.Podemosutilizarobreakparaquebrarolaçomaisinterno.Mas,sequisermosquebrarumlaçomaisexterno,teremosdeencadeardiversosifs e seu código ficará uma bagunça. O Java possui um artifício chamado labeled loops;pesquisesobreeles.

Oqueacontecesevocêtentardividirumnúmerointeiropor0?Epor0.0?

Existe um caminho entre os tipos primitivos que indicam se há a necessidade ou não decastingentreostipos.Porexemplo,int->long->double(umintpodesertratadocomoumdouble, mas não o contrário). Pesquise (ou teste), e posicione os outros tiposprimitivosnessefluxo.

Alémdosoperadoresde incremento,existemosdedecremento,como--i ei--.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 ser muitosimples;mas recomendamos fortemente que você faça os exercícios para se acostumar com erros decompilação,mensagensdojavac,convençãodecódigo,etc...

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

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

Nãocopieecoledeumexercíciojáexistente!Aproveiteparapraticar.

1. Imprimatodososnúmerosde150a300.

3.12PARASABERMAIS

3.13EXERCÍCIOS:FIXAÇÃODESINTAXE

.

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, vai começ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, temosumnovoxdeacordocomaseguinteregra:

sexépar,x=x/2sexéimpar,x=3*x+1imprimex

Oprogramadevepararquandoxtiverovalorfinalde1.Porexemplo,parax=13,asaídaserá:

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

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

CasadoCódigo,ebookcompreçodeebook.

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

EditoraCasadoCódigocomlivrosdeumaformadiferente

3.14DESAFIOS:FIBONACCI

.

CAPÍTULO4

"Programação orientada a objetos é uma péssima ideia, que só poderia ter nascido na Califó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,noqualrecebemosessainformação,edepoistemosqueenviaressescaracteresparaumafunçãoquevaivalidá-lo,comonopseudocódigoabaixo:

cpf=formulario->campo_cpfvalida(cpf)

AlguémteobrigaasemprevalidaresseCPF?Vocêpode, inúmerasvezes,esquecerdechamaressevalidador.Mais: considerequevocê tem50 formulárioseprecisevalidaremtodoselesoCPF.Se suaequipetem3programadorestrabalhandonessesformulá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,maseleprecisa lertudoisso,resultandoumentravemuitogrande!

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

ORIENTAÇÃOAOBJETOSBÁSICA

4.1MOTIVAÇÃO:PROBLEMASDOPARADIGMAPROCEDURAL

.

sistemagrande,simplesmentenãotemostempodelertodoocódigoexistente.

Considerandoquevocênãoerrenessepontoequesuaequipetenhaumacomunicaçãomuitoboa(percebaquecomunicaçãoexcessivapodeserprejudicialeatrapalharoandamento),aindatemosoutroproblema:imagineque,emtodoformulário,vocêtambémquerqueaidadedoclientesejavalidada-oclienteprecisatermaisde18anos.Vamosterdecolocarumif...masonde?Espalhadoportodoseucó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 existeuma forma simplesde 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.

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

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.

JáconheceoscursosonlineAlura?

4.2CRIANDOUMTIPO

.

Reparenafigura:apesardopapeldoladoesquerdoespecificarumaConta,essaespecificaçãoéumaConta?Nósdepositamosesacamosdinheirodessepapel?Não.UtilizamosaespecificaçãodaContaparapodercriarinstânciasquerealmentesãocontas,ondepodemosrealizarasoperaçõesquecriamos.

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

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

Apalavraclassevemdataxonomiadabiologia.Todososseresvivosdeumamesmaclassebiológicatêm uma série de atributos e comportamentos em comum, mas não são iguais, podem variar nosvaloresdessesatributosecomorealizamessescomportamentos.

HomoSapiensdefineumgrupodeseresquepossuemcaracterísticasemcomum,porémadefinição(a ideia, o conceito)deumHomoSapiens é um serhumano?Não.Tudo está especificadonaclasseHomoSapiens,massequisermosmandaralguémcorrer,comer,pular,precisaremosdeumainstânciadeHomoSapiens,ouentãodeumobjetodotipoHomoSapiens.

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

.

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 paradigma da orientação a objetos é justo saberdistinguiroque é classe eoqueéobjeto.É comumo inicianteutilizar,obviamentede formaerrada,essasduaspalavrascomosinônimos.

Vamoscomeçar apenas comoqueumaConta tem, enão comoque ela faz (veremos logo emseguida).

Umtipodesses,comooespecificadodeContaacima,podeserfacilmentetraduzidoparaJava:

classConta{intnumero;Stringtitular;doublesaldo;

//..}

STRING

StringéumaclasseemJava.Elaguardaumacadeiadecaracteres,umafrasecompleta.Comoestamosaindaaprendendooqueéumaclasse,entenderemoscomdetalhesaclasseStringapenasemcapítulosposteriores.

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

JátemosumaclasseemJavaqueespecificaoquetodoobjetodessaclassedeveter.Mascomousá-la?Alémdessaclasse,aindateremosoPrograma.javaeapartirdeleéquevamosutilizaraclasseConta.

4.3UMACLASSEEMJAVA

4.4CRIANDOEUSANDOUMOBJETO

.

Paracriar (construir, instanciar)umaConta, bastausar apalavra chavenew.Devemosutilizartambé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áveleoutraveznousodonew.Masháummotivo,queembreveentenderemos.

AtravésdavariávelminhaConta,podemosacessaroobjetorecémcriadoparaalterarseutitular,seusaldo,etc:

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

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

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

É importante fixarqueoponto foiutilizadopara acessar algo emminhaConta.AminhaContapertenceaoDuke,etemsaldodemilreais.

.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Dentro da classe, também declararemos o que cada conta faz e como isto é feito - oscomportamentosquecadaclassetem,istoé,oqueelafaz.Porexemplo,dequemaneiraqueumaContasacadinheiro?EspecificaremosissodentrodaprópriaclasseConta,enãoemumlocaldesatreladodasinformações da própria Conta. É por isso que essas "funções" são chamadas de mé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, nenhumainformaçãoseráenviadadevoltaaquempediu.

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

SaberinglêsémuitoimportanteemTI

4.5MÉTODOS

.

Dentrodométodo,estamosdeclarandoumanovavariável.Essavariável,assimcomooargumento,vaimorrernofimdométodo,poisesteéseuescopo.Nomomentoquevamosacessarnossoatributo,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+=paradeixarométodobemsimples.O+= somaquantidade aovalor antigodo saldo e guardanopróprio saldo, ovalorresultante.

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étodosempretemquedefiniroqueretorna,nemquedefinaquenãoháretorno,comonos

4.6MÉTODOSCOMRETORNO

.

exemplosanterioresondeestávamosusandoovoid.

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ãotemvoidna frente. Istoquerdizerque,quando é acessado, ele devolve algum tipo de informação.No caso, umboolean. A palavra chavereturnindicaqueomé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:

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.

Épor essemotivoque,diferentedos tipos primitivos comoint elong, precisamosdarnewdepoisdedeclaradaavariável:

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

Contac2;c2=newConta();}

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

Basta lembrar que, em Java,umavariávelnunca éumobjeto.Nãohá, no Java, umamaneiradecriarmosoqueéconhecidocomo"objetopilha"ou"objetolocal",poistodoobjetoemJava,semexceção,éacessadoporumavariávelreferência.

Essecódigonosdeixanaseguintesituação:

Contac1;c1=newConta();

Contac2;c2=newConta();

4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS

.

Internamente,c1ec2vãoguardarumnúmeroqueidentificaemqueposiçãodamemóriaaquelaContaseencontra.Dessamaneira,aoutilizarmoso"."paranavegar,oJavavaiacessaraContaqueseencontranaquelaposiçãodememória,enãoumaoutra.

Para quem conhece, é parecido com um ponteiro, porém você não podemanipulá-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ávelc1? É o objeto?Não.Na verdade, o valor guardado é a referência (endereço) de onde o objeto seencontranamemóriaprincipal.

Namemória,oqueacontecenessecaso:

Contac1=newConta();Contac2=c1;

.

Quandofizemosc2=c1,c2passaafazerreferênciaparaomesmoobjetoquec1 referencianesseinstante.

Então,nessecódigoemespecífico,quandoutilizamosc1ouc2estamosnosreferindoexatamenteaomesmoobjeto!Elassãoduasreferênciasdistintas,porémapontamparaomesmoobjeto!Compará-lascom"=="vainosretornartrue,poisovalorqueelascarregaméomesmo!

Outraformadeperceber,équedemosapenasumnew,entãosópodehaverumobjetoContanamemó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,paramelhorentenderasreferênciasnoJava,saibaqueonew,depoisdealocaramemóriaparaesseobjeto,devolveuma "flecha", istoé,umvalorde referência.Quandovocêatribui issoaumavariá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,esimoendereçoemqueeleseencontra.Comoemcadaumadessasvariáveisguardamosduascontascriadasdiferentemente,elasestãoemespaçosdiferentesdamemória,oquefazotestenoifvalerfalse.Ascontas podem ser equivalentes no nosso critério de igualdade, porém elas não são omesmo objeto.Quandosetratadeobjetos,podeficarmaisfácilpensarqueo==comparaseosobjetos(referências,naverdade)sãoomesmo,enãosesãoiguais.

.

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

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Esequisermosterummétodoquetransferedinheiroentreduascontas?Podemosficartentadosacriarummétodoquerecebedoisparâmetros:conta1econta2dotipoConta.Mascuidado:assimestamospensandodemaneiraprocedural.

Aideiaéque,quandochamarmosométodotransfere,játeremosumobjetodotipoConta(othis),portantoométodo recebeapenasum parâmetrodo tipoConta, aContadestino (alémdovalor):

classConta{

//atributosemétodos...

voidtransfere(Contadestino,doublevalor){

AprendasedivertindonaAluraStart!

4.8OMÉTODOTRANSFERE()

.

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.Paraficaraindamais interessante,vocêpodechamarosmétodosdeposita esacajá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áqueoobjetoéclonado?

No Java, a passagem de parâmetro funciona como uma simples atribuição como no uso do "=".Então,esseparâmetrovaicopiarovalordavariáveldotipoContaqueforpassadocomoargumento.Equaléovalordeumavariáveldessas?Seuvaloréumendereço,umareferência,nuncaumobjeto.Porissonãohácópiadeobjetosaqui.

.

Esseúltimocódigopoderiaserescritocomumasintaxemuitomaissucinta.Como?

TRANSFEREPARA

PercebaqueonomedestemétodopoderiasertransfereParaaoinvésdesótransfere.Achamadadométodo ficamuitomaisnatural, é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,sobrenomeecpfdotitulardaconta.Começaríamosatermuitosatributos...e,sevocêpensardireito,umaContanãotemnome,nemsobrenomenemcpf,quemtemessesatributoséumCliente.Entãopodemoscriarumanovaclasseefazerumacomposição

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

classCliente{Stringnome;Stringsobrenome;Stringcpf;}

classConta{intnumero;doublesaldo;Clientetitular;//..}

4.9CONTINUANDOCOMATRIBUTOS

.

Edentrodomaindaclassedeteste:

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

Aqui,simplesmentehouveumaatribuição.Ovalordavariávelcécopiadoparaoatributotitulardoobjeto aoqualminhaConta se refere. Emoutras palavras,minhaConta tem uma referência aomesmoClientequecserefere,epodeseracessadoatravésdeminhaConta.titular.

Vocêpoderealmentenavegarsobretodaessaestruturadeinformação,sempreusandooponto:

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

Ouainda,podefazerissodeumaformamaisdiretaeatémaiselegante:

minhaConta.titular.nome="Duke";

Umsistemaorientadoaobjetoséumgrandeconjuntodeclassesquevaisecomunicar,delegandoresponsabilidadesparaquemformaisaptoarealizardeterminadatarefa.AclasseBancousaaclasseContaqueusaaclasseCliente,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,queindicaumareferênciaparanenhumobjeto.

Se,emalgumcaso,vocêtentaracessarumatributooumétododealguémqueestásereferenciando

.

paranull,vocêreceberáumerroduranteaexecução(NullPointerException,queveremosmaisàfrente).Daparaperceber,então,queonewnãotrazumefeitocascata,amenosquevocêdêumvalordefault(ouuseconstrutores,quetambémveremosmaisafrente):

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

Comessecódigo,todanovaContacriadajáteráumnovoClienteassociado,semnecessidadedeinstanciá-lologoemseguidadainstanciaçãodeumaConta.Qualalternativavocêdeveusar?Dependedo caso: para todanovaConta você precisa de umnovoCliente? É essa pergunta que deve 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,vamosvercomoficariamcertasclassesrelacionadasaumafábrica de carros. Vamos criar uma classe Carro , com certos atributos, que descrevem suascaracterí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;}if(this.velocidadeAtual>=0&&this.velocidadeAtual<40){

4.10PARASABERMAIS:UMAFÁBRICADECARROS

.

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.

.

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

CasadoCódigo,LivrosdeTecnologia.

Quando declaramos uma classe, um método ou um atributo, podemos dar o nome quequisermos,seguindoumaregra.Porexemplo,onomedeummétodonãopodecomeçarcomumnúmero.Pesquisesobreessasregras.

Comovocêpodeterreparado,sempredamosnomesàsvariáveiscomletrasminúsculas.Équeexistemconvençõesdecódigo,dadaspelaOracle,parafacilitaralegibilidadedocódigoentreprogramadores. Essa convenção émuito seguida. Leia sobre ela pesquisando por "java codeconventions".

Énecessáriousar a palavra chavethis quando for acessar um atributo? Para que, então,utilizá-la?

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

Omodelodacontaaseguirseráutilizadoparaosexercíciosdospróximoscapítulos.

O objetivo aqui é criar um sistema para gerenciar as contas de umBanco.Os exercícios dessecapítulosãoextremamenteimportantes.

1. Modele uma conta. A ideia aqui é apenas modelar, isto é, só identifique que informações sãoimportantes.DesenhenopapeltudooqueumaContatemetudooqueelafaz.Eladeveteronomedotitular(String),onúmero(int), a agência (String), o saldo (double) e umadatadeabertura (String).Alémdisso, ela deve fazer as seguintes ações: saca, para retirar um valor do

Seuslivrosdetecnologiaparecemdoséculopassado?

4.11UMPOUCOMAIS...

4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS

.

saldo;deposita,paraadicionarumvaloraosaldo;calculaRendimento,paradevolverorendimentomensaldessaconta.

2. Transforme o modelo acima em uma classe Java. Teste-a, usando uma outra classe que tenha omain.Vocêdeve criar a classeda conta comonomeConta,maspodenomear comoquiser aclassedetestes,contudo,eladevepossuirométodomain.

AclasseContadeveconterpelomenososseguintesmétodos:

sacaquerecebeumvalorcomoparâmetroeretiraessevalordosaldodacontadepositaquerecebeumvalorcomoparâmetroeadicionaessevaloraosaldodaconta

calculaRendimentoquenãorecebeparâmetroalgumedevolveovalordosaldomultiplicadopor0.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ó.CrieaclasseConta, coloqueseusatributose,antesdecolocarqualquermétodo,compileoarquivo java.OarquivoConta.classserágerado,masnãopodemos"executá-lo"jáqueessaclassenãotemummain.Dequalquerforma,avantageméqueassimverificamosquenossaclasseConta jáestátomandoformaeestáescritaemsintaxecorreta.

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

Umesboçodaclassequepossuiomain:

classTestaConta{

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

.

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, por umaquestãode organização, é boa prática criar um arquivo.java paracadaclasse.Emcapítulosposteriores, veremos tambémdeterminadoscasosnosquaisvocêseráobrigadoadeclararcadaclasseemumarquivoseparado.

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

javac*.java

3. CrieummétodorecuperaDadosParaImpressao(),quenãorecebeparâmetromasdevolveotextocomtodasasinformaçõesdanossacontaparaefetuarmosaimpressão.

Dessamaneira,vocênãoprecisa ficarcopiandoecolandoummontedeSystem.out.println()paracadamudançaetestequefizercomcadaumdeseusfuncionários,vocêsimplesmentevaifazer:

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

VeremosmaisafrenteométodotoString,queéumasoluçãomuitomaiseleganteparamostrararepresentaçãodeumobjetocomoString,alémdenãojogartudoproSystem.out (sósevocê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;

Contac2=c1;

Oqueacontececomoifdoexercícioanterior?

6. (opcional)EmvezdeutilizarumaStringpararepresentaradata,crieumaoutraclasse,chamadaData.Elapossui3camposint,paradia,mêseano.Façacomquesuacontapasseausá-la. (éparecidocomoúltimoexemplodaexplicação,emqueaConta passou a ter referênciaparaumCliente).

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

classData{intdia;intmes;intano;}

.

ModifiquesuaclasseTestaContaparaquevocêcrieumaDataeatribuaelaaConta:

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

FaçaodesenhodoestadodamemóriaquandocriarmosumConta.

7. (opcional)ModifiqueseumétodorecuperaDadosParaImpressaoparaqueeledevolvaovalordadataDeAberturadaquelaConta:

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 deatribuirmosumadataparaestaConta?

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étodorecuperaDadosParaImpressaodaclasseContapossaficarassim:

classConta{//atributosemetodos

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

.

1. Ummétodopode chamar elemesmo.Chamamos issoderecursão.Vocêpoderesolver 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étodocalculaFibonacci não pode ter nenhum laço, só pode chamar elemesmo comomé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)

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

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

Sevocêestácomdificuldadeemalgumapartedessecapítulo,aproveiteetreinetudooquevimosnospequenosprogramasabaixo:

Programa1

4.13DESAFIOS

Agoraéamelhorhoraderespirarmaistecnologia!

4.14FIXANDOOCONHECIMENTO

.

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

Crieumapessoa,coloqueseunomee idade iniciais, façaalgunsaniversários(aumentandoaidade)eimprimaseunomeesuaidade.

Programa2

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

Crieumaporta,abraefecheamesma,pinte-adediversascores,alteresuasdimensõeseuseométodoestaAbertaparaverificarseelaestáaberta.

Programa3

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

Crieumacasaepinte-a.Crietrêsportasecoloque-asnacasa;abraefecheasmesmascomodesejar.UtilizeométodoquantasPortasEstaoAbertasparaimprimironúmerodeportasabertas.

.

CAPÍTULO5

"Amarcadohomem imaturo éque ele quermorrernobrementeporuma causa, enquantoamarcadohomemmaduroéquerervivermodestamenteporuma."--J.D.Salinger

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

controlar o acesso aos seus métodos, atributos e construtores através dos modificadoresprivateepublic;escrevermétodosdeacessoaatributosdotipogettersesetters;escreverconstrutoresparasuasclasses;utilizarvariáveisemétodosestáticos.

Um dos problemasmais simples que temos no nosso sistema de contas é que ométodo sacapermite 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!!}}

Podemosincluirumifdentrodonossométodosaca()paraevitarasituaçãoqueresultariaem

MODIFICADORESDEACESSOEATRIBUTOSDECLASSE

5.1CONTROLANDOOACESSO

.

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ódigoiriaserepetirao longodetodanossaaplicaçãoe,pior,alguémpodeesquecerdefazeressacomparaçãoemalgummomento,deixandoacontanasituaçãoinconsistente.AmelhorformaderesolverissoseriaforçarquemusaaclasseContaainvocarométodosacaenãopermitiroacessodiretoaoatributo.ÉomesmocasodavalidaçãodeCPF.

Para fazer issono Java,bastadeclararqueos atributosnãopodemser acessadosde forada classeatravésdapalavrachaveprivate:

classConta{privatedoublesaldo;//...}

privateéummodificadordeacesso(tambémchamadodemodificadordevisibilidade).

Marcandoumatributo comoprivado, fechamoso acesso aomesmo em relação a todas as outrasclasses,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álido ou não! Esta validação não deve ser controlada por quem está usando a classe e sim por elamesma, centralizando essa responsabilidade e facilitando futurasmudançasno sistema.Muitasoutrasvezes nem mesmo queremos que outras classes saibam da existência de determinado atributo,escondendo-oporcompleto,jáqueeledizrespeitoaofuncionamentointernodoobjeto.

Repareque,queminvocaométodosacanãofazamenorideiadequeexisteumaverificaçãoparaovalordosaque.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. Talfuncionalidade é 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, quepermite a todosacessaremumdeterminadoatributooumétodo:

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

.

EQUANDONÃOHÁMODIFICADORDEACESSO?

Atéagora,tínhamosdeclaradovariáveisemétodossemnenhummodificadorcomoprivateepublic . Quando isto acontece, o seu método ou atributo fica num estado de visibilidadeintermediárioentreoprivateeopublic,queveremosmaisprafrente,nocapítulodepacotes.

Émuitocomum,efaztodosentido,queseusatributossejamprivateequasetodosseusmétodossejampublic(nãoéumaregra!).Destaforma,todaconversadeumobjetocomoutroéfeitaportrocademensagens,istoé,acessandoseusmétodos.Algomuitomaiseducadoquemexerdiretamenteemumatributoquenãoéseu!

Melhorainda!OdiaemqueprecisarmosmudarcomoérealizadoumsaquenanossaclasseConta,adivinhe onde precisaríamosmodificar? Apenas nométodo saca, o que faz pleno sentido. Comoexemplo,imaginecobrarCPMFdecadasaque:bastavocêmodificarali,enenhumoutrocódigo,foraaclasseConta, precisará ser recompilado.Mais: as classes queusamessemétodonemprecisam ficarsabendode talmodificação!Você precisa apenas recompilar aquela classe e substituir aquele arquivo.class.Ganhamosmuitoemesconderofuncionamentodonossométodonahoradedarmanutençãoefazermodificações.

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

CasadoCódigo,ebookcompreçodeebook.

Oquecomeçamosavernessecapítuloéaideiadeencapsular,istoé,escondertodososmembrosdeumaclasse (comovimosacima), alémde esconder como funcionamas rotinas (no casométodos)donossosistema.

EditoraCasadoCódigocomlivrosdeumaformadiferente

5.2ENCAPSULAMENTO

.

Encapsularéfundamentalparaqueseusistemasejasuscetívelamudanças:nãoprecisaremosmudaruma regra de negócio em vários lugares,mas sim em apenas um único lugar, já que essa regra estáencapsulada.(vejaocasodométodosaca)

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

PROGRAMANDOVOLTADOPARAAINTERFACEENÃOPARAAIMPLEMENTAÇÃO

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

A implementaçãoemsi, o conteúdodosmétodos,não tem tanta importânciaparaousuáriodessaclasse,umavezqueelesóprecisasaberoquecadamétodopretendefazer,enãocomoelefaz,poisistopodemudarcomotempo.

EssafrasevemdolivroDesignPatterns,deEricGammaetal.Umlivrocultuadonomeiodaorientaçãoaobjetos.

Semprequevamosacessarumobjeto,utilizamossuainterface.Existemdiversasanalogiasfáceisnomundoreal:

Quandovocêdirigeumcarro,oqueteimportasãoospedaiseovolante(interface)enãoomotor que você está usando (implementação). É claro que ummotor diferente pode te darmelhoresresultados,masoqueelefazéomesmoqueummotormenospotente,adiferençaestá em como ele faz. Para trocar um carro a álcool para um a gasolina você não precisareaprender a dirigir! (trocar a implementação dos métodos não precisa mudar a interface,

.

fazendocomqueasoutrasclassescontinuemusandoelesdamesmamaneira).

Todos os celulares fazem a mesma coisa (interface), eles possuem maneiras (métodos) dediscar, ligar, desligar, atender, etc. O que muda é como eles fazem (implementação), masreparequeparaefetuarumaligaçãopoucoimportaseocelularéiPhoneouAndroid,issoficaencapsuladonaimplementaçã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,vaireceberumerrodecompilaçã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í,aclasseClienteéaúnicaresponsávelpelosseusprópriosatributos!

Omodificadorprivate fazcomqueninguémconsigamodificar,nemmesmoler,oatributoemquestão.Comisso,temosumproblema:comofazerparamostrarosaldodeumaConta,jáquenemmesmopodemosacessá-loparaleitura?

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

classConta{

5.3GETTERSESETTERS

.

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áticamaiscomumécriardoismétodos,umqueretornaovaloreoutroquemudaovalor.

Aconvençãoparaessesmétodosédecolocarapalavragetousetantesdonomedoatributo.Porexemplo,anossacontacomsaldo,limiteetitularficaassim,nocasodagentedesejardaracessoaleituraeescritaatodososatributos:

classConta{

privateStringtitular;privatedoublesaldo;

publicdoublegetSaldo(){returnthis.saldo;}

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

publicStringgetTitular(){returnthis.titular;}

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

Éumamápráticacriarumaclassee,logoemseguida,criargettersesettersparatodosseusatributos.Vocêsódevecriarumgetterousettersetiverarealnecessidade.ReparequenesseexemplosetSaldonãodeveriatersidocriado,jáquequeremosquetodosusemdeposita()esaca().

Outrodetalheimportante,ummétodogetXnãonecessariamenteretornaovalordeumatributoquechamaX doobjeto emquestão. Isso é interessanteparao encapsulamento. Imagine a situação:

.

queremosqueobancosempremostrecomosaldoovalordo limite somadoao saldo (umapráticacomumdosbancosquecostuma iludir seusclientes).Poderíamos semprechamarc.getLimite()+c.getSaldo(),masissopoderiagerarumasituaçãode"replaceall"quandoprecisássemosmudarcomoo saldo é mostrado. Podemos encapsular isso em um método e, porque não, dentro do pró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.Enemdeveexistir enquanto não houver essa necessidade.OmétodogetSaldo() não devolve simplesmente osaldo...esimoquequeremosquesejamostradocomosefosseosaldo.Utilizargettersesettersnãosó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.

.

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,eleexecutaoconstrutordaclasse.Oconstrutordaclasseéumblocodeclaradocomomesmonomequeaclasse:

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.

A partir do momento que você declara um construtor, o construtor default não é maisfornecido.

5.4CONSTRUTORES

.

Ointeressanteéqueumconstrutorpodereceberumargumento,podendoassiminicializaralgumtipodeinformaçã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);

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

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ãopodemosabrirumarquivoparaleiturasemdizerqualéonomedoarquivoquedesejamos ler! Portanto, nadamais natural que passar uma String representando o nome de um

JáconheceoscursosonlineAlura?

5.5ANECESSIDADEDEUMCONSTRUTOR

.

arquivonahoradecriarumobjetodotipodeleituradearquivo,equeissosejaobrigatório.

Vocêpodetermaisdeumconstrutornasuaclassee,nomomentodonew,oconstrutorapropriadoseráescolhido.

CONSTRUTOR:UMMÉTODOESPECIAL?

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

CHAMANDOOUTROCONSTRUTOR

Umconstrutor só pode rodar durante a construçãodo 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,dessamaneiraumClientejáseráconstruídoecomumCPFválido.

.

JAVABEAN

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

Nosso banco também quer controlar a quantidade de contas existentes no sistema. 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;

Quando declaramos um atributo como static, ele passa a não ser mais um atributo de cadaobjeto,esimumatributodaclasse,ainformaçãoficaguardadapelaclasse,nãoémaisindividualparacadaobjeto.

Paraacessarmosumatributoestático,nãousamosapalavrachavethis,massimonomedaclasse:

classConta{privatestaticinttotalDeContas;//...

5.6ATRIBUTOSDECLASSE

.

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.Usamosapalavrastaticdenovo,mudandoométodoanterior.

publicstaticintgetTotalDeContas(){returnConta.totalDeContas;}

Paraacessaressenovométodo:

inttotal=Conta.getTotalDeContas();

ReparequeestamoschamandoummétodonãocomumareferênciaparaumaConta,esimusandoonomedaclasse.

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.

.

Em algumas empresas, o UML é amplamente utilizado. Às vezes, o programador recebe oUML já pronto, completo, e só deve preencher a implementação, devendo seguir à risca oUML.Oquevocêachadessaprática?Quaisasvantagensedesvantagens.

Seumaclassesótematributosemétodosestáticos,queconclusõespodemostirar?Oquelhepareceummétodoestáticoemcasoscomoesses?

Nocasodeatributosbooleanos,pode-seusarnolugardogetosufixois.Dessamaneira,caso tivéssemos um atributo booleano ligado, em vez de getLigado poderíamos terisLigado.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

1. Adicioneomodificadordevisibilidade(private, senecessário)paracadaatributo emétododaclasseConta.TentecriarumaContanomainemodificaroulerumdeseusatributosprivados.Oqueacontece?

2. CrieapenasosgettersesettersnecessáriosdasuaclasseConta.Pensesempreseéprecisocriarcadaumdeles.Porexemplo:

classConta{privateStringtitular;

//...

publicStringgetTitular(){

5.7UMPOUCOMAIS...

SaberinglêsémuitoimportanteemTI

5.8EXERCÍCIOS:ENCAPSULAMENTO,CONSTRUTORESESTATIC

.

returnthis.titular;}

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

Nãocopieecole!Aproveiteparapraticarsintaxe.LogopassaremosausaroEclipseeaísimteremosprocedimentosmaissimplesparaestetipodetarefa.

ReparequeométodocalculaRendimentoparecetambémumgetter.Aliás,seriacomumalguémnomeá-lo de getRendimento . Getters não precisam apenas retornar atributos. Eles podemtrabalharcomessesdados.

3. ModifiquesuasclassesqueacessamemodificamatributosdeumaContaparautilizarosgettersesettersrecé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,onomedotitulardaContaduranteacriaçãodoobjeto.Utilizeconstrutoresparaobteresseresultado.

Dica:utilizeumconstrutorsemargumentos também,paraocasodeapessoanãoquererpassarotitulardaConta.

Seriaalgocomo:

classConta{publicConta(){//construtorsemargumentos}

publicConta(Stringtitular){//construtorquerecebeotitular}}

Porquevocêprecisadoconstrutorsemargumentosparaqueapassagemdonomesejaopcional?

5. (opcional)AdicioneumatributonaclasseContade tipoint que se chama identificador.Esseidentificador deve ter um valor único para cada instância do tipo Conta. A primeira Containstanciada tem identificador 1, a segunda 2, e assim por diante. Você deve utilizar os recursosaprendidosaquipararesolveresseproblema.

.

Crieumgetterparaoidentificador.Devemosterumsetter?

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

7. (opcional) Suponha que temos a classePessoaFisica que tem um CPF como atributo. Comogarantir que pessoa física alguma tenha CPF invalido, nem seja criada PessoaFisica sem cpfinicial?(Suponhaquejáexisteumalgoritmodevalidaçãodecpf:bastapassarocpfporummétodovalida(Stringx)...)

1. Porqueessecódigonãocompila?

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

2. ImaginequetenhaumaclasseFabricaDeCarroequerogarantirquesóexisteumobjetodessetipoemtodaamemória.NãoexisteumapalavrachaveespecialparaistoemJava,entãoteremosdefazernossa classe de tal maneira que ela respeite essa nossa necessidade. Como fazer isso? (pesquise:singletondesignpattern)

5.9DESAFIOS

.

CAPÍTULO6

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

Neste capítulo, você será apresentado aoAmbiente deDesenvolvimento Eclipse 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.

OEclipseéaIDElíderdemercado.FormadaporumconsórciolideradopelaIBM,possuiseucó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.

Baixe o Eclipse do site oficial http://www.eclipse.org. Apesar de ser escrito em Java, a bibliotecagráficausadanoEclipse,chamadaSWT,usacomponentesnativosdosistemaoperacional.Porissovocêdevebaixaraversãocorrespondenteaoseusistemaoperacional.

Descompacteoarquivoepronto,bastarodaroexecutável.

OUTRASIDES

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

Alémdessas,Oracle,BorlandeaprópriaIBMpossuemIDEscomerciaisealgumasversõesmaisrestritasdeusolivre.

AempresaJetBrainsdesenvolveoIntelliJIDEA,umaIDEpagaquetemganhomuitosadeptos.

ECLIPSEIDE

6.1OECLIPSE

.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

CliquenoíconedoEclipsenoseuDesktop.

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

Vocêpodedeixarodiretóriopré-definido.

Logoemseguida,uma teladeWelcome seráaberta,ondevocê temdiversos linkspara tutoriais eajuda.CliqueemWorkbench.

AprendasedivertindonaAluraStart!

6.2APRESENTANDOOECLIPSE

.

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

6.3VIEWSEPERSPECTIVE

.

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 menu Window -> Show View -> Other, você pode ver as dezenas de Views que já vem

.

embutidasnoEclipse.Acostume-seasempreprocurarnovasViews,elaspodemteajudaremdiversastarefas.

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

6.4CRIANDOUMPROJETONOVO

.

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.

.

CliqueemFinish.OEclipsepediráparatrocaraperspectivaparaJava;escolha"No"parapermaneceremResource.NaViewNavigator,vocêveráonovoprojetoesuaspastasearquivos:

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

CliqueemFinish.OEclipsepossuidiversoswizards,masusaremosomínimodeles.Ointeressanteéusarocodeassistequickfixesqueaferramentapossuieveremosemseguida.Nãoseatenteàsmilharesdeopçõesdecadawizard,apartemaisinteressantedoEclipsenãoéessa.

EscrevaométododepositacomoabaixoenotequeoEclipsereclamadeerroemthis.saldopoisesteatributonãoexiste.

.

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 corrigirboapartedos errosnahoradeprogramar e,comofizemos,economizaradigitaçãodecertoscódigosrepetitivos.Nonossoexemplo,nãoprecisamoscriarocampoantes;oEclipsefazissoparanós.Eleatéacertaatipagem,jáqueestamossomandoeleaumdouble.Oprivateécolocadopormotivosquejáestudamos.

VáaomenuFile->Saveparagravar.Control+Stemomesmoefeito.

.

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

6.5CRIANDOOMAIN

.

CrieumanovaclassechamadaPrincipal.Vamoscolocarummétodomain para testarnossaConta.Emvezdedigitartodoométodomain,vamosusarocodeassistdoEclipse.EscrevasómaineaperteCtrl+Espaçologoemseguida.

OEclipsesugeriráacriaçãodométodomaincompleto;selecioneestaopção.Ocontrol+espaçoéchamadodecodeassist.Assim comoos quick fixes sãode extrema importância.Experimenteusar ocodeassistemdiversoslugares.

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 nosajuda.EscrevasysoeaperteCtrl+EspaçoqueoEclipseescreveráSystem.out.println()paravocê.

Paraimprimir,chameoconta.getSaldo():

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

NotequeoEclipseacusaráerroemgetSaldo()porqueestemétodonãoexistenaclasseConta.VamosusarCtrl+1emcimadoerroparacorrigiroproblema:

.

OEclipsesugerecriarummétodogetSaldo()naclasseConta.Selecioneestaopçãoeométodoseráinseridoautomaticamente.

publicObjectgetSaldo(){//TODOAuto-generatedmethodstubreturnnull;}

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

publicdoublegetSaldo(){returnthis.saldo;}

EssespequenosrecursosdoEclipsesãodeextremautilidade.Dessamaneira,vocêpodeprogramarsem sepreocupar commétodosque aindanão existem, jáque aqualquermomento elepodegeraroesqueleto(apartedaassinaturadométodo).

Vamosrodarométodomaindessanossaclasse.NoEclipse,cliquecomobotãodireitonoarquivoPrincipal.javaeváemRunas...JavaApplication.

6.6EXECUTANDOOMAIN

.

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+3 e depois digitarggaseenter.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

.

Existemdezenasdeoutros.DentreosmaisutilizadospelosdesenvolvedoresdaCaelum,escolhemososseguintesparacomentar:

Ctrl+F11 roda a última classe que você rodou.É omesmoque clicar no ícone verde quepareceumbotãodeplaynabarradeferramentas.

Ctrl+PgUpeCtrl+PgDownNaveganasabasabertas.Útilquandoestivereditandováriosarquivosaomesmotempo.

Ctrl+Shift+FFormataocódigosegundoasconvençõesdoJava

Ctrl+MExpandeaViewatualparaatelatoda(mesmoefeitodedardoiscliquesnotí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!Ex-alunodaCaelumtem15%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 seguintesinformações:saldo (double),titular(String),numero (int) eagencia (String).Na classeConta, crie osmétodosdeposita esaca comonos capítulos anteriores.Crie tambémuma

Agoraéamelhorhoraderespirarmaistecnologia!

6.8EXERCÍCIOS:ECLIPSE

.

classeTesteDaConta comomain e instancieuma conta.Desta vez, tente abusardo control+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,éutilizaroatalhocontrol+3enacaixadeseleçãodigiteggas,iniciaisdeGenerateGettersandSetters!

OBS:Nãocrieumsetterparaoatributosaldo!

4. Váparaaclasseque temomain e segureoCONTROLapertado enquanto vocêpassa omousesobreoseucó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. 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.

.

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

.

CAPÍTULO7

"Umadiscussãoprolongadasignificaqueambasaspartesestãoerradas"--Voltaire

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

separarsuasclassesempacotes;preparararquivossimplesparadistribuição.

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

Porexemplo:podeserqueaminhaclassedeDatafuncionedeumcertojeito,eaclasseDatadeumcolega,deoutro jeito.Pode serquea classedeData deumabiblioteca funcione aindadeumaterceiramaneiradiferente.

Comopermitirque tudo isso realmente funcione?Comocontrolarquemquerusarqual classedeData?

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 eGregorianCalendar;todaselastrabalhamcomdatasdeformasdiferentes.

PACOTES-ORGANIZANDOSUASCLASSESEBIBLIOTECAS

7.1ORGANIZAÇÃO

.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

SeaclasseCliente estánopacotecontas, eladeverá estarnodiretório comomesmonome:contas . Se ela se localiza no pacote br.com.caelum.contas , significa que está no diretóriobr/com/caelum/contas.

AclasseCliente,queselocalizanesseúltimodiretóriomencionado,deveserescritadaseguinteforma:

packagebr.com.caelum.contas;

classCliente{//...}

Ficafácilnotarqueapalavrachavepackageindicaqualopacote/diretóriocontémestaclasse.

Umpacotepodeconternenhumoumaissubpacotese/ouclassesdentrodele.

Agoraéamelhorhoraderespirarmaistecnologia!

7.2DIRETÓRIOS

.

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.

As classesdopacotepadrãodebibliotecasnão seguemessanomenclatura,que foidadaparabibliotecasdeterceiros.

Para usar uma classe do mesmo pacote, basta fazer referência a ela como foi feito até agorasimplesmenteescrevendoopróprionomedaclasse.SequisermosqueaclasseBancofiquedentrodopacotebr.com.caelum.contas,eladeveserdeclaradaassim:

packagebr.com.caelum.contas;

classBanco{Stringnome;}

ParaaclasseClienteficarnomesmopacote,seguimosamesmafórmula:

packagebr.com.caelum.contas;

classCliente{Stringnome;Stringendereco;}

AnovidadechegaaotentarutilizaraclasseBanco(ouCliente)emumaoutraclassequeestejaforadessepacote,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

.

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

Mesmoassim,aotentarcompilaraclasseanterior,surgeumerroreclamandoqueaclasseBanconãoestávisível.

Acontecequeasclasses só sãovisíveisparaoutrasnomesmopacote e,parapermitirqueaclasseTesteDoBanco veja e acesse a classe Banco em outro pacote, precisamos alterar essa última etransformá-laempública:

packagebr.com.caelum.contas;

publicclassBanco{Stringnome;}

Apalavra chavepublic libera o acesso para classes de outros pacotes. Domesmo jeito que ocompilador 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 todoopacotepara identificar qualclassequeremosusar?Oexemploqueusamosficoubemcomplicadodeler:

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

Existe umamaneiramais simples de se referenciar a classe Banco: basta importá-la do pacotebr.com.caelum.contas:

packagebr.com.caelum.contas.main;

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

publicclassTesteDoBanco{

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

}

.

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

PACKAGE,IMPORT,CLASS

Émuito importantemanteraordem!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 umpacotenão implica emperdade performance em tempodeexecução,maspodetrazerproblemascomclassesdemesmonome!Alémdisso,importardeumemuméconsideradoboaprática,poisfacilitaaleituraparaoutrosprogramadores.UmaIDEcomooEclipsejávaifazerissoporvocê,assimcomoaorganizaçãoemdiretórios.

Osmodificadoresdeacessoexistentes emJava sãoquatro, e atéomomento jávimos três,mas sóexplicamosdois.

public -Todospodemacessaraquiloque fordefinidocomopublic.Classes, atributos,construtoresemétodospodemserpublic.

protected -Aquiloqueéprotected pode ser acessadopor todas as classesdomesmopacoteeportodasasclassesqueoestendam,mesmoqueessasnãoestejamnomesmopacote.Somenteatributos,construtoresemétodospodemserprotected.

padrão(semnenhummodificador) -Senenhummodificadorforutilizado, todasasclassesdomesmopacotetêmacessoaoatributo,construtor,métodoouclasse.

private-Aúnicaclassecapazdeacessarosatributos,construtoresemétodosprivadoséaprópria classe. Classes, como conhecemos, não podem ser private , mas atributos,construtoresemétodossim.

7.4ACESSOAOSATRIBUTOS,CONSTRUTORESEMÉTODOS

.

CLASSESPÚBLICAS

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

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

Classesaninhadaspodemserprotectedouprivate,masesseéumtópicoavançadoquenãoseráestudadonessemomento.

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

CasadoCódigo,ebookcompreçodeebook.

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

EditoraCasadoCódigocomlivrosdeumaformadiferente

7.5USANDOOECLIPSECOMPACOTES

.

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

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

.

NoEclipsenuncaprecisamosdeclararumimport,poiselesemprevaisugeririssoquandousarmosoCtrl+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émutilizeosquickfixesquandooEclipsereclamardosdiversosproblemasdecompilaçãoqueaparecerão.Épossívelfazeresse exercício inteiro semmodificar uma linha de 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 pacoteseguindoaconvençãodecódigodaSun,desdeobr,eoEclipsetratarádefazeraseparaçãodaspastascorretamente.Cuidado:paraessecurso,osnomesdospacotesprecisamserosseguintes:

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

7.6EXERCÍCIOS:PACOTES

.

br.com.caelum.contas.modelo:colocaraclasseConta

Antesdecorrigirqualquererrodecompilação,primeiromovatodasassuasclasses,semdeixarnenhumanopacotedefault.

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

3. Casoocódigonãocompileprontamente, reparequepelomenosalgummétodoquedeclaramosépackage-privatequando,naverdade,precisamosqueelesejapublic.Omesmovaleparaasclasses:algumasdelasprecisarãoserpúblicas.

Se houver algum erro de compilação, use o recurso de quick fix do Eclipse aqui: elemesmo vaisugerirqueomodificadordeacessodeveserpúblico.Paraisso,useoctrl+1emcadaumdoserros,escolhendooquickfixmaisadequadoparaseuproblema.

4. (Opcional)AbraaviewNavigatorparavercomoficouosarquivosnosistemadearquivosdoseusistemaoperacional.Paraisso,usectrl+3,comeceadigitarNavigatoreescolhaaopçãodeabriressaview..

.

CAPÍTULO8

"Perder tempo em aprender coisas que não interessam, priva-nos de descobrir coisas interessantes" --CarlosDrummonddeAndrade

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

criaroJARdoseuaplicativo;colocarumJARnobuildpathdoseuprojeto;lerumjavadoc;criarojavadocdoseuaplicativo.

Assimqueumprogramaficapronto,émeiocomplicadoenviardezenasoucentenasdeclassesparacadaclientequequerutilizá-lo.

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

OARQUIVO.JAR

Oarquivo jarouJavaARchive, possui umconjuntode classes (e arquivosde configurações)compactados, no estilo de um arquivo zip. O arquivo jar pode ser criado com qualquercompactadorzipdisponívelnomercado,inclusiveoprogramajarquevemjuntocomoJDK.

Paracriarumarquivojardonossoprogramadebanco,bastairaodiretórioondeestãocontidasasclasses eusaro comandoa seguirpara criaroarquivobanco.jar com todas as classesdospacotesbr.com.caelum.utilebr.com.caelum.banco:

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

Parausaressearquivobanco.jarpararodaroTesteDoBancobastarodarojavacomoarquivojarcomoargumento:

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

FERRAMENTAS:JAREJAVADOC

8.1ARQUIVOS,BIBLIOTECASEVERSÕES

.

Paraadicionarmaisarquivos.jar,quepodemserbibliotecas,aoprogramabastarodarojavadaseguintemaneira:

java-classpathbiblioteca1.jar;biblioteca2.jarNomeDaClasse

Vale lembrarqueopontoeví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.Basta verificaronomedabiblioteca (por exemplolog4j-1.2.13.jar)paradescobriraversãodela.

Então é possível rodar dois programas aomesmo tempo, cadaumutilizandouma versãodabibliotecaatravé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.

.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Nesteexemplo,vamosgeraroarquivoJARdonossoprojetoapartirdoEclipse:

CliquecomobotãodireitoemcimadonomedoseuprojetoeselecioneaopçãoExport.

Na telaExport (comomostraa figuraabaixo), selecioneaopção "JAR file" e aperteobotão

AprendasedivertindonaAluraStart!

8.2GERANDOOJARPELOECLIPSE

.

"Next".

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

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

.

Na tela abaixo,naopção "select theclassof theapplicationentrypoint", 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

NositedaOracle,vocêpode(edeve)baixaradocumentaçãodasbibliotecasdoJava,frequentementereferidacomo"javadoc"ouAPI(sendonaverdadeadocumentaçãodaAPI).

8.3JAVADOC

.

Nesta documentação, no quadro superior esquerdo, você encontra os pacotes e, no inferioresquerdo,estáalistagemdasclasseseinterfacesdorespectivopacote(oudetodos,casonenhumtenhasidoespecificado).Clicando-seemumaclasseou interface,oquadrodadireitapassaadetalhar 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 demenu, selecione omenuProject, depois a opção "Generate Javadoc...". (apenasdisponívelseestivernaperspectivaJava,masvocêpodeacessaromesmowizardpeloexportdoprojeto).

8.4GERANDOOJAVADOC

.

Emseguida,aparecerãoasopçõesparageraradocumentaçãodoseusistema,selecionetodasas classes do seu sistema e deixe as outras opções como estão. Não esqueça de marcar ocaminhodaopção"Destination",poiséláqueestarásuadocumentação.

.

Abraadocumentaçãoatravésdocaminhoquevocêmarcoueabraoarquivoindex.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){...

.

}

Vejacomoficou:

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

8.5EXERCÍCIOS:JAREJAVADOC

.

1. Gereumjardoseusistemacomoarquivodemanifesto.Execute-ocomjava-jar:

java-jarcaelum-banco-1.0.jar

SeoWindowsouoLinux foi configuradopara trabalhar coma extensão .jar, basta você dar umduplo clique no arquivo, que ele será "executado": o arquivo Manifest será lido para que eledescubraqualéaclassecommainqueoJavadeveprocessar.

2. GereoJavadocdoseusistema.Para isso,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ãotemumainterfacegráficadousuário.Sequisermosrodaronossosistematemosqueexecutá-lopeloterminalcomosvaloreshard-coded.Seriamaisinteressantequetivéssemosumainterfacemaisamigávelparaqueousuáriopudesseinteragircomonossosistema.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,depois selecionara abaLibraries e, finalmente, clicarnobotãoAddExternal Jars... .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.

VánomenuProject->Properties

8.6IMPORTANDOUMJAREXTERNO

8.7EXERCÍCIOS:IMPORTANDOUMJAR

.

SelecioneaopçãoJavaBuildPath

SelecioneaabaLibraries

CliquenobotãoAddExternalJars...

Selecioneoarquivofj11-lib-contas.jarlocalizadonapastadosarquivosdoscursos/11

CliquenobotãoOkparafecharajaneladeimportação

2. Para verificarmosque a importaçãodeu certo, vamos chamaruma classedabiblioteca importadaparaexibirumajaneladeboas-vindas.

CrieumaclasseTestaJarnopacotebr.com.caelum.contas.main.

Crietambémométodomain.

3. Dentrodométodocriado,vamos invocarométodomaindaclasseOlaMundo que existeno jarimportado.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.Useoatalhoctrl+shift+O.

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!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

AgoraquejáimportamosoJarquecontémainterfacegráfica,vamosdarumaolhadanaprimeirateladonossosistema:

Agoraéamelhorhoraderespirarmaistecnologia!

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

.

Nestatela,podemosperceberquetemosbotõesparaasaçõesdecriaçãodeconta,saqueedepósito,quedevemutilizaraimplementaçãoexistenteemnossaclasseConta.

Se quisermos visualizar a tela, podemos criar um main que chamará a classe TelaDeContasresponsávelpelasuaexibição:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

.

Aoexecutarmosaaplicaçãoocorreráumerro:

Masporqueesteerroocorreu?Acontecequeatelaprecisaconheceralguémquesaibaexecutarasaçõesdesaqueedepósitonaconta,queconsigabuscarosdadosdatelaparapopularaconta.Comonãotemosninguémquesaibafazeristoainda,ocorreuoerro.

VamosentãocriaraclasseManipuladorDeContasqueseráresponsávelporfazeresta"ponte"entreatelaeaclassedeConta:

packagebr.com.caelum.contas;

publicclassManipuladorDeContas{

}

Agora,aoexecutarmosaaplicação,veremosqueatelaaparececomsucesso:

.

Esetentarmosclicarnobotãodecriaçãodeconta?Tambémocorreumerro!

.

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ãoutilizemosesteparâmetro,precisamosrecebê-lo.

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

publicvoidcriaConta(Eventoevento){Contaconta=newConta();conta.setAgencia("1234");conta.setNumero(56789);conta.setTitular("Batman");}}

Se tentarmos executar a aplicação e clicarnobotãocria conta, vemosque agoranãoocorremaisnenhumerromasaomesmotempoosdadosdacontanãosãopopuladosnatela.Istoacontecepoisavariávelconta é apenas local, ou seja, ela só existe dentro dométodocriaConta. Além disso sequiséssemosdepositarumvalornaconta,emqualcontadepositaríamos?Elanãoévisívelparanenhum

.

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!

.

Só falta criarmos os métodos saca e deposita. Vamos começar implementando o métododeposita. Nele precisamos do valor digitado pelo usuário na tela e é pra isto que serve a classeEvento. Se quisermos buscar um valor do tipo double, podemos invocar o método doublepassandoonomedocampoquequeremosrecuperarcomoparâ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!

.

1. CrieaclasseManipuladorDeContas dentrodopacotebr.com.caelum.contas.Reparequeospacotes br.com.caelum.contas.main e br.com.caelum.contas.modelo são subpacotes dopacotebr.com.caelum.contas,portantoopacotebr.com.caelum.contasjáexiste.Paracriaraclassenestepacote,bastaselecioná-lonajaneladecriaçãodaclasse:

8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA

.

AclasseManipuladorDeContasfaráaligaçãodaContacomatela,porissoprecisaremosdeclararumatributodotipoConta.

2. CrieométodocriaContaquerecebecomoparâmetroumobjetodotipoEvento.Instancieumacontaparaoatributocontaecoloqueosvaloresdenumero,agenciaetitular.Algocomo:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setTitular("Batman");//façaomesmoparaosoutrosatributos}

3. Comacontainstanciada,agorapodemosimplementarasfuncionalidadesdesaqueedepósito.CrieométododepositaquerecebeumEvento,queéaclassequeretornaosdadosdatelanostiposqueprecisamos.Porexemplo,sequisermosovaloradepositarsabemosqueeleédotipodoubleequeonomedocamponatelaévalorentãopodemosfazer:

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}

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 pacotebr.com.caelum.contascomummain.NelavamoschamaromaindaclasseTelaDeContasquemostraráateladenossosistema.Nãoseesqueçadefazeroimportdestaclasse!

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

Rodeaaplicação,crieacontaetentefazerasoperaçõesdesaqueedepósito.Tudodevefuncionarnormalmente.

.

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;}}

//outrosmétodos

HERANÇA,REESCRITAEPOLIMORFISMO

9.1REPETINDOCÓDIGO?

.

}

PRECISAMOSMESMODEOUTRACLASSE?

PoderíamosterdeixadoaclasseFuncionariomaisgenérica,mantendonelasenhadeacesso,eonúmerodefuncionáriosgerenciados.Casoofuncionárionãofosseumgerente,deixaríamosestesatributosvazios.

Essaéumapossibilidade,porémpodemoscomeçara termuitoatributosopcionais,eaclasseficariaestranha.Eemrelaçãoaosmétodos?AclasseGerentetemométodoautentica,quenã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íamosdefazercomqueoGerente tivesse tudo que um Funcionario tem, gostaríamos que ela fosse uma extensã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 todomomento que criarmos um objeto do tipo Gerente, este objeto possuirá também osatributosdefinidosnaclasseFuncionario,poisumGerenteéumFuncionario:

.

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ãoconsegue 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,poisdessamaneiraqualquerumpoderiaalterarosatributosdosobjetosdestetipo.Existeumoutromodificadordeacesso,oprotected,queficaentreoprivateeopublic.Umatributoprotected só pode ser acessado (visível) pela própria classe, por suas subclasses, e pelasclassesqueseencontramnomesmopacote.

publicclassFuncionario{protectedStringnome;protectedStringcpf;protecteddoublesalario;//métodosdevemviraqui}

.

SEMPREUSARPROTECTED?

Entãoporqueusarprivate?Depoisdeumtempoprogramandoorientadoaobjetos,vocêvaicomeçarasentirquenemsempreéumaboaideiadeixarqueaclassefilhaacesseosatributosdaclasse mãe, pois isso quebra um pouco a ideia de que só aquela classe deveria manipular seusatributos.Essaéumadiscussãoumpoucomaisavançada.

Alémdisso,nãosóas subclasses,mas tambémasoutrasclassesqueseencontramnomesmopacote, podem acessar os atributos protected. Veja outras alternativas ao protected noexercíciodediscussãoemsaladeaulajuntamentecomoinstrutor.

Da mesma maneira, podemos ter uma classe Diretor que estenda Gerente e a classePresidentepodeestenderdiretamentedeFuncionario.

Fique claro que essa é uma decisão de negócio. Se Diretor vai estender de Gerente ou não, vaidependerse,paravocê,DiretoréumGerente.

Umaclassepodetervárias filhas,maspodeterapenasumamãe,éachamadaherançasimplesdojava.

.

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

CasadoCódigo,ebookcompreçodeebook.

Todo fim de ano, os funcionários do nosso banco recebem uma bonificação. Os funcioná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());

Oresultadoaquiserá500.Nãoqueremosessaresposta,poisogerentedeveriater750debônusnessecaso.Paraconsertarisso,umadasopçõesseriacriarumnovométodonaclasseGerente,chamado,porexemplo, getBonificacaoDoGerente. O problema é que teríamos dois métodos em Gerente ,confundindobastantequemforusaressaclasse,alémdequecadaumdaumarespostadiferente.

NoJava,quandoherdamosummétodo,podemosalterarseucomportamento.Podemosreescrever(reescrever,sobrescrever,override)estemétodo:

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

EditoraCasadoCódigocomlivrosdeumaformadiferente

9.2REESCRITADEMÉTODO

.

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ódigoquedeterminadormétodoéareescritadeummétododa sua classemãe. Fazemos isso colocando @Override em cima do método. Isso é chamadoanotação.Existemdiversasanotaçõesecadaumavaiterumefeitodiferentesobreseucódigo.

@OverridepublicdoublegetBonificacao(){returnthis.salario*0.15;}

Repare que, por questões de compatibilidade, isso não é obrigatório. Mas caso ummétodoestejaanotadocom@Override,elenecessariamenteprecisaestarreescrevendoummétododaclassemãe.

Depoisde reescrito,nãopodemosmais chamarométodoantigoque foraherdadoda classemãe:realmente alteramos o seu comportamento. Mas podemos invocá-lo no caso de estarmos dentro daclasse.

Imagine que para calcular a bonificação de umGerente devemos fazer igual ao cálculo de umFuncionarioporémadicionandoR$1000.Poderíamosfazerassim:

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnthis.salario*0.10+1000;}//...}

Aquiteríamosumproblema:odiaqueogetBonificacaodoFuncionariomudar,precisaremos

9.3INVOCANDOOMÉTODOREESCRITO

.

mudar o método do Gerente para acompanhar a nova bonificação. Para evitar isso, ogetBonificacaodoGerentepodechamarodoFuncionarioutilizandoapalavrachavesuper.

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnsuper.getBonificacao()+1000;}//...}

Essa invocação vai procurar o método com o nome getBonificacao de uma super classe deGerente.NocasoelelogovaiencontraressemétodoemFuncionario.

Essaéumapráticacomum,poismuitoscasosométodoreescritogeralmentefaz"algoamais"queométododaclassemãe.Chamarounãoométododecimaéumadecisãosuaedependedoseuproblema.Algumasvezesnãofazsentidoinvocarométodoquereescrevemos.

OqueguardaumavariáveldotipoFuncionario?UmareferênciaparaumFuncionario,nuncaoobjetoemsi.

Naherança,vimosquetodoGerenteéumFuncionario,poiséumaextensãodeste.Podemosnos referir a um Gerente como sendo um Funcionario . Se alguém precisa falar com umFuncionariodobanco,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).

Atéaquitudobem,maseseeutentar:

9.4POLIMORFISMO

.

funcionario.getBonificacao();

Qualéoretornodessemétodo?500ou750?NoJava,ainvocaçãodemétodosemprevaiserdecididaemtempodeexecução.OJavavaiprocuraroobjetonamemóriae,aísim,decidirqualmétododeveserchamado, sempre relacionando com sua classe de verdade, e não com a que estamos usando parareferenciá-lo.ApesardeestarmosnosreferenciandoaesseGerentecomosendoumFuncionario,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étodoquerecebeumFuncionariocomoargumento. Pense comonuma porta na agência bancária como 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éumGerente,oseumétodoreescritoseráinvocado.Reafirmando:nãoimportacomonosreferenciamosaumobjeto,ométodoqueseráinvocadoésempreoqueédele.

No dia em que criarmos uma classe Secretaria, por exemplo, que é filha de Funcionario,precisaremos mudar a classe de ControleDeBonificacoes ? Não. Basta a classe Secretariareescrever os métodos que lhe parecerem necessários. É exatamente esse o poder do polimorfismo,

.

juntamentecomareescritademétodo:diminuiroacoplamentoentreasclasses,paraevitarquenovoscódigosresultememmodificaçõeseminúmeroslugares.

ReparequequemcriouControleDeBonificacoespodenunca ter imaginadoacriaçãodaclasseSecretaria ouEngenheiro. Contudo, não será necessário reimplementar esse controle em cadanovaclasse:reaproveitamosaquelecódigo.

HERANÇAVERSUSACOPLAMENTO

Notequeousodeherançaaumentaoacoplamentoentreasclasses,istoé,oquantoumaclassedependedeoutra.Arelaçãoentreclassemãeefilhaémuitoforteeissoacabafazendocomqueoprogramadordas classes filhas tenhaqueconhecera implementaçãodaclassemãeevice-versa -ficadifícilfazerumamudançapontualnosistema.

Por exemplo, imagine se tivermos quemudar algo na nossa classeFuncionario, mas nãoquiséssemosquetodososfuncionáriossofressemamesmamudança.Precisaríamospassarporcadauma das filhas de Funcionario verificando se ela se comporta como deveria ou se devemossobrescreverotalmétodomodificado.

Esse éumproblemadaherança, enãodopolimorfismo,que resolveremosmais tardecomaajudadeInterfaces.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Imaginequevamosmodelarumsistemaparaafaculdadequecontroleasdespesascomfuncionárioseprofessores.Nossofuncionárioficaassim:

JáconheceoscursosonlineAlura?

9.5UMOUTROEXEMPLO

.

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,ogetInfotambé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íamosdeacessar 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 paraprofessor,quantoparafuncionáriocomum.

Umcertodia,muitodepoisdeterminaressaclassederelatório,resolvemosaumentarnossosistema,e colocar uma classe nova, que representa o Reitor . Como ele também é umEmpregadoDaFaculdade, seráquevamosprecisaralteraralgonanossaclassedeRelatorio?Não.Essa é a ideia!Quem programou a classe GeradorDeRelatorio nunca imaginou que existiria umaclasseReitore,mesmoassim,osistemafunciona.

publicclassReitorextendsEmpregadoDaFaculdade{//informaçõesextraspublicStringgetInfo(){

.

returnsuper.getInfo()+"eeleéumreitor";}//nãosobrescrevemosogetGastos!!!}

SenãohouvesseherançaemJava,comovocêpoderiareaproveitarocódigodeoutraclasse?

Umadiscussãomuitoatualésobreoabusonousodaherança.Algumaspessoasusamherançaapenasparareaproveitarocódigo,quandopoderiamterfeitoumacomposição.Procuresobreherançaversuscomposição.

Mesmo depois de reescrever ummétodo da classemãe, a classe filha ainda pode acessar ométodoantigo.Istoéfeitoatravésdapalavrachavesuper.método().Algoparecidoocorreentreosconstrutoresdasclasses,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{

publicstaticvoidmain(String[]args){SistemaBancario.mostraTela(false);//TelaDeContas.main(args);}}

9.6UMPOUCOMAIS...

9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO

.

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: sequeremos uma conta corrente ou uma conta poupança. Vamos então criar as classescorrespondentes.

CrieaclasseContaCorrentenopacotebr.com.caelum.contas.modelo e faça comque elasejafilhadaclasseContaCrieaclasseContaPoupancanopacotebr.com.caelum.contas.modelo e faça comque elasejafilhadaclasseConta

3. Precisamos pegar os dados da tela para conseguirmos criar a conta correspondente. NoManipuladorDeContas vamos alterar ométodocriaConta. Atualmente, apenas criamosumanovacontacomosdadosdiretonocódigo.Vamosfazercomqueagoraosdadossejamrecuperados

.

datelaparacolocarmosnanovaconta,faremosissoutilizandooobjetoevento:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setAgencia(evento.getString("agencia"));this.conta.setNumero(evento.getInt("numero"));this.conta.setTitular(evento.getString("titular"));}

Masprecisamosdizerqual tipode contaquequeremos criar!Devemos então recuperaro tipodacontaescolhidoecriaracontacorrespondente.Paraisso,aoinvésdecriarumobjetodotipo'Conta',vamosusarométodogetSelecionadoNoRadiodoobjetoeventoparapegarotipo,fazerumifparaverificaresse tipoe sódepoiscriaroobjetodo tipocorrespondente.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 tiposde contas,nossa listanãoconsegueexibiro tipodecadacontanalistadatelainicial.Pararesolverisso,podemoscriarummétodogetTipoemcadaumadenossascontasfazendocomqueacontacorrentedevolvaastring"ContaCorrente"eacontapoupançadevolvaastring"ContaPoupança":

publicclassContaCorrenteextendsConta{publicStringgetTipo(){return"ContaCorrente";}}

publicclassContaPoupancaextendsConta{publicStringgetTipo(){return"ContaPoupança";}}

5. AltereosmétodossacaedepositaparabuscaremocampovalorOperacaoaoinvésdeapenasvalornaclasseManipuladorDeContas.

6. Vamosmudarocomportamentodaoperaçãodesaquedeacordocomotipodecontaqueestiversendo utilizada.Na classeManipuladorDeContas vamos alterar ométodo saca para tirar 10centavosdecadasaqueemumacontacorrente:

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ãoexistenaclasseContaapesardeexistirnasclassesfilhas.Comoestamostratandotodasascontasgenericamente,sóconseguimosacessarosmétodosdaclassemãe.Vamosentãocolocá-lonaclasseConta:

publicclassConta{publicStringgetTipo(){return"Conta";}}

7. Agoraocódigocompilamastemosumoutroproblema.AlógicadonossosaquevazouparaaclasseManipuladorDeContas.Sealgumdiaprecisarmosalterarovalorda taxanosaque, teríamosquemudar em todos os lugares onde fazemos uso do método saca . Esta lógica deveria estarencapsuladadentrodométodosacadecadaconta.VamosentãosobrescreverométododentrodaclasseContaCorrente:

publicclassContaCorrenteextendsConta{@Overridepublicvoidsaca(doublevalor){this.saldo-=(valor+0.10);}

//restantedaclasse}

Repare que, para acessar o atributo saldo herdado da classeConta,você vai precisarmudar omodificadordevisibilidadedesaldoparaprotected.

Agora que a lógica está encapsulada, podemos corrigir o método saca da classeManipuladorDeContas:

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 é apresentadocorretamentenalistadecontasdatelainicial.

Agora,cliquenacontacorrenteapresentadanalistaparaabrirateladedetalhesdecontas.Testeasoperaçõ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 implementarométodotransfere na classeManipuladorDeContas parafazeroví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útildopolimorfismo.Porémexisteumautilidadededeclararmosumavariáveldeumtipomenosespecíficodoqueoobjetorealmenteé,comofazemosnaclasseManipuladorDeContas.

Éextremamenteimportanteperceberquenãoimportacomonosreferimosaumobjeto,ométodoque será invocado é sempreomesmo!A JVMvaidescobrir em tempodeexecuçãoqualdeve serinvocado,dependendodequetipoéaqueleobjeto,nãoimportandocomonosreferimosaele.

11. (Opcional)AnossaclasseContadevolveapalavra "Conta"nométodogetTipo.Use a palavrachavesupernosmétodosgetTiporeescritosnasclassesfilhas,paranãoterdereescreveapalavra"Conta"aodevolverostipos"ContaCorrente"e"ContaPoupança".

12. (Opcional) Se vocêprecisasse criaruma classeContaInvestimento, e seumétodosaca fossecomplicadíssimo,vocêprecisariaalteraraclasseManipuladorDeContas?

.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

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?

SaberinglêsémuitoimportanteemTI

9.8 DISCUSSÕES EM AULA: ALTERNATIVAS AO ATRIBUTOPROTECTED

.

CAPÍTULO10

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

Aotérminodessecapítulo,vocêserácapazdeutilizarclassesabstratas,quandonecessário.

Nestecapítulo,aconselhamosquevocêpasseausaroEclipse.VocêjátemconhecimentosuficientedoserrosdecompilaçãodojavaceagorapodeaprenderasfacilidadesqueoEclipsetetrazaoajudarvocênocódigocomoschamadosquickfixesequickassists.

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étodo registra recebe qualquer referência do tipo Funcionario, isto é, podem serobjetosdo tipoFuncionario e qualquerde seus subtipos:Gerente,Diretor e, eventualmente,

CLASSESABSTRATAS

10.1REPETINDOMAISCÓDIGO?

.

alguma nova subclasse que venha ser escrita, sem prévio conhecimento do autor daControleDeBonificacao.

EstamosutilizandoaquiaclasseFuncionarioparaopolimorfismo.Senãofosseela,teríamosumgrande prejuízo: precisaríamos criar um método registra para receber cada um dos tipos deFuncionario,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? Essa pergunta é diferente de saber se fazsentidoterumobjetodotipoFuncionario:nessecaso,fazsimeémuitoútil.

ReferenciandoFuncionariotemosopolimorfismodereferência,jáquepodemosreceberqualquerobjetoquesejaumFuncionario.Porém,darnewemFuncionariopodenãofazersentido,istoé,não queremos receber umobjeto do tipoFuncionario,mas sim que aquela referência seja ou umGerente,ouumDiretor,etc.AlgomaisconcretoqueumFuncionario.

ControleDeBonificacoescdb=newControleDeBonificacoes();Funcionariof=newFuncionario();cdb.adiciona(f);//fazsentido?

Vejamosumoutrocasoemquenãofazsentidoterumobjetodaqueletipo,apesardaclasseexistir:imagineaclassePessoa e duas filhas,PessoaFisica ePessoaJuridica.Quandopuxamosumrelatóriodenossosclientes(umaarraydePessoaporexemplo),queremosquecadaumdelessejaouumaPessoaFisica,ouumaPessoaJuridica.A classePessoa, nesse caso, estaria sendousadaapenasparaganharopolimorfismoeherdaralgumascoisas:nãofazsentidopermitirinstanciá-la.

Pararesolveressesproblemas,temosasclassesabstratas.

.

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

CasadoCódigo,ebookcompreçodeebook.

Oque,exatamente,vemaseranossaclasseFuncionario?NossaempresatemapenasDiretores,Gerentes, Secretárias, etc. Ela é uma classe que apenas idealiza um tipo, define apenas umrascunho.

Paraonossosistema,éinadmissívelqueumobjetosejaapenasdotipoFuncionario(podeexistirumsistemaemquefaçasentidoterobjetosdotipoFuncionarioouapenasPessoa,mas,nonossocaso,não).

Usamosapalavrachaveabstractparaimpedirqueelapossaserinstanciada.Esseéoefeitodiretodeseusaromodificadorabstractnadeclaraçãodeumaclasse:

publicabstractclassFuncionario{

protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*1.2;}

//outrosatributosemétodoscomunsatodosFuncionarios

}

E,nomeiodeumcódigo:

Funcionariof=newFuncionario();//nãocompila!!!

EditoraCasadoCódigocomlivrosdeumaformadiferente

10.2CLASSEABSTRATA

.

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;}}

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ãodetransformarFuncionarioemumaclasseabstratadependeudonossodomínio.Podeserque,emumsistemacomclassessimilares,façasentidoqueumaclasseanálogaaFuncionariosejaconcreta.

SeométodogetBonificacaonãofossereescrito,eleseriaherdadodaclassemãe,fazendocomquedevolvesseosaláriomais20%.

Levando em consideração que cada funcionário em nosso sistema tem uma regra totalmentediferenteparaserbonificado,fazalgumsentidoteressemétodonaclasseFuncionario?Seráqueexisteumabonificaçãopadrãopara todo tipodeFuncionario?Parecequenão, cada classe filha teráum

10.3MÉTODOSABSTRATOS

.

método diferente de bonificação pois, de acordo com nosso sistema, não existe uma regra geral:queremos que cada pessoa que escreve a classe de um Funcionario diferente (subclasses deFuncionario)reescrevaométodogetBonificacaodeacordocomassuasregras.

Poderíamos,então, jogarforaessemétododaclasseFuncionario?Oproblemaéque, seelenãoexistisse, não poderíamos chamar o método apenas com uma referência a um Funcionario, poisningué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.

ExisteumrecursoemJavaque,emumaclasseabstrata,podemosescreverquedeterminadométodoserásempreescritopelasclassesfilhas.Istoé,ummétodoabstrato.

Ele indicaque todasasclasses filhas (concretas, istoé,quenão foremabstratas)devemreescreveressemétodoounãocompilarão.Écomosevocêherdassearesponsabilidadedeteraquelemétodo.

COMODECLARARUMMÉTODOABSTRATO

Àsvezes,nãoficaclarocomodeclararummétodoabstrato.

Bastaescreverapalavrachaveabstractnaassinaturadomesmoecolocarumpontoevírgulaemvezdeabreefechachaves!

publicabstractclassFuncionario{

publicabstractdoublegetBonificacao();

//outrosatributosemétodos

}

Reparequenãocolocamosocorpodométodoeusamosapalavrachaveabstractparadefiniromesmo. Por que não colocar corpo algum?Porque essemétodo nunca vai ser chamado, sempre quealguémchamarométodogetBonificacao,vaicairemumadassuasfilhas,querealmenteescreveramomé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,comcerteza suas subclasses têmessemétodo,oquegaranteque essainvocação demétodo não vai falhar. Basta pensar que uma referência do tipoFuncionario nuncaapontaparaumobjetoquenão temométodogetBonificacao, poisnão épossível instanciarumaclasse abstrata, apenas as concretas. Ummétodo abstrato obriga a classe em que ele se encontra serabstrata,oquegaranteacoerênciadocódigoacimacompilar.

E se, no nosso exemplo de empresa, tivéssemos o seguinte diagrama de classes com os seguintesmétodos:

Ouseja,tenhoaclasseabstrataFuncionario,comométodoabstratogetBonificacao;asclassesGerenteePresidenteestendendoFuncionarioeimplementandoométodogetBonificacao;e,porfim,aclasseDiretor,queestendeGerente,masnãoimplementaométodogetBonificacao.

Essasclassesvãocompilar?Vãorodar?

Arespostaésim.E,alémdetudo,farãoexatamenteoquenósqueremos,pois,quandoGerenteePresidentepossuemosmétodosperfeitamenteimplementados,aclasseDiretor,quenãopossuiométodoimplementado,vaiusaraimplementaçãoherdadadeGerente.

10.4AUMENTANDOOEXEMPLO

.

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?Vairodar?

Denovo,arespostaésim,poisSecretariaéumaclasseabstratae,porisso,oJavatemcertezadeque 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ãopossuemnenhum segredono aprendizado,mas quem está aprendendoorientaçãoaobjetospodeterumaenormedificuldadeparasaberquandoutilizá-las,oqueémuitonormal.

Estudaremosopacotejava.io,queusabastantesclassesabstratas,sendoumexemplorealdeusodesserecurso,quevaimelhoraroentendimentodelas.(classeInputStreamesuasfilhas)

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

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ê?Quemétodosseriaminteressantescandidatosaseremabstratos?

TransformeaclasseContaemabstrata:

publicabstractclassConta{//...}

2. ComoaclasseContaagoraéabstrata,nãoconseguimosdarnewnelamais.SenãopodemosdarnewemConta,qualéautilidadedeterummétodoquerecebeumareferênciaaContacomoargumento?Aliás,possoterisso?

3. Apenasparaentendermelhoroabstract,comenteométodogetTipo()daContaPoupanca,dessaformaeleherdaráométododiretamentedeConta.

TransformeométodogetTipo()daclasseContaemabstrato.Repareque,aocolocarapalavrachaveabstract ao ladodométodo,oEclipse rapidamentevai sugerirquevocêdeve removerocorpo(body)dométodocomumquickfix.

SuaclasseContadeveficarparecidacom:

JáconheceoscursosonlineAlura?

10.5PARASABERMAIS...

10.6EXERCÍCIOS:CLASSESABSTRATAS

.

publicabstractclassConta{//atributosemétodosquejáexistiam

publicabstractStringgetTipo();}

QualéoproblemacomaclasseContaPoupanca?

4. DescomenteométodogetTipo na classeContaPoupanca, e se necessário altere-o para que aclassepossacompilarnormalmente.

5. (opcional) Existe outramaneira de a classe ContaPoupanca compilar se você não reescrever ométodoabstrato?

6. (opcional)PraqueterométodogetTiponaclasseContaseelenãofaznada?OqueacontecesesimplesmenteapagarmosessemétododaclasseContaedeixarmosométodogetTiponasfilhas?

7. (opcional) Posso chamar ummé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();

.

CAPÍTULO11

"Umaimagemvalemilpalavras.Umainterfacevalemilimagens."--BenShneiderman

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

dizeroqueéumainterfaceeasdiferençasentreherançaeimplementação;escreverumainterfaceemJava;utilizá-lascomoumpoderosorecursoparadiminuiracoplamentoentreasclasses.

Imagine que umSistemadeControle doBanco pode ser acessado, alémde pelosGerentes, pelosDiretoresdoBanco.Então,teríamosumaclasseDiretor:

publicclassDiretorextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro}

}

EaclasseGerente:

publicclassGerenteextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro//nocasodogerenteverificatambémseodepartamentodele//temacesso}

}

INTERFACES

11.1AUMENTANDONOSSOEXEMPLO

.

ReparequeométododeautenticaçãodecadatipodeFuncionariopodevariarmuito.Masvamosaosproblemas.Considere oSistemaInterno e seu controle: precisamos receber umDiretor ouGerentecomoargumento,verificarseeleseautenticaecolocá-lodentrodosistema.

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){//invocarométodoautentica?//nãoda!NemtodoFuncionariotem}}

OSistemaInternoaceitaqualquertipodeFuncionario,tendoeleacessoaosistemaounão,masnote que nem todo Funcionario possui ométodo autentica. Isso nos impede de chamar essemétodo com uma referência apenas aFuncionario (haveria um erro de compilação).O que fazerentão?

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){funcionario.autentica(...);//nãocompila}}

UmapossibilidadeécriardoismétodosloginnoSistemaInterno:umparareceberDiretoreoutroparareceberGerente.Jávimosqueessanãoéumaboaescolha.Porquê?

publicclassSistemaInterno{

//designproblemáticopublicvoidlogin(Diretorfuncionario){funcionario.autentica(...);}

//designproblemáticopublicvoidlogin(Gerentefuncionario){funcionario.autentica(...);}

}

.

Cada vez que criarmos uma nova classe de Funcionario que é autenticável, precisaríamosadicionarumnovomé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 oSistemaInternoreceberiareferênciasdessetipo,comoaseguir:

publicclassSistemaInterno{

publicvoidlogin(FuncionarioAutenticavelfa){

intsenha=//pegasenhadeumlugar,oudeumscannerdepolegar

//aquieupossochamaroautentica!//PoistodoFuncionarioAutenticaveltembooleanok=fa.autentica(senha);

}}

.

Repare que FuncionarioAutenticavel é uma forte candidata a classe abstrata. Mais ainda, ométodoautenticapoderiaserummétodoabstrato.

O uso de herança resolve esse caso,mas vamos a uma outra situação um poucomais 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, por exemplo, fazerClienteextendsFuncionarioAutenticavel. Realmente, resolve oproblema,mastrarádiversosoutros.ClientedefinitivamentenãoéFuncionarioAutenticavel.Sevocê fizer isso,oCliente terá, por exemplo, ummétodogetBonificacao, umatributo salario eoutrosmembrosquenãofazemomenorsentidoparaestaclasse!Nãofaçaherançaquandoarelaçãonãoéestritamente"éum".

.

Como resolver essa situação? Note que conhecer a sintaxe da linguagem não é o suficiente,precisamosestruturar/desenharbemanossaestruturadeclasses.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

O que precisamos para resolver nosso problema? Arranjar uma forma de poder referenciar

SaberinglêsémuitoimportanteemTI

11.2INTERFACES

.

Diretor,GerenteeClientedeumamesmamaneira,istoé,acharumfatorcomum.

Seexistisseuma formanaqual essas classesgarantissemaexistênciadeumdeterminadométodo,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

Quem quiser, pode "assinar" esse contrato, sendo assim obrigado a explicar como será feita essaautenticação.Avantageméque,seumGerenteassinaressecontrato,podemosnosreferenciaraumGerentecomoumAutenticavel.

PodemoscriaressecontratoemJava!

publicinterfaceAutenticavel{

booleanautentica(intsenha);

}

Chama-seinterfacepoiséamaneirapelaqualpoderemosconversarcomumAutenticavel.Interfaceéamaneiraatravésdaqualconversamoscomumobjeto.

Lemosainterfacedaseguintemaneira:"quemdesejarserautenticávelprecisasaberautenticardadoum inteiro e retornando um booleano". Ela é um contrato onde quem assina se responsabiliza porimplementaressesmé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étodosdeuma interfacesãopúblicoseabstratos, sempre).Paraimplementarusamosapalavrachaveimplementsnaclasse:

publicclassGerenteextendsFuncionarioimplementsAutenticavel{

privateintsenha;

.

//outrosatributosemétodos

publicbooleanautentica(intsenha){if(this.senha!=senha){returnfalse;}//podefazeroutraspossíveisverificações,comosaberseesse//departamentodogerentetemacessoaoSistema

returntrue;}

}

Oimplementspodeserlidodaseguintemaneira:"AclasseGerentesecomprometeasertratadacomoAutenticavel,sendoobrigadaaterosmétodosnecessários,definidosnestecontrato".

Apartirdeagora,podemostratarumGerentecomosendoumAutenticavel.Ganhamosmaispolimorfismo!TemosmaisumaformadereferenciaraumGerente.QuandocrioumavariáveldotipoAutenticavel, 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.

.

}

}

Pronto!EjápodemospassarqualquerAutenticavelparaoSistemaInterno.EntãoprecisamosfazercomqueoDiretortambémimplementeessainterface.

publicclassDiretorextendsFuncionarioimplementsAutenticavel{

//métodoseatributos,alémdeobrigatoriamenteteroautentica

}

PodemospassarumDiretor.Nodiaemquetivermosmaisumfuncionáriocomacessoaosistema,bastaqueeleimplementeessainterface,paraseencaixarnosistema.

QualquerAutenticavelpassadoparaoSistemaInternoestábomparanós.Reparequepoucoimporta quem o objeto referenciado realmente é, pois ele tem um método autentica que é onecessário para nosso SistemaInterno funcionar corretamente. Aliás, qualquer outra classe quefuturamenteimplementeessainterfacepoderá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}

}

.

NãofazdiferençaseéumDiretor,Gerente,Cliente ouqualquer classe que venhapor aí.Basta seguir o contrato! Mais ainda, cada Autenticavel pode se autenticar de uma maneiracompletamentediferentedeoutro.

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ãoprecisamnecessariamente reescrevê-lo.Veremos que isso acontece, por exemplo, comométodoList.sort,duranteocapítulodecoleções.Éumtruquemuitoutilizadoparapoderevoluirumainterfacesemquebrarcompatibilidadecomasimplementaçõesanteriores.

Interfaces representamuma barreira no aprendizado do Java: parece que estamos escrevendo umcódigoquenão servepranada, jáque teremosessa linha (a assinaturadométodo) escritanasnossasclassesimplementadoras.Essaéumamaneiraerradadesepensar.Oobjetivodousodeumainterfaceédeixarseucódigomaisflexívelepossibilitaramudançadeimplementaçãosemmaiorestraumas.Nãoéapenasumcódigodeprototipação,umcabeçalho!

Os mais 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

.

Veremosousodeinterfacesnocapítulodecoleções,oquemelhoraoentendimentodoassunto.OexemplodainterfaceComparabletambémémuitoesclarecedor,ondeenxergamosoreaproveitamentodecódigoatravésdasinterfaces,alémdoencapsulamento.ParaométodoCollections.sort(),poucoimporta quem vai ser passado como argumento. Para ele, basta que a coleção seja de objetoscomparáveis.ElepodeordenarElefante,ConexaoouContaCorrente, desdeque implementemComparable.

Comofazercomquetodasaschamadasparabancosdedadosdiferentesrespeitemamesmaregra?Usandointerfaces!

Imagine uma interfaceConexao contendo todos os métodos necessários para a comunicação etroca de dados com um banco de dados. Cada banco de dados fica encarregado de criar a suaimplementaçãoparaessainterface.

QuemforusarumaConexaonãoprecisaseimportarcomqualobjetoexatamenteestátrabalhando,jáqueelevai cumpriropapelque todaConexao deve ter.Não importa se é uma conexão comumOracleouMySQL.

Apesar do java.sql.Connection não trabalhar bem assim, a ideia é muito similar, porém asconexõesvêmdeumafactorychamadaDriverManager.

Conexãoabancodedadosestáforadoescopodessetreinamento,maséumdosprimeirostópicosabordadosnocursoFJ-21,juntamentecomDAO.

11.4EXEMPLOINTERESSANTE:CONEXÕESCOMOBANCODEDADOS

.

UMPOUCOMAIS...

Possosubstituirtodaminhaherançaporinterfaces?Qualéavantagemeadesvantagem?

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

1. Nossobancoprecisatributardinheirodealgunsbensquenossosclientespossuem.Paraissovamoscriarumainterfacenopacotebr.com.caelum.contas.modelodonossoprojetofj11-contasjáexistente:

publicinterfaceTributavel{publicdoublegetValorImposto();publicStringgetTitular();publicStringgetTipo();}

Lemosessainterfacedaseguintemaneira:"todosquequiseremsertributávelprecisamsaberretornarovalordoimposto,devolvendoumdouble".

Algunsbenssãotributáveiseoutrosnão,ContaPoupancanãoétributável,jáparaContaCorrentevocêprecisapagar1%dacontaeoSeguroDeVidatemumataxafixade42reaismais2%dovalordoseguro.

AproveiteoEclipse!QuandovocêescreverimplementsTributavelnaclasseContaCorrente,oquickfixdoEclipsevaisugerirquevocêreescrevaométodo;escolhaessaopçãoe,depois,preenchaocorpodométodoadequadamente:

AprendasedivertindonaAluraStart!

11.5EXERCÍCIOS:INTERFACES

.

publicclassContaCorrenteextendsContaimplementsTributavel{

//outrosatributosemétodos

publicdoublegetValorImposto(){returnthis.getSaldo()*0.01;}}

CrieaclasseSeguroDeVida,aproveitandonovamentedoEclipse,paraobter:

publicclassSeguroDeVidaimplementsTributavel{privatedoublevalor;privateStringtitular;privateintnumeroApolice;

publicdoublegetValorImposto(){return42+this.valor*0.02;}

//gettersesettersparaosatributos}

2. Vamos criar a classeManipuladorDeSeguroDeVida dentro do pacote br.com.caelum.contaspara vincular a classeSeguroDeVida com a tela de criação de seguros. Esta classe deve ter umatributodotipoSeguroDeVida.

Crie também o método criaSeguro que deve receber um parâmetro do tipo Evento paraconseguirobterosdadosda 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.Osegurocadastradodeveaparecernatabeladesegurosdevida.

4. Queremosagorasaberqualovalortotaldosimpostosdetodosostributáveis.VamosentãocriaraclasseManipuladorDeTributaveis dentrodopacotebr.com.caelum.contas.Crie tambémomé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.Observequeagoraque temos o seguro de vida funcionando, a tela de relatório já consegue imprimir o valor dosimpostosindividuaisdecadatipodeTributavel.

6. NométodocalculaImpostosprecisamosbuscarosvaloresdeimpostosdecadaTributavel esomá-los. Para saber a quantidade de tributáveis, a classe Evento possui ummétodo chamadogetTamanhoDaListaquedevereceberonomeda listadesejada,nocaso"listaTributaveis".Existetambé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étodogetSaldo,porexemplo,poisvocênãotemagarantiadequeoTributavelquevaiserpassadocomo argumento tem esse método. A única certeza que você tem é de que esse objeto tem osmétodosdeclaradosnainterfaceTributavel.

Éinteressanteenxergarqueasinterfaces(comoaqui,nocaso,Tributavel)costumamligarclassesmuito distintas, unindo-as por uma característica que elas tem em comum. No nosso exemplo,

.

SeguroDeVidaeContaCorrentesãoentidadescompletamentedistintas,porémambaspossuemacaracterísticadeseremtributáveis.

SeamanhãogovernocomeçaratributaratémesmoPlanoDeCapitalizacao,bastaqueessaclasseimplemente a interface Tributavel! Repare no grau de desacoplamento que temos: a classeGerenciadorDeImpostoDeRendanemimaginaquevaitrabalharcomoPlanoDeCapitalizacao.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: caso você faça esse exercício, faça isso num projeto à parte conta-interface já queusaremosaContacomoclasseemexercíciosfuturos.

1. (Opcional)TransformeaclasseContaemumainterface.

publicinterfaceConta{publicdoublegetSaldo();publicvoiddeposita(doublevalor);publicvoidsaca(doublevalor);publicvoidatualiza(doubletaxaSelic);}

AdapteContaCorrenteeContaPoupancaparaessamodificação:

publicclassContaCorrenteimplementsConta{//...}

publicclassContaPoupancaimplementsConta{//...

11.6EXERCÍCIOSAVANÇADOSOPCIONAIS

.

}

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:

Ratherthansubclassing,justusepureinterfaces.It'snotsomuchthatclassinheritanceisparticularlybad.Itjusthasproblems.

(Tradução livre: "Em vez de fazer subclasses, use simplesmente interfaces. Não é que a herança declassessejaparticularmenteruim.Elasótemproblemas.")

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/

11.7DISCUSSÃO:FAVOREÇACOMPOSIÇÃOEMRELAÇÃOÀHERANÇA

.

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

.

CAPÍTULO12

"Quempensapouco,erramuito"--LeonardodaVinci

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

controlarerrosetomardecisõesbaseadasnosmesmos;criarnovostiposdeerrosparamelhorarotratamentodelesemsuaaplicaçãooubiblioteca;assegurarqueummétodofuncionoucomodizemseu"contrato".

Voltando às Contas que criamos no capítulo 6, o que aconteceria ao tentar chamar ométodosacacomumvalorforadolimite?Osistemamostrariaumamensagemdeerro,masquemchamouométodosacanãosaberáqueissoaconteceu.

Comoavisaraquelequechamouométododequeelenãoconseguiufazeraquiloquedeveria?

Em Java, os mé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é,estarnumestadoinconsistentedeacordocomanossamodelagem.

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étodo e não a própria classe! Portanto, nada mais natural do que a classe sinalizar que um erroocorreu.

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;

EXCEÇÕESECONTROLEDEERROS

12.1MOTIVAÇÃO

.

}else{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çãoseriaalteraroretornodebooleanparainteretornarocódigodoerroqueocorreu.Issoéconsideradoumamá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íveldescobrir 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

.

argumentodosaqueinválidooudoidinválidodeumclienteéumaexceçãoàregra.

EXCEÇÃO

Uma exceção representa uma situação que normalmente não ocorre e representa algo deestranhoouinesperadonosistema.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

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);System.out.println(cc.getSaldo());

JáconheceoscursosonlineAlura?

12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS

.

if(i==5){cc=null;}}System.out.println("fimdometodo2");}}

Repareométodomainchamandometodo1eesse,porsuavez,chamandoometodo2.Cadaumdessesmétodospodetersuasprópriasvariáveislocais,istoé:ometodo1nãoenxergaasvariáveisdeclaradasdentrodomaineporaíemdiante.

ComooJava(emuitasdasoutraslinguagens)fazisso?Todainvocaçãodemétodoéempilhadaemuma estrutura de dados que isola a área dememória de cada um. Quando ummétodo termina(retorna), ele volta para ométodoque o invocou.Ele descobre isso através dapilhade execução(stack):bastaremoveromarcadorqueestánotopodapilha:

Porém, o nosso metodo2 propositadamente possui um enorme problema: está acessando umareferê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 em estadode alerta e vai ver se ométodo atual toma algumaprecaução aotentarexecutaressetrechodecódigo.Comopodemosver,ometodo2nãotomanenhumamedidadiferentedoquevimosatéagora.

.

Comoometodo2nãoestátratandoesseproblema,aJVMpáraaexecuçãodeleanormalmente,semesperareleterminar,evoltaumstackframeprabaixo,ondeseráfeitanovaverificação:"ometodo1está se precavendo de um problema chamado NullPointerException?" "Não..." Volta para omain, onde tambémnãoháproteção, então a JVMmorre (na verdade, quemmorre é apenas a Thread corrente; se quiser saber mais sobre, há um apêndice de Threads e ProgramaçãoConcorrentenofinaldaapostila).

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ódigoquevaitentar(try)executaroblocoperigosoe,casooproblemasejadotipoNullPointerException,eleserápego(caught).ReparequeéinteressantequecadaexceçãonoJavatenhaumtipo...elapodeteratributosemétodos.

2. Adicioneumtry/catchemvoltadofor,pegandoNullPointerException.Oqueo códigoimprime?

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);}

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");

.

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

.

Quetaltentardividirumnúmeroporzero?SeráqueaJVMconseguefazeraquiloquenósdefinimosquenãoexiste?

publicclassTestandoADivisao{

publicstaticvoidmain(String[]args){inti=5571;i=i/0;System.out.println("Oresultado"+i);}}

Tenteexecutaroprogramaacima.Oqueacontece?

ReparequeumNullPointerExceptionpoderiaserfacilmenteevitadocomumifquechecariaseareferênciaédiferentedenull.

Outrocasoemquetambémocorretaltipodeexceçãoéquandoumcasterradoéfeito(veremosmaisprafrente).Emtodososcasos,taisproblemasprovavelmentepoderiamserevitadospeloprogramador.Époressemotivoqueojavanãoteobrigaadarotry/catchnessasexceptionsechamamosessasexceçõesdeunchecked.Emoutraspalavras,ocompiladornãochecasevocêestátratandoessasexceções.

ERROS

Oserros em Java sãoum tipode exceçã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, compilaramerodaram.Emum,oerroterminouoprogramae,nooutro,foipossíveltratá-lo.

MasnãoésóessetipodeexceçãoqueexisteemJava.Umoutrotipo,obrigaaquemchamaométodoou construtor a tratar essa exceção. Chamamos esse tipo de exceção de checked, pois o compiladorchecaráseelaestásendodevidamentetratada,diferentedasanteriores,conhecidascomounchecked.

12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS

.

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.O primeiro, é tratá-lo com otry ecatch domesmo jeito que usamos no exemplo anterior, dereferêncianula:

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:

.

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();}}}

No início, existe uma grande tentação de sempre passar o problema pra frente para outros otratarem.Podeserquefaçasentido,dependendodocaso,masnãoatéomain,porexemplo.Aconteceque quem tenta abrir um arquivo sabe como lidar com um problema na leitura.Quem chamou ummétodonocomeç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.

.

BOASPRÁTICASNOTRATAMENTODEEXCEÇÕES

NoblogdaCaelumháumextensoartigodiscutindoasboaspráticasemrelaçãoaotratamentodeexceções.

http://blog.caelum.com.br/2006/10/07/lidando-com-exceptions/

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

UmapequenapartedaFamíliaThrowable:

SaberinglêsémuitoimportanteemTI

12.5UMPOUCODAGRANDEFAMÍLIATHROWABLE

.

É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áriodeclararnothrowsasexceptionsquesãounchecked,porémépermitidoeàsvezes,facilitaaleituraeadocumentaçãodoseucódigo.

12.6MAISDEUMERRO

.

Lembre-sedométodosacadanossaclasseConta.Eledevolveumbooleancasoconsigaounãosacar:

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

Podemos,também,lançarumaException,oqueéextremamenteútil.Dessamaneira,resolvemosoproblemadealguémpoderesquecerdefazerumifnoretornodeummétodo.

Apalavra chave throw, que está no imperativo, lança umaException. Isto é bem diferente dethrows,queestánopresentedoindicativo,equeapenasavisadapossibilidadedaquelemétodolançá-la,obrigandoooutrométodoqueváutilizardestedesepreocuparcomessaexceçãoemquestão.

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewRuntimeException();}else{this.saldo-=valor;}}

Nonossocaso, lançaumado tipounchecked.RuntimeException é a exceptionmãede todas asexceptionsunchecked.Adesvantagem,aqui,équeelaémuitogenérica;quemreceberesseerronãosabedizerexatamentequalfoioproblema.PodemosentãousarumaExceptionmaisespecífica:

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewIllegalArgumentException();}else{this.saldo-=valor;}}

IllegalArgumentExceptiondizumpoucomais:algofoipassadocomoargumentoeseumétodonão gostou. Ela é uma Exception unchecked pois estende de RuntimeException e já faz parte dabibliotecadojava.(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);

12.7LANÇANDOEXCEÇÕES

.

}catch(IllegalArgumentExceptione){System.out.println("SaldoInsuficiente");}

Podíamos melhorar ainda mais e passar para o construtor da IllegalArgumentException omotivodaexceçã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 eexceptions)vairetornaramensagemquepassamosaoconstrutordaIllegalArgumentException.

try{cc.saca(100);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Imaginequevamossacardinheirodediversascontas:

Contacc=newContaCorrente();cc.deposita(100);

Contacp=newContaPoupanca();cp.deposita(100);

//sacandodascontas:

AprendasedivertindonaAluraStart!

12.8OQUECOLOCARDENTRODOTRY?

.

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 uma opção boa, pois a mensagem "consegui sacar" será impressa mesmo que ocatchsejaacionado.Semprequetemosalgoquedependedalinhadecimaparasercorreto,devemosagrupá-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êvaicolocardentrodotry influenciamuitoaexecuçãodoprograma!Pensedireitonaslinhasquedependemumadaoutraparaaexecuçãocorretadasualógicadenegócios.

.

Ébemcomumcriarumaprópriaclassedeexceçãoparacontrolarmelhorousode suasexceções.Dessamaneira,podemospassarvaloresespecíficosparaelacarregar,quesejamúteisdealgumaforma.Vamoscriaranossa:

Voltamos para o exemplo das Contas , vamos criar a nossa Exceção deSaldoInsuficienteException:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Emvezde lançarumIllegalArgumentException, vamos lançar nossa própria exception, comumamensagemquedirá"SaldoInsuficiente":

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewSaldoInsuficienteException("SaldoInsuficiente,"+"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, obrigandoaquemchamaessemétodoadartry-catch,outhrows:

publicclassSaldoInsuficienteExceptionextendsException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Osblocostryecatchpodemconterumaterceiracláusulachamadafinallyqueindicaoquedeveserfeitoapósotérminodoblocotryoudeumcatchqualquer.

12.9CRIANDOSEUPRÓPRIOTIPODEEXCEÇÃO

12.10PARASABERMAIS:FINALLY

.

Éinteressantecolocaralgoqueéimprescindíveldeserexecutado,casooquevocêqueriafazertenhadado certo, ou não.O casomais comum é o de liberar um recurso no finally, como um arquivo ouconexãocombancodedados,paraquepossamosteracertezadequeaquelearquivo(ouconexão)váserfechado,mesmoquealgotenhafalhadonodecorrerdocódigo.

Noexemploaseguir,oblocofinallyserásempreexecutado,independentementedetudoocorrerbemoudeaconteceralgumproblema:

try{//blocotry}catch(IOExceptionex){//blococatch1}catch(SQLExceptionsqlex){//blococatch2}finally{//blocoqueserásempreexecutado,independente//sehouveounãoexceptioneseelafoitratadaounão}

Hátambém,noJava7,umrecursopoderosoconhecidocomotry-with-resources,quepermiteutilizarasemânticadofinallydeumamaneirabemmaissimples.

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

CasadoCódigo,LivrosdeTecnologia.

1. Na classe Conta,modifique ométodo deposita(doublex): Ele deve lançar uma exceptionchamadaIllegalArgumentException,quejáfazpartedabibliotecadoJava,semprequeovalorpassadocomoargumentoforinválido(porexemplo,quandofornegativo).

publicvoiddeposita(doublevalor){if(valor<0){thrownewIllegalArgumentException();}else{this.saldo+=valor;}

Seuslivrosdetecnologiaparecemdoséculopassado?

12.11EXERCÍCIOS:EXCEÇÕES

.

}

2. Rodeaaplicação,cadastreumacontaetentedepositarumvalornegativo.Oqueacontece?

3. Ao lançar a IllegalArgumentException, passe via construtor uma mensagem a ser exibida.LembrequeaString recebidacomoparâ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ãopodesacarumvalornegativo!

5. Vamosvalidartambémqueoclientenãopodesacarumvalormaiordoqueosaldodisponívelemconta.CriesuaprópriaException,SaldoInsuficienteException.Paraisso,vocêprecisacriarumaclassecomessenomequesejafilhadeRuntimeException.

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áticadizquedevemospreferirusarasjáexistentesdoJavasemprequepossível.

6. (opcional)ColoqueumconstrutornaclasseSaldoInsuficienteExceptionquerecebaovalorqueeletentousacar(istoé,elevaireceberumdoublevalor).

Quandoestendemosumaclasse,nãoherdamosseusconstrutores,maspodemosacessá-losatravésdapalavrachavesuperdedentrodeumconstrutor.Asexceçõesdo Javapossuemumasériedeconstrutores úteis para poder populá-las já com umamensagem de erro. Então vamos criar um

.

construtoremSaldoInsuficienteExceptionquedelegueparaoconstrutordesuamãe.Essavaiguardaressamensagemparapodermostrá-laaoserinvocadoométodogetMessage:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(doublevalor){super("Saldoinsuficienteparasacarovalorde:"+valor);}}

Dessamaneira, na hora de dar o throw new SaldoInsuficienteException você vai precisarpassaressevalorcomoargumento:

if(this.saldo<valor){thrownewSaldoInsuficienteException(valor);}

Atenção: você pode se aproveitar do Eclipse para isso: comece já passando o valor comoargumentoparaoconstrutordaexceptioneoEclipsevaireclamarquenãoexistetalconstrutor.Oquickfix(ctrl+1)vaisugerirqueelesejaconstruindo,poupando-lhetempo!

Eagora,comoficaométodosacadaclasseContaCorrente?

7. (opcional)DeclareaclasseSaldoInsuficienteException comofilhadiretadeException emvezdeRuntimeException.Elapassaaserchecked.Oqueissoresulta?

Vocêvaiprecisaravisarqueoseumétodosaca()throwsSaldoInsuficienteException,poiselaéumacheckedexception.Alémdisso,quemchamaessemétodovaiprecisartomarumadecisãoentretry-catchouthrows.FaçausodoquickfixdoEclipsenovamente!

Depois, retorne a exception para unchecked, isto é, para ser filha de RuntimeException, poisutilizaremoselaassimemexercíciosdoscapítulosposteriores.

1. Oqueaconteceseacabaramemóriadajavavirtualmachine?

ExisteumapéssimapráticadeprogramaçãoemjavaqueéadeescreverocatcheothrowscomException.

ExistemcódigosquesempreusamExceptionpoisissocuidadetodosospossíveiserros.Omaiorproblemadisso é generalizar o erro. Se alguém joga algodo tipoException paraquemo chamou,quemrecebenãosabequalotipoespecíficodeerroocorreuenãovaisabercomotrataromesmo.

Sim,hácasosondeotratamentodemaisdeumaexceptionpodeserfeitodeumamesmamaneira.

12.12DESAFIOS

12.13DISCUSSÃOEMAULA:CATCHETHROWSEMEXCEPTION

.

Por exemplo, se queremos terminar a aplicação tanto no caso de IOException quanto emSQLException.Sefizermoscatch(Exceptione)parapegaressesdoiscasos,teremosumproblema:aaplicaçãovaipararmesmoqueoutraexceçãosejalançada.Asoluçãocorretaseriaterdoiscatches,masaí teríamoscódigorepetido.Paraevitarocódigorepetido,podemosusaromulti-catchdoJava7,quepermite um mesmo catch cuidar de mais de 1 exceção, através da sintaxe catch(IOException |SQLExceptione){...}.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraéamelhorhoraderespirarmaistecnologia!

.

CAPÍTULO13

"Nossascabeçassãoredondasparaqueospensamentospossammudardedireção."--FrancisPiacaba

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

utilizarasprincipaisclassesdopacotejava.lange leradocumentaçãopadrãodeprojetosjava;usaraclasseSystemparaobterinformaçõesdosistema;utilizaraclasseStringdeumamaneiraeficienteeconhecerseusdetalhes;utilizarosmétodosherdadosdeObjectparageneralizarseuconceitodeobjetos.

Jáusamos,pordiversasvezes,asclassesStringeSystem.VimososistemadepacotesdoJavaenunca precisamos dar um import nessas classes. Isso ocorre porque elas estão dentro do pacotejava.lang,queéautomaticamenteimportadoparavocê.Éoúnicopacotecomestacaracterística.

Vamosverumpoucodesuasprincipaisclasses.

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

CasadoCódigo,LivrosdeTecnologia.

OPACOTEJAVA.LANG

13.1PACOTEJAVA.LANG

Seuslivrosdetecnologiaparecemdoséculopassado?

13.2UMPOUCOSOBREACLASSESYSTEM

.

A classe System possui uma série de atributos e métodos estáticos. Já usamos o atributoSystem.out,paraimprimir.

Olhandoadocumentação,vocêvaiperceberqueoatributooutédotipoPrintStreamdopacotejava.io. Veremos sobre essa classemais adiante. Já podemos perceber que poderíamos quebrar oSystem.out.printlnemduaslinhas:

PrintStreamsaida=System.out;saida.println("olamundo!");

OSystemcontatambémcomummétodoquesimplesmentedesligaavirtualmachine,retornandoumcódigodeerroparaosistemaoperacional,éoexit.

System.exit(0);

VeremostambémumpoucomaissobreaclasseSystemnospróximoscapítulosenoapêndicedeThreads.ConsulteadocumentaçãodoJavaevejaoutrosmétodosúteisdaSystem.

Todométodoqueprecisamosreceberalgumparâmetro temosquedeclararo tipodomesmo.Porexemplo,nonossométodosacaprecisamospassar comoparâmetroumvalordo tipodouble. Setentarmospassarqualquercoisadiferentedissoteremosumerrodecompilação.

AgoravamosobservaroseguintemétododopróprioJava:

System.out.println("Olámundo!");

Nestecaso,ométodoprintlnestárecebendoumaString epoderíamospensarqueo tipodeparâmetroqueelerecebeéString.Masaomesmo tempopodemospassarparaessemétodocoisascompletamentediferentescomoint,Conta,Funcionario,SeguroDeVida,etc.Comoessemétodoconseguerecebertantosparâmetrosdetiposdiferentes?

Umapossibilidade seria o uso da sobrecarga, declarandoumprintln para cada tipo de objetodiferente. 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());}

Essemétodo pode ser invocado passando como parâmetro qualquer tipo de conta que temos nonossosistema:ContaCorrenteeContaPoupancapoisambassãofilhasdeConta. Se quiséssemosqueonossométodoconseguissereceberqualquertipodeobjetoteríamosqueterumaclassequefossemãedetodosessesobjetos.ÉparaissoqueexisteaclasseObject!

13.3JAVA.LANG.OBJECT

.

Semprequandodeclaramosumaclasse,essaclasseéobrigada aherdardeoutra. Istoé,para todaclassequedeclararmos,existeumasuperclasse.Porém,criamosdiversasclassessemherdardeninguém:

classMinhaClasse{

}

Quandoo Javanãoencontraapalavrachaveextends, ele consideraque você estáherdandodaclasseObject,quetambémseencontradentrodopacotejava.lang.Vocêatémesmopodeescreveressaherança,queéomesmo:

publicclassMinhaClasseextendsObject{

}

Todasasclasses,semexceção,herdamdeObject,sejadiretaouindiretamente,poiselaéamãe,vó,bisavó,etcdequalquerclasse.

Podemos tambémafirmarquequalquerobjetoemJavaéumObject, podendo ser referenciadocomo tal. Então, qualquer objeto possui todos osmétodos declarados na classe Object e veremosalgunsdeleslogoapósocasting.

A habilidade de poder se referir a qualquer objeto como Object nos traz muitas vantagens.Podemos criar ummétodo que recebe um Object como argumento, isto é, qualquer objeto! Porexemplo,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 deidentidade:

Conta@34f5d74a

Masesequisermosimprimiralgodiferente?Nanossateladedetalhesdeconta,temosumacaixadeseleçãoondenossascontasestãosendoapresentadascomovalordopadrãodotoString.Semprequequeremos modificar o comportamento de um método em relação a implementação herdada dasuperclasse,podemossobrescrevê-lonaclassefilha:

publicabstractclassConta{

13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING

toString

.

protecteddoublesaldo;//outrosatributos...

@OverridepublicStringtoString(){return"[titular="+titular+",numero="+numero+",agencia="+agencia+"]";}}

Agorapodemosusaressemétodoassim:

ContaCorrentecc=newContaCorrente();System.out.println(cc.toString());

E o melhor, 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+.SeoJavaencontraumobjetonomeiodaconcatenaçã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 comono casodotoString, todos objetos do Java possuem um outrométodo chamadoequalsqueéutilizadoparacompararobjetosdaqueletipo.Porpadrão,essemétodoapenascomparaasreferênciasdosobjetos.Comotodavezque inserimosumanovacontanosistemaestamosfazendonewemalgumtipodeconta,asreferênciasnuncavãoseriguais,mesmoosdados(númeroeagência)sendoiguais.

Mas,esefosseprecisocompararosatributos?Quaisatributoseledeveriacomparar?OJavaporsisónão faz isso,maspodemossobrescreveroequals da classeObject para criarmos esse critériodecomparação.

OequalsrecebeumObjectcomoargumentoedeveverificarseelemesmoéigualaoObjectrecebidopararetornarumboolean.Sevocênãoreescreveressemétodo,ocomportamentoherdadoéfazerum==comoobjetorecebidocomoargumento.

publicabstractclassConta{

equals

.

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étodoseatributosdesseobjetoqueimaginamosserumaConta?Se estamos referenciando-ocomoObject,nãopodemosacessá-locomosendoConta.Ocódigoacimanãocompila!

PoderíamosentãoatribuiressareferênciadeObjectparaContaparadepoisacessarosatributosnecessários?Tentemos:

ContaoutraConta=object;

Nós temoscertezadequeesseObject se refereaumaConta, já que anossa lista só imprimecontas.Masocompilador Javanão temgarantias sobre isso!Essa linhaacimanãocompila,poisnemtodoObjectéumaConta.

Pararealizaressaatribuição,paraissodevemos"avisar"ocompiladorJavaquerealmentequeremosfazer isso, sabendo do risco que corremos. Fazemos o castingde referências, parecido com de tiposprimitivos:

ContaoutraConta=(Conta)object;

Ocódigopassaa compilar,mas seráque roda?Essecódigo roda semnenhumproblema,pois emtempodeexecuçãoaJVMverificaráseessareferênciarealmenteéparaumobjetodetipoConta,eestá!Senãoestivesse,umaexceçãodotipoClassCastExceptionserialançada.

Comisso,nossométodoequalsficariaassim:

publicabstractclassConta{protecteddoublesaldo;//outrosatributos...

publicbooleanequals(Objectobject){if(object==null){returnfalse;}

ContaoutraConta=(Conta)object;

Castingdereferências

.

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 fundamentalentendimento 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 doobjetopassadonãoserdetipocompatívelcomasuaclasse.Entãoantesdefazerocastingdevemosverificar isso,eparatalusamosapalavrachaveinstanceof,ou teríamosumaexceptionsendolanç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));}

.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Como verificar se a classeThrowable que é a superclasse deException também reescreve ométodotoString?

AmaioriadasclassesdoJavaquesãomuitoutilizadas terãoseusmétodosequals etoStringreescritosconvenientemente.

2. Utilize-sedadocumentaçãodoJavaedescubradequeclasseéoobjetoreferenciadopeloatributooutdaSystem.

Repareque,comodevidoimport,poderíamosescrever:

//faltaadeclaraçãodasaída________saida=System.out;saida.println("ola");

Avariávelsaida precisa ser declarada de que tipo? É isso que você precisa descobrir. Se vocêdigitaressecódigonoEclipse,elevaitesugerirumquickfixedeclararáavariávelparavocê.

Estudaremosessaclasseemumcapítulofuturo.

3. Rode a aplicação e cadastreduas contas.Na tela dedetalhesde conta, verifiqueoque aparecenacaixadeseleçãodecontaparatransferência.Porqueissoacontece?

4. Reescreva o método toString da sua classe Conta fazendo com que uma mensagemmaisexplicativa seja devolvida. Lembre-se de aproveitar dos recursos do Eclipse para isto: digitandoapenasocomeçodonomedométodoa ser reescritoepressionandoctrl+espaço, elevai sugerirreescrever ométodo, poupando o trabalho de escrever a assinatura dométodo e cometer algumengano.

publicabstractclassConta{

Agoraéamelhorhoraderespirarmaistecnologia!

13.5EXERCÍCIOS:JAVA.LANG.OBJECT

.

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. Reescreva ométodoequals da classeConta para que duas contas com omesmo nú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ê pode usar o ctrl+ espaço do Eclipse para escrever o esqueleto dométodoequals, bastadigitardentrodaclasseequepressionarctrl+espaço.

Rodeaaplicaçãoetenteadicionarduascontascomomesmonúmeroeagência.Oqueacontece?

StringéumaclasseemJava.VariáveisdotipoStringguardamreferênciasaobjetos,enãoumvalor,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

.

Temosaquidoisobjetosdiferentes!E,então,comofaríamosparaverificarseoconteúdodoobjetoéomesmo?Utilizamosométodoequals,quefoireescritopelaString,parafazeracomparaçãodecharemchar.

if(x.equals(y)){System.out.println("consideramosiguaisnocritériodeigualdade");}else{System.out.println("consideramosdiferentesnocritériodeigualdade");}

Aqui,acomparaçãoretornaverdadeiro.Porquê?PoisquemimplementouaclasseStringdecidiuqueesteseriaomelhorcritériodecomparação.Vocêpodedescobriroscritériosdeigualdadedecadaclassepeladocumentação.

PodemostambémconcatenarStringsusandoo+.PodemosconcatenarStringscomqualquerobjeto,atémesmonúmeros:

inttotal=5;System.out.println("ototalgastoé:"+total);

O compilador utilizará os métodos apropriados da classe String e possivelmente métodos deoutrasclassespararealizartaltarefa.

SequisermoscompararduasStrings,utilizamosométodocompareTo,que recebeumaStringcomoargumento edevolveum inteiro indicando se aString vemantes, é igual ou vemdepois daStringrecebida.Seforemiguais,édevolvido0;seforanterioràStringdoargumento,devolveuminteironegativo;e,seforposterior,uminteiropositivo.

Fatoimportante:umaStringéimutável.OjavacriaumpooldeStringsparausarcomocachee,seaStringnãofosseimutável,mudandoovalordeumaStringafetariatodasasStrings deoutrasclassesquetivessemomesmovalor.

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:

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 cadainvocaçã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ê podeencontrar mais informações sobre isto na documentação da classe String e no seu métodointern().

OUTROSMÉTODOSDACLASSESTRING

Existem diversos métodos da classe String que são extremamente importantes.Recomendamossempreconsultarojavadocrelativoaessaclasseparaaprendercadavezmaissobreamesma.

Porexemplo,ométodocharAt(i),retornaocaractereexistentenaposiçãoidaString,ométodolengthretornaonúmerodecaracteresnamesmaeométodosubstringquerecebeumintedevolveaSubStringapartirdaposiçãopassadaporaqueleint.

OindexOfrecebeumcharouumaStringedevolveoíndiceemqueaparecepelaprimeiraveznaStringprincipal(hátambémolastIndexOfquedevolveoíndicedaúltimaocorrência).

OtoUpperCaseeotoLowerCasedevolvemumanovaStringtodaemmaiúsculaetodaemminúscula,respectivamente.

ApartirdoJava6,temosaindaométodoisEmpty,quedevolvetrueseaStringforvaziaoufalsecasocontrário.

Algunsmétodosúteisparabuscassãoocontainseomatches.

Hámuitosoutrosmétodos,recomendamosquevocêsempreconsulteojavadocdaclasse.

.

JAVA.LANGSTRINGBUFFERESTRINGBUILDER

ComoaclasseStringéimutável,trabalharcomumamesmaStringdiversasvezespodeterum efeito colateral: gerar inúmeras Strings temporárias. Isto prejudica a performance daaplicaçãoconsideravelmente.

NocasodevocêtrabalharmuitocomamanipulaçãodeumamesmaString (por exemplo,dentrodeumlaço),oidealéutilizaraclasseStringBuffer.AclasseStringBufferrepresentaumasequênciadecaracteres.DiferentementedaString,elaémutável,enãopossuiaquelepool.

AclasseStringBuilder temexatamenteosmesmosmétodos,comadiferençadelanãoserthread-safe.VeremossobreesteconceitonocapítulodeThreads.String.

1. Queremosqueascontasapresentadasnacaixadeseleçãodatransferênciaapareçamcomonomedotitularemmaiúsculas.ParafazerissovamosalterarométodotoStringdaclasseConta.UtilizeométodotoUpperCasedaStringparaisso.

2. Apósalterarmosomé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 encontradentrodeoutra?Epara tirar os espaços embrancodaspontasdeumaString?EparasaberseumaStringestávazia?EparasaberquantoscaracterestemumaString?

TomecomohábitosemprepesquisaroJavaDoc!ConheceraAPI,aospoucos,é fundamentalparaquevocênãoprecisereescreveraroda!

5. (opcional) Escreva ummétodo que usa osmétodoscharAt elength de umaString paraimprimiramesmacaractereacaractere,comcadacaractereemumalinhadiferente.

13.7EXERCÍCIOS:JAVA.LANG.STRING

.

6. (opcional) Reescreva o método do exercício anterior, mas modificando ele para que imprima aString de trás para a frente e emuma linha só.Teste-apara "Socorram-me, subi no ônibus emMarrocos"e"anotaramadatadamaratona".

7. (opcional)PesquiseaclasseStringBuilder(ouStringBuffernoJava1.4).Elaémutável.Porqueusá-laemvezdaString?Quandousá-la?

Comovocêpoderia reescrever ométodode escrever aString de trás para a frenteusandoumStringBuilder?

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

CasadoCódigo,ebookcompreçodeebook.

1. ConvertaumaStringparaumnúmerosemusarasbibliotecasdojavaquejáfazemisso. Issoé,umaStringx="762"devegeraruminti=762.

Paraajudar,saibaqueumcharpodeser"transformado"emintcomomesmovalornuméricofazendo:

charc='3';inti=c-'0';//ivale3!

Aquiestamosnosaproveitandodoconhecimentodatabelaunicode:osnúmerosde0a9estãoemsequência! Você poderia usar o método estático Character.getNumericValue(char) em vezdisso.

QualéasuanecessidadecomoJava?Precisafazeralgoritmosderedesneurais?Gerargráficos3D?Relatórios emPDF?Gerar código de barra?Gerar boletos?ValidarCPF?Mexer comum arquivo do

EditoraCasadoCódigocomlivrosdeumaformadiferente

13.8DESAFIO

13.9DISCUSSÃOEMAULA:OQUEVOCÊPRECISAFAZEREMJAVA?

.

Excel?

O instrutor vai mostrar que para a maioria absoluta das suas necessidades, alguém já fez umabibliotecaeadisponibilizou.

.

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 foi criaruma arraydedoublede 10posições e atribuir o endereçonoqual ela 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

.

ARRAYS-UMPROBLEMANOAPRENDIZADODEMUITASLINGUAGENS

Aprender a usar arrays pode ser um problema em qualquer linguagem. Isso porque envolveumasériedeconceitos,sintaxeeoutros.NoJava,muitasvezesutilizamosoutrosrecursosemvezdearrays, em especial os pacotes de coleções do Java, que veremos no capítulo 15. Portanto, fiquetranquilocasonãoconsigadigerirtodasintaxedasarraysnumprimeiromomento.

No caso do bilhete de loteria, podemos utilizar o mesmo recurso. Mais ainda, a quantidade denúmeros do nosso bilhete pode ser definido por uma variável. Considere que n indica quantosnúmerosnossobilheteterá,podemosentãofazer:

int[]numerosDoBilhete=newint[n];

Eassimpodemosacessaremodificarosinteiroscomíndicede0an-1.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%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

.

Quantascontasforamcriadasaqui?Naverdade,nenhuma.Foramcriados10espaçosquevocêpodeutilizarparaguardarumareferênciaaumaContaCorrente.Porenquanto,elessereferenciamparalugarnenhum(null).Sevocêtentar:

System.out.println(minhasContas[0].getSaldo());

Umerrodurante a execuçãoocorrerá! Pois, na primeira posiçãoda array, nãoháuma referê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.

Mas e se agoraquisermos guardar tantoContaCorrente quantoContaPoupança?Um array deContaCorrente só consegue guardar objetos domesmo tipo. Se quisermos guardar os dois tipos deconta,devemoscriarumarraydeConta!

Conta[]minhasContas=newConta[10];minhasContas[0]=newContaCorrente();minhasContas[1]=newContaPoupanca();

Percebaquenão estamos criandoumobjetodo tipoConta, que é abstrata, estamos criando 10espaçosqueguardamreferênciasparaqualquertipodeconta.

14.3PERCORRENDOUMAARRAY

.

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êpodeacessá-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

.

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çãoparafacilitaressatarefadepercorrerarraysetorná-lamaislegível.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Paraconsolidarmososconceitossobrearrays,vamosfazeralgunsexercíciosquenãointerferememnossoprojeto.

1. CrieumaclasseTestaArrays enométodomain crie umarrayde contasde tamanho10.Emseguida,façaumlaçoparacriar10contascomsaldosdistintosecolocá-lasnoarray.Porexemplo,vocêpodeutilizaroíndicedolaçoemultiplicá-lopor100paragerarosaldodecadaconta:

Conta[]contas=newConta[10];

for(inti=0;i<contas.length;i++){Contaconta=newContaCorrente();

SaberinglêsémuitoimportanteemTI

14.5EXERCÍCIOS:ARRAYS

.

conta.deposita(i*100.0);//escrevaocódigoparaguardaracontanaposiçãoidoarray}

2. AindanaclasseTestaArrays,façaumoutrolaçoparacalculareimprimiramédiadossaldosdetodasascontasdoarray.

3. (opcional) Crie uma classe TestaSplit que reescreva uma frase com as palavras na ordeminvertida."Socorram-me, subinoônibus emMarrocos"deveretornar "Marrocos emônibusno subiSocorram-me,".Utilize ométodosplit da String para te auxiliar. Essemétodo divide umaStringdeacordocomoseparadorespecificadoedevolveaspartesemumarraydeString,porexemplo:

Stringfrase="Umamensagemqualquer";String[]palavras=frase.split("");

//Agorasóbastapercorreroarraynaordeminversaimprimindoaspalavras

4. (opcional)CrieumaclasseBancodentrodopacotebr.com.caelum.contas.modeloOBancodeve terumnomeeumnúmero (obrigatoriamente) euma referência aumaarraydeConta detamanho10,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ênciaaContacomoargumentoeguardaessaconta.

VocêdeveinseriraContaemumaposiçãodaarrayqueestejalivre.Existemváriasmaneirasparavocê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,muitomenosorientadaaobjetosde se trabalhar.VocêantescriaumaContaejápassaareferênciadela,quedentrodoobjetopossuititular,saldo,etc.

6. (opcional)CrieumaclasseTestaBancoquepossuiráummétodomain.Dentrodelecriealgumasinstâ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 deContaCorrente ficasse acimado laço, estaríamos adicionado cinco vezes amesma instância deContaCorrentenesteBancoeapenasmudandoseudepósitoacadaiteração,quenessecasonãoéoefeitodesejado.

Opcional:ométodoadicionapodegerarumamensagemdeerroindicandoquandooarrayjáestácheio.

7. (opcional)PercorraoatributocontasdasuainstânciadeBancoeimprimaosdadosdetodasassuascontas.Parafazerisso,vocêpodecriarummétodochamadomostraContasdentrodaclasseBanco:

publicvoidmostraContas(){for(inti=0;i<this.contas.length;i++){System.out.println("Contanaposição"+i);//preencherparamostraroutrasinformacoesdaconta

.

}}

Cuidadoaopreencheressemétodo:alguns índicesdoseuarraypodemnãoconterreferênciaparaumaContaconstruída,istoé,aindasereferiremparanull.Sepreferir,useofornovodojava5.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)Crieummétodoparaverificar seumadeterminadaConta se encontraounão comocontadestebanco:

publicbooleancontem(Contaconta){//...}

Vocêvaiprecisar fazerumfor em seu array e verificar se a contapassada comoargumento seencontradentrodoarray.Eviteaomáximousarnúmeroshard-coded,istoé,useo.length.

10. (opcional)Casoo array já esteja cheionomomentode adicionarumaoutra conta, crieumarraynovocomumacapacidademaiorecopieosvaloresdoarrayatual.Istoé,vamosfazerarealocaçãodoselementosdoarrayjáquejavanãotemisso:umarraynasceemorrecomomesmolength.

USANDOOTHISPARAPASSARARGUMENTO

Dentrodeummétodo,vocêpodeusarapalavrathisparareferenciarasimesmoepodepassaressareferênciacomoargumento.

Arrayspodemtermaisdeumadimensão. Istoé,emvezde termosumaarrayde10contas,podemosterumaarrayde10por10contasevocêpodeacessaracontanaposiçãodacolunaxelinhay.Naverdade,umaarraybidimensionalemJavaéumaarraydearrays.Pesquisesobreisso.

14.6UMPOUCOMAIS...

.

Umaarraybidimensionalnãoprecisa ser retangular, istoé, cada linhapode terumnúmerodiferentedecolunas.Como?Porque?

Oqueacontecesecriarmosumaarrayde0elementos?e-1?

Ométodomain recebeumaarraydeStrings comoargumento.Essa array é passadapelousuárioquandoeleinvocaoprograma:

$javaTesteargumento1outromaisoutro

Enossaclasse:

publicclassTeste{publicstaticvoidmain(String[]args){for(Stringargumento:args){

.

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 imprimironúmerodeportasabertaseométodototalDePortaspara imprimiro totaldeportasemsuacasa.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

14.7DESAFIOSOPCIONAIS

AprendasedivertindonaAluraStart!

.

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ão conseguimos saber quantas posições do array já foram populadas sem criar, para isso,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 algumaestruturadedadosexterna,asposiçõesvazias?Esenãohouverespaçovazio?Teríamosdecriarumarraymaiorecopiarosdadosdoantigoparaele?

Hámais questões: comoposso saber quantas posições estão sendousadasno array?Vouprecisarsemprepercorreroarrayinteiroparaconseguiressainformação?

COLLECTIONSFRAMEWORK

15.1ARRAYSSÃOTRABALHOSOS,UTILIZARESTRUTURADEDADOS

.

Alémdessasdificuldadesqueosarraysapresentavam, faltavaumconjuntorobustodeclassesparasupriranecessidadedeestruturasdedadosbásicas,comolistasligadasetabelasdeespalhamento.

Comesseseoutrosobjetivosemmente,ocomitêresponsávelpeloJavacriouumconjuntodeclasseseinterfacesconhecidocomoCollectionsFramework,queresidenopacotejava.utildesdeoJava21.2.

COLLECTIONS

AAPIdeCollectionsérobustaepossuidiversasclassesquerepresentamestruturasdedadosavançadas.

Porexemplo,nãoénecessárioreinventararodaecriarumalistaligada,massimutilizaraquelaqueoJavadisponibiliza.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Um primeiro recurso que a API de Collections 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 resolvetodososproblemasque levantamosemrelaçãoaoarray (busca, remoção, tamanho "infinito",...).Esse

SaberinglêsémuitoimportanteemTI

15.2LISTAS:JAVA.UTIL.LIST

.

códigojáestápronto!

AAPIdeCollectionstrazainterfacejava.util.List,queespecificaoqueumaclassedevesercapazde fazerparaseruma lista.Hádiversas implementaçõesdisponíveis,cadaumacomumaformadiferentederepresentarumalista.

A implementaçãomaisutilizadada interfaceList éaArrayList, que trabalha comumarrayinterno para gerar uma lista. Portanto, ela é mais rápida na pesquisa do que sua concorrente, aLinkedList,queémaisrápidanainserçãoeremoçãodeitensnaspontas.

ARRAYLISTNÃOÉUMARRAY!

É comumconfundiremumaArrayList comum array, porém ela não é um array.O queocorreé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,umquerecebeoobjetoaserinseridoeocolocanofinaldalista,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 osmétodostrabalhamcomObject.

Assim,épossívelcriar,porexemplo,umalistadeContasCorrentes:

ContaCorrentec1=newContaCorrente();c1.deposita(100);

ContaCorrentec2=newContaCorrente();

.

c2.deposita(200);

ContaCorrentec3=newContaCorrente();c3.deposita(300);

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 comoargumentoo índicedo elementoque se querrecuperar.Atravésdele,podemosfazerumforparaiterarnalistadecontas:

for(inti=0;i<contas.size();i++){contas.get(i);//códigonãomuitoútil....}

Mascomofazerparaimprimirosaldodessascontas?PodemosacessarogetSaldo()diretamenteapósfazercontas.get(i)?Nãopodemos; lembre-se que toda lista trabalha sempre comObject.Assim, a referência devolvida pelo get(i) é do tipo Object , sendo necessário o cast paraContaCorrentesequisermosacessarogetSaldo():

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;econtains(), que recebe umobjeto como argumento e devolvetrue oufalse, indicando se oelementoestáounãonalista.

AinterfaceListealgumasclassesqueaimplementampodemservistasnodiagramaaseguir:

.

ACESSOALEATÓRIOEPERCORRENDOLISTASCOMGET

Algumaslistas,comoaArrayList,têmacessoaleatórioaosseuselementos:abuscaporumelemento em uma determinada posição é feita demaneira imediata, sem que a lista inteira sejapercorrida(quechamamosdeacessosequencial).

Nestecaso,oacessoatravésdométodoget(int)émuitorápido.Casocontrário,percorrerumalistausandoumforcomoessequeacabamosdever,podeserdesastroso.Aopercorrermosumalista,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 eremoveroprimeiroeúltimoelementodalista.Elatambémtemofuncionamentointernodiferente,oquepodeimpactarperformance,comoveremosduranteosexercíciosnofinaldocapítulo.

.

VECTOR

Outra implementação é a tradicional classe Vector , presente desde o Java 1.0, que foiadaptadaparausocomoframeworkdeCollections,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 houveracessosimultâ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?Como ométodoget devolve umObject,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:eleindicaquenossalistafoicriadaparatrabalharexclusivamentecomobjetosdotipoContaCorrente. Issonostrazumasegurançaemtempodecompilaçã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());}

A partir do Java 7, se você instancia um tipo genérico namesma linha de sua declaração, não é

15.3LISTASNOJAVA5EJAVA7COMGENERICS

.

necessáriopassar os tiposnovamente, bastausarnewArrayList<>(). É conhecido comooperadordiamante:

List<ContaCorrente>contas=newArrayList<>();

ValeressaltaraimportânciadousodainterfaceList:quandodesenvolvemos,procuramossemprenosreferiraela,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ãoespecífico?Dessamaneira,odiaqueoptarmospordevolverumaLinkedListemvezdeArrayList,as pessoas que estão usando o método buscaTodasContas poderão ter problemas, pois estavamfazendo referência a uma ArrayList. O ideal é sempre trabalhar com a interface mais genéricapossível:

classAgencia{

//modificaçãoapenasnoretorno:publicList<Conta>buscaTodasContas(){ArrayList<Conta>contas=newArrayList<>();

//paracadacontadobancodedados,contas.add

returncontas;}}

ÉomesmocasodepreferirreferenciaraosobjetoscomInputStream como fizemosnocapítulopassado.

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 umaimplementaçãoemespecíficocomoArrayList,deixandoométodomaisflexível:

classAgencia{

publicvoidatualizaContas(List<Conta>contas){//...}}

15.4AIMPORTÂNCIADASINTERFACESNASCOLEÇÕES

.

Também declaramos atributos como List em vez de nos comprometer como uma ou outraimplementação.Dessaformaobtemosumbaixoacoplamento:podemostrocaraimplementação,jáqueestamosprogramandoparaainterface!Porexemplo:

classEmpresa{

privateList<Funcionario>empregados=newArrayList<>();

//...}

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Vimos anteriormente que as listas são percorridas demaneira pré-determinada de acordo com ainclusãodositens.Mas,muitasvezes,queremospercorreranossalistademaneiraordenada.

AclasseCollectionstrazummétodoestáticosortquerecebeumListcomoargumentoeoordenaporordemcrescente.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.

AprendasedivertindonaAluraStart!

15.5ORDENAÇÃO:COLLECTIONS.SORT

.

Mas toda lista em Javapode serdequalquer tipodeobjeto, por exemplo,ContaCorrente. E sequisermosordenaruma 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étodosortnecessitaque todos seusobjetosda lista sejamcomparáveis epossuamummétodoque se comparacomoutraContaCorrente.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étododeveretornarzero,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,conseguimos dizer se um objeto émaior,menor ou igual ao outro, segundo algum critério por nós

.

definido.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,semprecisarmos fazernada? Simples: quemescreveu a classeString (lembre que ela é uma classecomoqualqueroutra)implementouainterfaceComparableeométodocompareToparaStrings,fazendocomparaçãoemordemalfabética.(ConsulteadocumentaçãodaclasseStringevejaométodocompareTo lá).OmesmoacontececomoutrasclassescomoInteger,BigDecimal,Date, entreoutras.

.

OUTROSMÉTODOSDACLASSECOLLECTIONS

AclasseCollectionstrazumagrandequantidadedemétodosestáticosúteisnamanipulaçãodecoleções.

binarySearch(List,Object):Realizaumabuscabináriapordeterminadoelementonalistaordenadaeretornasuaposiçã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 doschamadosStreams,queficaumpoucoforadoescopodeumcursoinicialdeJava.

Existeumaclasseanáloga,ajava.util.Arrays,quefazoperaçõessimilarescomarrays.

Éimportanteconhecê-lasparaevitarescrevercódigojáexistente.

Vamosordenarocampodedestinoda teladedetalhesdacontaparaqueascontasapareçamemordemalfabéticadetitular.

1. FaçasuaclasseContaimplementarainterfaceComparable<Conta>.Utilizeocritériodeordenarpelotitulardaconta.

publicclassContaimplementsComparable<Conta>{...}

DeixeoseumétodocompareToparecidocomeste:

publicclassContaimplementsComparable<Conta>{

//...todoocódigoanteriorficaaqui

publicintcompareTo(ContaoutraConta){returnthis.titular.compareTo(outraConta.titular);}}

2. Queremosqueascontasapareçamnocampodedestinoordenadaspelotitular.Vamosentãocriaro

15.6EXERCÍCIOS:ORDENAÇÃO

.

método ordenaLista na classe ManipuladorDeContas. Use o Collections.sort() paraordenaralistarecuperadadoEvento:

publicclassManipuladorDeContas{

//outrosmétodos

publicvoidordenaLista(Eventoevento){List<Conta>contas=evento.getLista("destino");Collections.sort(contas);}}

Rodeaaplicação,adicionealgumascontaseverifiqueseascontasaparecemordenadaspelonomedotitularnateladedetalhesdeconta.

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 é oCollections.sort, queousa comobaseparao algoritmodeordenação). Isso criaum sistemaextremamente coeso e, aomesmo tempo, combaixo acoplamento: a classeCollections nuncaimaginouqueordenariaobjetosdotipoConta,mas jáqueelessãoComparable, o seumétodosortestásatisfeito.

3. OqueteriaacontecidoseaclasseContanãoimplementasseComparable<Conta>mas tivesseométodocompareTo?

Façaumteste:removatemporariamenteasentençaimplementsComparable<Conta>,nãoremovaométodocompareToevejaoqueacontece.Bastaterométodo,semassinarainterface?

4. Comoposso inverter a ordemdeuma lista?Comoposso embaralhar todosos elementosdeumalista?Comopossorotacionaroselementosdeumalista?

InvestigueadocumentaçãodaclasseCollectionsdentrodopacotejava.util.

5. (opcional)CrieumanovaclasseTestaListaquecriaumaArrayListeinserenovascontascomsaldosaleatóriosusandoumlaço(for).Adivinheonomedaclasseparacolocarsaldosaleatórios?Random. Do pacote java.util . Consulte sua documentação para usá-la (utilize o métodonextInt()passandoonúmeromáximoasersorteado).

6. ModifiqueaclasseTestaListaparautilizarumaLinkedListemvezdeArrayList:

List<Conta>contas=newLinkedList<Conta>();

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çãoquenãopermiteelementosduplicados.

Outracaracterísticafundamentaldeleéofatodequeaordememqueoselementossãoarmazenadospodenãoseraordemnaqualelesforaminseridosnoconjunto.Ainterfacenãodefinecomodeveserestecomportamento.Talordemvariadeimplementaçãoparaimplementação.

Um conjunto é representado pela interfaceSet e tem como suas principais implementações asclassesHashSet,LinkedHashSeteTreeSet.

15.7CONJUNTO:JAVA.UTIL.SET

.

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 aceitaelementos repetidos. Não hámétodos que trabalham com índices, como o get(int) que as listaspossuem.AgrandevantagemdoSetéqueexistemimplementações,comoaHashSet, quepossuiumaperformanceincomparávelcomasListsquandousadoparapesquisa(métodocontains porexemplo).Veremosessaenormediferençaduranteosexercícios.

ORDEMDEUMSET

Seriapossívelusarumaoutraimplementaçãodeconjuntos,comoumTreeSet,queinsereoselementosdetalformaque,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ávamosoSetdeformaqueeletrabalhavacomObject,havendonecessidadedecastings.

.

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

CasadoCódigo,LivrosdeTecnologia.

AscoleçõestêmcomobaseainterfaceCollection,quedefinemétodosparaadicionareremoverumelemento,everificarseeleestánacoleção,entreoutrasoperações,comomostraatabelaaseguir:

UmacoleçãopodeimplementardiretamenteainterfaceCollection,porémnormalmenteseusaumadasduassubinterfacesmaisfamosas:justamenteSeteList.

A interfaceSet, como previamente vista, define um conjunto de elementos únicos enquanto ainterfaceListpermiteelementosduplicados,alémdemanteraordemaqualelesforamadicionados.

A busca emumSet pode sermais rápida do que emumobjeto do tipoList, pois diversasimplementações utilizam-se de tabelas de espalhamento (hash tables), realizando a busca para tempolinear(O(1)).

A interfaceMap faz parte do framework,mas não estendeCollection. (veremos Map maisadiante).

Seuslivrosdetecnologiaparecemdoséculopassado?

15.8PRINCIPAISINTERFACES:JAVA.UTIL.COLLECTION

.

NoJava5,temosoutrainterfacefilhadeCollection:aQueue,quedefinemétodosdeentradaede saídae cujocritério serádefinidopela sua implementação (porexemploLIFO,FIFOouaindaumheapondecadaelementopossuisuachavedeprioridade).

Comopercorreroselementosdeumacoleção?Se foruma lista,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 quintoelementodoconjunto,jáqueumconjuntonãopossuioconceitode"ordem"

Podemosusaroenhanced-for(o"foreach")doJava5parapercorrerqualquerCollectionsemnospreocupar com isso. Internamente o compilador vai fazer com que seja usado o Iterator daCollectiondadaparapercorreracoleção.Repare:

Set<String>conjunto=newHashSet<>();

conjunto.add("java");conjunto.add("vraptor");conjunto.add("scala");

for(Stringpalavra:conjunto){System.out.println(palavra);}

Emqueordemoselementosserãoacessados?

15.9PERCORRENDOCOLEÇÕESNOJAVA5

.

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 quedesejarmos!SempreconsidereusarumSetsenãohouveranecessidadedeguardaroselementosemdeterminadaordemebuscá-losatravésdeumíndice.

No eclipse, você pode escrever foreach e dar ctrl+espaço, que ele vai gerar o esqueleto desseenhancedfor!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 interfaceIterator,queconheceinternamenteacoleçãoedáacessoatodososseuselementos,comoafiguraabaixomostra.

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, oIterator retorna o próximo objeto do conjunto.Um iterator pode ser obtido com ométodoiterator()deCollection,porexemplonumalistadeString:

Iterator<String>i=lista.iterator();

AinterfaceIteratorpossuidoismétodosprincipais:hasNext()(comretornobooleano),indica

15.10 PARA SABER MAIS: ITERANDO SOBRE COLEÇÕES COMJAVA.UTIL.ITERATOR

.

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ó terminaquando todosos elementosdo conjunto forempercorridos, isto é,quandoométodohasNextmencionarquenãoexistemmaisitens.

LISTITERATOR

Umalistafornece,alémdeacessoaumIterator,umListIterator,queoferecerecursosadicionais,específicosparalistas.

UsandooListIterator,vocêpode,porexemplo,adicionarumelementonalistaouvoltarparaoelementoquefoi"iterado"anteriormente.

USARITERATOREMVEZDOENHANCED-FOR?

OIteratorpodesimaindaserútil.Alémde iterarnacoleçãocomofazoenhanced-for,oIterator consegue remover elementos da coleção durante a iteração de uma forma elegante,atravésdométodoremove.

.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

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árias linguagens.Algumas linguagens,comoPerlouPHP,possuemumsuportemaisdiretoamapas,ondesãoconhecidoscomomatrizes/arraysassociativas.

java.util.Map é um mapa, pois é possível usá-lo para mapear uma chave a um valor, porexemplo: mapeie à chave "empresa" o valor "Caelum", ou então mapeie à chave "rua" ao valor"Vergueiro".Semelhanteaassociaçõesdepalavrasquepodemosfazeremumdicionário.

Agoraéamelhorhoraderespirarmaistecnologia!

15.11MAPAS-JAVA.UTIL.MAP

.

Ométodo put(Object, Object) da interface Map recebe a chave e o valor de uma novaassociação. Para saber o que está associado a um determinado objeto-chave, passa-se esse objeto nométodoget(Object).Semdúvidaessassãoasduasoperaçõesprincipaisemaisfrequentesrealizadassobreummapa.

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),oque tornaria necessário o casting no momento que recuperar elementos. Usando os generics, comofizemosaqui,nãoprecisamosmaisdocasting.

SuasprincipaisimplementaçõessãooHashMap,oTreeMapeoHashtable.

Apesardomapa fazerpartedo framework, elenão estende a interfaceCollection, por ter umcomportamentobemdiferente.Porém,ascoleçõesinternasdeummapa(adechaveseadevalores,verFigura7)sãoacessíveispormétodosdefinidosnainterfaceMap.

.

OmétodokeySet()retornaumSetcomaschavesdaquelemapaeométodovalues()retornaaCollectioncomtodososvaloresqueforamassociadosaalgumadaschaves.

Ummapa importante é a tradicional classeProperties, quemapeia strings e émuitoutilizadaparaaconfiguraçãodeaplicações.

APropertiespossui,também,métodosparaleregravaromapeamentocombaseemumarquivotexto,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ãohouveanecessidadedocastingparaStringnomomentoderecuperarosobjetosassociados. Isto porque a classe Properties foi desenhada com o propósito de trabalhar com a

15.12PARASABERMAIS:PROPERTIES

.

associaçãoentreStrings.

Muitas das coleções do java guardam os objetos dentro de tabelas de hash. Essas tabelas sãoutilizadasparaqueapesquisadeumobjetosejafeitademaneirarápida.

Comofunciona?Cadaobjetoé"classificado"peloseuhashCodee,comisso,conseguimosespalharcadaobjetoagrupando-ospelohashCode.Quandobuscamosdeterminadoobjeto,sóvamosprocurarentre os elementos que estão no grupo daquele hashCode. Dentro desse grupo, vamos testando oobjetoprocuradocomocandidatousandoequals().

Paraque isso funcionedireito,ométodohashCodedecadaobjetodeve retornaromesmovalorparadoisobjetos,seelessãoconsideradosequals.Emoutraspalavras:

a.equals(b)implicaa.hashCode()==b.hashCode()

Implementar hashCode de tal maneira que ele retorne valores diferentes para dois objetosconsideradosequalsquebraocontratodeObjecteresultará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().

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

CasadoCódigo,ebookcompreçodeebook.

15.13PARASABERMAIS:EQUALSEHASHCODE

EditoraCasadoCódigocomlivrosdeumaformadiferente

.

AscoleçõesdoJavaoferecemgrandeflexibilidadeaousuário.Aperdadeperformanceemrelaçãoàutilizaçãodearrayséirrelevante,masdeve-setomaralgumasprecauções:

Grande parte das coleções usam, internamente, um array para armazenar os seus dados.Quandoessearraynãoémaissuficiente,écriadaummaioreoconteúdodaantigaécopiado.Esteprocessopodeacontecermuitasvezes,nocasodevocêterumacoleçãoquecrescemuito.Vocêdeve,então,criarumacoleçãojácomumacapacidadegrande,paraevitaroexcessoderedimensionamento.

Eviteusarcoleçõesqueguardamoselementospelasuaordemdecomparaçãoquandonãohánecessidade.UmTreeSet gasta computacionalmenteO(log(n)) para inserir (ele utilizaumaárvorerubro-negracomoimplementação),enquantooHashSetgastaapenasO(1).

NãoiteresobreumaListutilizandoumforde0atélist.size()eusandoget(int)parareceberosobjetos.Enquantoissopareceatraente,algumasimplementaçõesdaListnãosão de acesso aleatório como a LinkedList , fazendo esse código ter uma péssimaperformancecomputacional.(useIterator)

1. Crieumcódigoqueinsira30milnúmerosnumaArrayListepesquise-os.VamosusarummétododeSystemparacronometrarotempogasto:

publicclassTestaPerformance{

publicstaticvoidmain(String[]args){System.out.println("Iniciando...");Collection<Integer>teste=newArrayList<>();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<>();

15.14PARASABERMAIS:BOASPRÁTICAS

15.15EXERCÍCIOS:COLLECTIONS

.

Oqueélento?Ainserçãode30milelementosouas30milbuscas?Descubracomputandootempogastoemcadaforseparadamente.

Adiferençaémaisquegritante.Sevocêpassarde30milparaumnúmeromaior,como50ou100mil,veráqueissoinviabilizaporcompletoousodeumaList,nocasoemquequeremosutilizá-laessencialmenteempesquisas.

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 baixo acoplamento em relação a estrutura de dados utilizada: podemostrocá-lafacilmente.

Esseéumcódigoextremamenteelegantee flexível.Como tempovocêvai repararque as pessoastentamprogramarsempresereferindoaessasinterfacesmenosespecíficas,namedidadopossível:métodos costumam receber e devolver Collections, Lists e Sets em vez de referenciardiretamente uma implementação. É o mesmo que ocorre com o uso de InputStream eOutputStream: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 comoLinkedListemrelaçã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ódigodeveficarcomosegue:

//criaomapaMap<String,Conta>mapaDeContas=newHashMap<>();

Queopçãodoctrl+1vocêescolheuparaqueeleadicionasseogenericsparavocê?

4. (opcional)Assimcomono exercício1, crieumacomparação entreArrayList 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...");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) (sabemosqueo correto seriautilizar o enhanced for ouoIterator). Para isso,insira30milelementosedepoispercorra-osusandocadaimplementaçãodeList.

Perceba que aqui o nosso intuito não é que você aprenda qual é o mais rápido, o importante éperceber que podemos tirar proveito do polimorfismo para nos comprometer apenas com a

.

interface.Depois,quandonecessário,podemostrocareescolherumaimplementaçãomaisadequadaasnossasnecessidades.

Qualdasduaslistasfoimaisrápidaparaadicionarelementosàprimeiraposição?

5. (opcional) Crie a classe Banco (caso não tenha sido criada anteriormente) no pacotebr.com.caelum.contas.modeloquepossuiumaListdeContachamadacontas.ReparequenumalistadeConta,vocêpodecolocartantoContaCorrentequantoContaPoupancaporcausadopolimorfismo.

Crie ummétodovoid adiciona(Conta c), ummétodoConta pega(int x) e outro intpegaQuantidadeDeContas(). Basta usar a sua lista e delegar essas chamadas para os métodos ecoleçõesqueestudamos.

ComoficouaclasseBanco?

6. (opcional)NoBanco,crieummétodoContabuscaPorTitular(Stringnome)queprocuraporumaContacujotitularsejaequalsaonomeDoTitulardado.

Vocêpode implementaressemétodocomumfornasua listadeConta, porémnão temumaperformanceeficiente.

Adicionandoum atributo privado do tipoMap<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étodoContabuscaPorTitular(String nomeDoTitular), basta você fazer o get no seu mapa, passandonomeDoTitularcomoargumento!

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 oequalsdequeduascontassãoequalsquandotemomesmonúmeroeagência.Felizmenteparanós, o próprio Eclipse já vem com um criador de equals e hashCode que os faz de formaconsistente.

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 agoracorretamenteemumHashSet,istoé,queelanãoguardacontascomnúmeroeagênciarepetidos.

.

Depois,removaométodohashCode.Continuafuncionando?

DominarousoeofuncionamentodohashCodeéfundamentalparaobomprogramador.

1. Gere todososnúmeros entre 1 e 1000 eordene emordemdecrescenteutilizandoumTreeSet.Comoficouseucódigo?

2. Geretodososnúmerosentre1e1000eordeneemordemdecrescenteutilizandoumArrayList.Comoficouseucódigo?

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

E se precisarmos ordernar uma lista com outro critério de comparação? Se precisarmos alterar aprópriaclasseemudarseumétodocompareTo, teremosapenasuma formade comparaçãoporvez.Precisamosdemais!

É possível definir outros critérios de ordenação usando a interface do java.util chamadaComparator . Existe um método sort em Collections que recebe, além da List , umComparatordefinindoumcritériodeordenaçãoespecífico.ÉpossívelterváriosComparators comcritériosdiferentesparausarquandofornecessário.

VamoscriarumComparatorqueserveparaordernarStringsdeacordocomseutamanho.

classComparadorPorTamanhoimplementsComparator<String>{publicintcompare(Strings1,Strings2){if(s1.length()<s2.length())return-1;

15.16DESAFIOS

JáconheceoscursosonlineAlura?

15.17PARASABERMAIS:COMPARATORS,CLASSESANÔNIMAS,JAVA8EOLAMBDA

.

if(s2.length()<s1.length())return1;return0;}}

Repare que, diferente de Comparable , o método aqui se chama compare e recebe doisargumentos,jáquequemoimplementanãoéopróprioobjeto.

Podemosdeixá-lomaiscurto,tomandoproveitodométodoestáticoauxiliarInteger.comparequecomparadoisinteiros:

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 ocomparadortambé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í,écomumescrevermosdiretamenteCollections.sort(lista,newComparadorPorTamanho()).

ReparequeaclasseComparadorPorTamanhoébempequena.Écomumhaveranecessidadedecriarvários critérios de comparação, emuitas vezes eles são utilizados apenas num único ponto do nossoprograma.

Háumaformadeescreveressaclasseeinstanciá-lanumaúnicainstrução.VocêfazissodandonewemComparator.Mascomo,sedissemosqueumainterfacenãopodeserinstanciada?RealmentenewComparator() 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){

EscrevendoumComparatorcomclasseanônima

.

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

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ânciadeComparatorqueocompare devolveInteger.compare(s1.length,l2.length).Atémesmooreturnnãoénecessário,jáquesótemosumainstruçãoapóso->.EsseéorecursodelambdadoJava8.

Uma outra novidade do Java 8 é a possibilidade de declarar métodos concretos dentro de umainterface, os chamadosdefaultmethods. Até o Java 7 não existiasort em listas. Colocar um novométodoabstratoemumainterfacepodeterconsequênciasdrásticas: todomundoqueaimplementava

EscrevendoumComparatorcomlambdanoJava8

.

paradecompilar!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,quepossuiapenasummétodo,querecebeumelementedevolveboolean.Porpossuirapenasummétodoabstrato 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

.

CAPÍTULO16

"A benevolência é sobretudo um vício do orgulho e não uma virtude da alma." -- Doantien AlphonseFranç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êmaiscomumentevaiusar,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

.

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

CasadoCódigo,LivrosdeTecnologia.

AssimcomotodoorestodasbibliotecasemJava,apartedecontroledeentradae saídadedados(conhecidocomoio)éorientadaaobjetoseusaosprincipaisconceitosmostradosatéagora:interfaces,classesabstratasepolimorfismo.

Aideiaatrásdopolimorfismonopacotejava.ioédeutilizarfluxosdeentrada(InputStream)edesaída(OutputStream)paratodaequalqueroperação,sejaelarelativaaumarquivo,aumcampoblobdobancodedados,aumaconexãoremotaviasockets,ouatémesmoàsentradaesaídapadrãodeumprograma(normalmenteotecladoeoconsole).

AsclassesabstratasInputStreameOutputStreamdefinem,respectivamente,ocomportamentopadrãodos fluxosemJava:emumfluxodeentrada,épossível lerbytese,no fluxode saída,escreverbytes.

A grande vantagem dessa abstração pode ser mostrada em ummétodo qualquer que utiliza umOutputStreamrecebidocomoargumentoparaescreveremumfluxodesaída.Paraondeométodoestáescrevendo?Nãosesabeenãoimporta:quandoosistemaprecisarescreveremumarquivoouemumasocket,bastachamaromesmométodo,jáqueeleaceitaqualquerfilhadeOutputStream!

Paralerumbytedeumarquivo,vamosusaroleitordearquivo,oFileInputStream.ParaumFileInputStreamconseguirlerumbyte,eleprecisasaberdeondeeledeveráler.Essainformaçãoétãoimportantequequemescreveuessaclasseobrigavocêapassaronomedoarquivopeloconstrutor:semissooobjetonãopodeserconstruído.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{

Seuslivrosdetecnologiaparecemdoséculopassado?

16.2ORIENTAÇÃOAOBJETOSNOJAVA.IO

16.3INPUTSTREAM,INPUTSTREAMREADEREBUFFEREDREADER

.

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 doEclipse,vaiserapartirdedentrododiretóriodoprojeto).Alternativamentevocêpodeusarumcaminhoabsoluto.

Quandotrabalhamoscomjava.io,diversosmétodoslançamIOException,queéumaexceptiondo tipo checked - o que nos obriga a tratá-la ou declará-la. Nos exemplos aqui, estamos declarandoIOExceptionatravésdaclausulathrowsdomainapenasparafacilitaroexemplo.Casoaexceptionocorra,aJVMvaiparar,mostrandoastacktrace.Estanãoéumaboapráticaemumaaplicaçãoreal:tratesuasexceptionsparasuaaplicaçãopoderabortarelegantemente.

InputStream tem diversas outras filhas, como ObjectInputStream , AudioInputStream ,ByteArrayInputStream,entreoutras.

Pararecuperarumcaractere,precisamostraduzirosbytescomoencodingdadoparaorespectivocódigounicode,issopodeusarumoumaisbytes.Escreveressedecodificadorémuitocomplicado,quemfazissoporvocêéaclasseInputStreamReader.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);intc=isr.read();}}

OconstrutordeInputStreamReaderpodereceberoencodingaserutilizadocomoparâmetro,sedesejado,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 é filha da classe abstrataReader, que possui diversas outras filhas - sãoclassesquemanipulamchars.

ApesardaclasseabstrataReader jáajudarnotrabalhodemanipulaçãodecaracteres,aindaseria

.

difícilpegarumaString.AclasseBufferedReaderéumReaderquerecebeoutroReaderpeloconstrutoreconcatenaosdiversoscharsparaformarumaStringatravé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 evitarrealizarmuitaschamadasao sistemaoperacional.Vocêpodeatéconfiguraro tamanhodobufferpeloconstrutor.

Éessaacomposiçãodeclassesqueestáacontecendo:

Essepadrãodecomposiçãoébastanteutilizadoeconhecido.ÉoDecoratorPattern.

Aqui,lemosapenasaprimeiralinhadoarquivo.OmétodoreadLinedevolvealinhaquefoilidaemuda o cursor para a próxima linha. Caso ele chegue ao fim do Reader (no nosso caso, fim doarquivo),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();}}

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.

16.4LENDOSTRINGSDOTECLADO

.

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.PodemosreceberargumentosdotipoInputStream e ter esse tipo de abstração: não importa exatamente de onde estamos lendo essepunhadodebytes,desdequeagenterecebaainformaçãoqueestamosquerendo.Comonafigura:

Repare que a ponta da direita poderia ser qualquer InputStream, seja ObjectInputStream,AudioInputStream,ByteArrayInputStream,ouanossaFileInputStream.Polimorfismo!OuvocêmesmopodecriarumafilhadeInputStream,sedesejar.

Por isso émuito comummétodos recebereme retornaremInputStream, em vez de suas filhasespecíficas. Com isso, elas desacoplam as informações e escondem a implementação, facilitando amudançaemanutençãodocódigo.Reparequeissovaiaoencontrodetudooqueaprendemosduranteoscapítulosqueapresentaramclassesabstratas,interfaces,polimorfismoeencapsulamento.

.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

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 receberumbooleanocomosegundoparâmetro,paraindicarsevocêquerreescreveroarquivooumanteroquejáestavaescrito(append).

OmétodowritedoBufferedWriternãoinsereo(s)caractere(s)dequebradelinha.Paraisso,vocêpodechamarométodonewLine.

Agoraéamelhorhoraderespirarmaistecnologia!

16.5AANALOGIAPARAAESCRITA:OUTPUTSTREAM

.

FECHANDOOARQUIVOCOMOFINALLYEOTRY-WITH-RESOURCES

Éimportantesemprefecharoarquivo.Vocêpodefazerissochamandodiretamenteométodo close do FileInputStream / OutputStream , ou ainda chamando o close doBufferedReader/Writer.Nesseúltimocaso,ocloseserácascateadoparaosobjetososquaisoBufferedReader/Writer utiliza para realizar a leitura/escrita, além dele fazer o flush dosbuffersnocasodaescrita.

Écomumefundamentalqueocloseestejadentrodeumblocofinally.Seumarquivoforesquecido aberto e a referência para ele for perdida, pode ser que ele seja fechado pelo garbagecollector,queveremosmaisa frente,porcausadofinalize.Masnãoébomvocêseprenderaisso. Se você esquecer de fechar o arquivo, no caso de um programa minúsculo como esse, oprogramavaiterminarantesqueotaldogarbagecollectorteajude,resultandoemumarquivonãoescrito(osbytes ficaramnobufferdoBufferedWriter). Problemas similares podemacontecercomleitoresquenãoforemfechados.

No Java 7 há a estrutura try-with-resources, que já fará o finally cuidar dos recursosdeclarados dentro do try(), invocando close. Pra isso, os recursos devem implementar ainterfacejava.lang.AutoCloseable,queéocasodosReaders,WriterseStreamsestudadosaqui:

try(BufferedReaderbr=newBufferedReader(newFile("arquivo.txt"))){//comexceçãoounão,oclose()dobrserainvocado}

ApartirdoJava5,temosaclassejava.util.Scanner,quefacilitabastanteotrabalhodelerdeumInputStream.Alémdisso,aclassePrintStreampossuiumconstrutorquejárecebeonomedeumarquivo como argumento.Dessa forma, a leitura do teclado com saída para um arquivo ficoumuitosimples:

Scanners=newScanner(System.in);PrintStreamps=newPrintStream("arquivo.txt");while(s.hasNextLine()){ps.println(s.nextLine());}

NenhumdosmétodoslançaIOException:PrintStreamlançaFileNotFoundExceptionsevocêoconstruirpassandoumaString.EssaexceçãoéfilhadeIOExceptioneindicaqueoarquivonãofoiencontrado.OScanner considerará que chegou ao fim se umaIOException for lançada, mas oPrintStreamsimplesmenteengoleexceptionsdessetipo.Ambospossuemmétodosparavocêverificarsealgumproblemaocorreu.

16.6UMAMANEIRAMAISFÁCIL:SCANNEREPRINTSTREAM

.

AclasseScanner é dopacotejava.util. Ela possuimétodosmuitoúteis para trabalhar comStrings, 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.

Existem duas classes chamadas java.io.FileReader e java.io.FileWriter. Elas sãoatalhosparaaleituraeescritadearquivos.

Odo{..}while(condicao);éumaalternativaparaseconstruirumlaço.Pesquise-oeutilize-ono códigopara ler umarquivo, ele vai ficarmais sucinto (vocênãoprecisará ler aprimeiralinhaforadolaço).

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

CasadoCódigo,ebookcompreçodeebook.

16.7UMPOUCOMAIS...

EditoraCasadoCódigocomlivrosdeumaformadiferente

.

Anteriormente, vimos que conseguimos ler e escrever dados emum arquivono Java utilizando aclasseScanner. Por padrão, quando fazemos essas operações, estamos trabalhando sempre com osdadosemformadeString.Maseseprecisássemoslerouescrevernúmerosinteirosemumarquivo?ComofaríamosparatransformaressesnúmerosemStringevice-versa?

Cuidado!Usamosaquiotermo"transformar",porémoqueocorrenãoéumatransformaçãoentreos tipos e sim uma forma de conseguirmos umString dado umint e vice-versa. O jeito maissimplesdetransformarumnúmeroemStringéconcatená-lodaseguintemaneira:

inti=100;Strings=""+i;System.out.println(s);

doubled=1.2;Strings2=""+d;System.out.println(s2);

Para formatar o número de uma maneira diferente, com vírgula e número de casas decimaisdevemosutilizaroutrasclassesdeajuda(NumberFormat,Formatter).

ParatransformarumaStringemnúmero,utilizamosasclassesdeajudaparaostiposprimitivoscorrespondentes. Por exemplo, para transformar a Strings em um número inteiro utilizamos ométodoestáticodaclasseInteger:

Strings="101";inti=Integer.parseInt(s);

As classes Double, Short , Long , Float etc contêm o mesmo tipo de método, comoparseDoubleeparseFloatqueretornamumdoubleefloatrespectivamente.

Essas classes também sãomuito utilizadas para fazer owrapping (embrulho) de tipos primitivoscomo objetos, pois referências e tipos primitivos são incompatíveis. Imagine que precisamos passarcomoargumentouminteiroparaonossoguardadordeobjetos.UminteironãoéumObject,comofazer?

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 recurso

16.8INTEGERECLASSESWRAPPERS(BOX)

16.9AUTOBOXINGNOJAVA5.0

.

chamadodeautoboxing,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 autoboxingdiretamenteparaObject também,possibilitandopassarum tipoprimitivoparaummétodoquereceberObjectcomoargumento:

Objecto=5;

NaclasseMath, existeumasériedemétodosestáticosque fazemoperaçõescomnúmeroscomo,por exemplo, arredondar(round), tirar o valor absoluto (abs), tirar a raiz(sqrt), calcular oseno(sin)eoutros.

doubled=4.6;longi=Math.round(d);

intx=-4;inty=Math.abs(x);

Consulteadocumentaçãoparaveragrandequantidadedemétodosdiferentes.

NoJava5.0,podemostirarproveitodoimportstaticaqui:

importstaticjava.lang.Math.*;

Issoeliminaanecessidadedeusaronomedaclasse,sobocustodelegibilidade:

doubled=4.6;longi=round(d);intx=-4;inty=abs(x);

16.10PARASABERMAIS:JAVA.LANG.MATH

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Vamossalvarascontascadastradasemumarquivoparanãoprecisarficaradicionandoascontasatodomomento.

1. NaclasseManipuladorDeContas,crieométodosalvaDadosquerecebeumEvento de ondeobteremosalistadecontas:

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 pacotebr.com.caelum.contasedeclareométodosalvaquedeverárecebera listadecontasaseremguardadas.Nestemétodovocêdevepercorreralistadecontasesalvá-lasseparandoasinformaçõesdetipo,numero,agencia,titularesaldocomvírgulas.Ocódigoficaráparecidocom:

publicclassRepositorioDeContas{

publicvoidsalva(List<Conta>contas){PrintStreamstream=newPrintStream("contas.txt");for(Contaconta:contas){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 (como

JáconheceoscursosonlineAlura?

16.11EXERCÍCIOS:JAVAI/O

.

java.io.FileNotFoundException). Utilize o devido try/catch e relance a exceção comoRuntimeException.UtilizeoquickfixdoEclipseparafacilitar(ctrl+1).

Vale lembrarquedeixar todasasexceptionspassaremdespercebidasnãoéumaboaprática!Vocêpodeusaraqui,poisestamosfocandoapenasnoaprendizadodautilizaçãodojava.io.

Quandotrabalhamoscomrecursosquefalamcomaparteexternaànossaaplicação,éprecisoqueavisemosquandoacabarmosdeusaressesrecursos.Porisso,éimportantíssimo lembrardefecharoscanaiscomoexteriorqueabrimosutilizandoométodoclose!

3. Voltando à classe ManipuladorDeContas, vamos completar o método salvaDados para queutilizeanossanovaclasseRepositorioDeContascriada.

publicvoidsalvaDados(Eventoevento){List<Conta>contas=evento.getLista("listaContas");RepositorioDeContasrepositorio=newRepositorioDeContas();repositorio.salva(contas);}

Rodesuaaplicação,cadastrealgumascontaseveja seapareceumarquivochamadocontas.txtdentrododiretóriosrcdeseuprojeto.TalvezsejanecessáriodarumF5neleparaqueoarquivoapareça.

4. (Opcional,Difícil)Vamos fazercomquealé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 chamadocarregaDados que devolva uma List<Conta>. Vamos fazer o mesmo que anteriormente eencapsularalógicadecarregamentodentrodaclasseRepositorioDeContas:

publicList<Conta>carregaDados(){RepositorioDeContasrepositorio=newRepositorioDeContas();returnrepositorio.carrega();}

Faça o código referente ao método carrega que devolve uma List dentro da classeRepositorioDeContasutilizandoaclasseScanner.ParaobterosvaloresdecadaatributovocêpodeutilizarométodosplitdaString.Lembre-sequeosatributosdascontassãocarregadosnaseguinteordem:tipo,numero,agencia,titularesaldo.Exemplo:

Stringlinha=scanner.nextLine();String[]valores=linha.split(",");Stringtipo=valores[0];

Alémdisso,acontadeveserinstanciadadeacordocomoconteúdodotipoobtido.Tambémfiqueatentopois osdados lidos virã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 odelimitereosoutrosmétodosnext.

6. (opcional) Crie uma classe TestaInteger e vamos fazer comparações com Integers dentro domain:

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áriasemumaaplicação.Precisoguardarumnúmerodecimalmuitogrande!Oquepoderiausar?

Odoubletambémtemproblemasdeprecisãoaofazercontas,porcausadearredondamentosdaaritmé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,sejaembibliotecasopensourcequevocêpodeencontrarpelainternet.

Aplicarbemosconceitosdeorientaçãoaobjetosé sempreumagrandedúvida.Semprequeremosencapsular direito, favorecer a flexibilidade, desacoplar classes, escrever código elegante e de fácilmanutençã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 certas

16.12 DISCUSSÃO EM AULA: DESIGN PATTERNS E O TEMPLATEMETHOD

.

soluçõesparaessesproblemasclássicos(nemsempremuitoelegantes).

O que fizeram foi criar soluções padrões para problemas comuns na orientação a objetos, echamaramissodeDesignPatterns, ouPadrõesdeProjeto.Oconceitovinhadaarquiteturaondeeramuitocomumteressetipodesolução.E,em1994,ganhougrandepopularidadenacomputaçãocomolivroDesign Patterns: Elements of Reusable Object-Oriented Software, um catálogo com várias dessassoluçõ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()daclassejava.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;}b[off+i]=(byte)c;}}catch(IOExceptionee){}returni;}

Discuta em aula como esse método aplica conceitos importantes da orientação a objetos epromoveflexibilidadeeextensibilidade.

.

CAPÍTULO17

"Aprimeiracoisaaentenderéquevocênãoentende."--SorenAabyeKierkegaard

Ondecontinuarao terminarosexercíciosde 'JavaeOrientaçãoaObjetos'?Aquiháumpost comsugestõesdecomoiniciarnacarreira:

http://blog.caelum.com.br/como-posso-aprender-java-e-iniciar-na-carreira/

Evocêpodeseguirnessescursoseáreas:

UmdosprincipaisusosdoJavaérodaraplicaçõesweb.EntramaquitecnologiascomoServlets,JSPseferramentasfamosasdomercado,comooStruts.

A Caelum oferece o curso FJ-21, onde você pode estudar os tópicos necessários para começar atrabalharcomJavanawebusandoasmelhorespráticas,designpatternsetecnologiasdomercado.Essaapostilatambémestádisponívelparadownload.

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

CasadoCódigo,ebookcompreçodeebook.

A melhor maneira para fixar tudo o que foi visto nos capítulos anteriores é planejar e montar

EAGORA?

17.1WEB

EditoraCasadoCódigocomlivrosdeumaformadiferente

17.2PRATICANDOJAVAEUSANDOBIBLIOTECAS

.

pequenos sistemas. Pense na modelagem de suas classes, como e onde usar herança, polimorfismo,encapsulamentoeoutrosconceitos.PratiqueousodasAPIsmaisúteisdo Java integrando-asao seussistemas.

O curso FJ-22 é um laboratório que alémde demonstrar o uso diversasAPIs e boas prá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

.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

JáconheceoscursosonlineAlura?

.

CAPÍTULO18

"Oúnicolugarondeosucessovemantesdotrabalhoénodicionário."--AlbertEinstein

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

executartarefassimultaneamente;colocartarefasparaaguardaratéqueumdeterminadoeventoocorra;entenderofuncionamentodoGarbageCollector.

Emvárias situações, precisamos "rodarduas coisas aomesmo tempo". ImagineumprogramaquegeraumrelatóriomuitograndeemPDF.Éumprocessodemoradoe,paradaralgumasatisfaçãoparaousuário,queremosmostrarumabarradeprogresso.QueremosentãogeraroPDFeaomesmotempoatualizarabarrinha.

Pensando um pouco mais amplamente, quando usamos o computador também fazemos vá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.

EmJava,usamosaclasseThreaddopacotejava.langparacriarmoslinhasdeexecuçãoparalelas.AclasseThreadrecebecomoargumentoumobjetocomocódigoquedesejamosrodar.Porexemplo,noprogramadePDFebarradeprogresso:

publicclassGeraPDF{

APÊNDICE-PROGRAMAÇÃOCONCORRENTEETHREADS

18.1THREADS

"Duastarefasaomesmotempo"

ThreadsemJava

.

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 sabequedeve chamarométodoroda?Comoelasabequenomedemétododaremosequeeladevechamaressemétodoespecial?FaltanaverdadeumcontratoentreasnossasclassesaseremexecutadaseaclasseThread.

EssecontratoexisteeéfeitopelainterfaceRunnable:devemosdizerquenossaclasseé"executável"e que segue esse contrato. Na interface Runnable, há apenas um método chamado run. Bastaimplementá-lo,"assinar"ocontratoeaclasseThreadjásaberáexecutarnossaclasse.

publicclassGeraPDFimplementsRunnable{publicvoidrun(){//lógicaparageraropdf...}}

publicclassBarraDeProgressoimplementsRunnable{publicvoidrun(){//mostrabarradeprogressoevaiatualizandoela...}}

AclasseThread recebe no construtor umobjeto que éumRunnable, e seumétodo startchamaométodorundanossaclasse.ReparequeaclasseThreadnãosabequaléotipoespecíficodanossaclasse;paraela,bastasaberqueaclassesegueocontratoestabelecidoepossuiométodorun.

Éobomusodeinterfaces,contratosepolimorfismonaprática!

.

ESTENDENDOACLASSETHREAD

A classe Thread implementa Runnable . Então, você pode criar uma subclasse dela ereescreverorunque,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,queseriaagrandevantagem.PrefiraimplementarRunnableaherdardeThread.

DORMINDO

Paraque a threadatualdurmabasta chamarométodoa seguir,por exemplo,paradormir3segundos:

javaThread.sleep(3*1000);

.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

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();

SaberinglêsémuitoimportanteemTI

18.2ESCALONADORETROCASDECONTEXTO

.

}}

Serodarmosesseprograma,qual será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ão sabemos exatamentequal é a saída.Rodeoprogramavárias vezes eobserve: emcadaexecuçãoasaídaéumpoucodiferente.

Oproblemaéquenocomputadorexisteapenasumprocessadorcapazdeexecutarcoisas.Equandoqueremosexecutarváriascoisasaomesmotempo,eoprocessadorsóconseguefazerumacoisadecadavez?Entraemcenaoescalonadordethreads.

O escalonador (scheduler), sabendo que apenas uma coisa pode ser executada de cada vez, pegatodasas threadsqueprecisamser executadas e fazoprocessador ficar alternandoa execuçãodecadauma delas. A ideia é executar um pouco de cada thread e fazer essa troca tão rapidamente que aimpressãoqueficaéqueascoisasestãosendofeitasaomesmotempo.

Oescalonadoréresponsávelporescolherqualapróximathreadaserexecutadaefazeratrocadecontexto (context switch).Eleprimeiro salvaoestadodaexecuçã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é importantequedeterminadacoisaseja feitaantesdeoutra,entãonãoestamos falandodeexecuçõ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)funcionacomoumaThread responsávelpor jogarfora todos os objetos que não estão sendo referenciados por nenhum outro objeto - seja demaneiradiretaouindireta.

Considereocódigo:

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.Esseobjeto jánãoémaisacessível.Temos,então,apenasumobjetoemmemória?Nãopodemosafirmarisso!ComooGarbageCollectoréumaThread,vocênãotemgarantiadequandoelevairodar.Vocêsósabeque,emalgummomentonofuturo,aquelamemóriavaiserliberada.

Algumaspessoascostumamatribuirnullaumavariável,comointuitodeacelerarapassagemdoGarbageCollectorporaqueleobjeto:

for(inti=0;i<100;i++){Listx=newArrayList();//fazalgumascoisascomaarraylistx=null;}

18.3GARBAGECOLLECTOR

.

Isso rarissimamente é necessário. O Garbage Collector age apenas sobre objetos, nunca sobrevariáveis.Nessecaso,avariávelxnãoexistirámaisacadaiteração,deixandoaArrayListcriadasemnenhumareferênciaparaela.

SYSTEM.GC()

Vocênunca consegue forçar oGarbageCollector,mas chamandoométodo estáticogc daclasseSystem, você está sugerindo que a Virtual Machine rode o Garbage Collector naquelemomento.Sesuasugestãovaiseraceitaounão, istodependedeJVMparaJVM,evocênãotemgarantias. Evite o uso destemétodo.Você não deve basear sua aplicação em quando oGarbageCollectorvairodarounão.

FINALIZER

A classe Object define também ummétodo finalize, que você pode reescrever. Essemé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 paraliberar recursos "caros"comoconexões, threadse recursosnativos. Issodeve serutilizadoapenasporseguranç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){

18.4EXERCÍCIOS

.

Programap1=newPrograma();p1.setId(1);

Threadt1=newThread(p1);t1.start();

Programap2=newPrograma();p2.setId(2);

Threadt2=newThread(p2);t2.start();

}}

RodeváriasvezesaclasseTesteeobserveosdiferentesresultadosemcadaexecução.Oquemuda?

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

É 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:

AprendasedivertindonaAluraStart!

18.5EASCLASSESANÔNIMAS?

.

Runnabler=newPrograma1();Threadt=newThread(r);t.start();

Em vez de criar essa classe Programa1, podemos utilizar o recurso de classe anônima. Ela nospermitedarnewnumainterface,desdequeimplementemosseusmétodos.Comisso,podemoscolocardiretamentenomain:

Runnabler=newRunnable(){publicvoidrun(){for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}};Threadt=newThread(r);t.start();

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, acessaratributos 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 interfacefuncional(contémapenasummétodoabstrato),elapodeserfacilmenteescritadessaforma:

Runnabler=()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);};Threadt=newThread(r);t.start();

A sintaxepode serumpouco estranha.Comonãoháparâmetros a serem recebidospelométodorun, usamoso() para indicar isso.Vale lembrar,maisumavez, queno lambdanãoprecisamosescreveronomedométodoqueestamos implementando,nonossocasoorun. Isso é possível poisexisteapenasummétodoabstratonainterface.

Querdeixarocódigomaisenxutoainda?PodemospassarolambdadiretamenteparaoconstrutordeThread,semcriarumavariáveltemporária!Elogoemseguidachamarostart:

newThread(()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}).start();

EcomlambdadoJava8?

.

Obviamente o uso excessivo de lambdas e classes anônimas pode causar uma certa falta delegibilidade.Você deve lembrar que usamos esses recursos para escrever códigosmais legíveis, e nãoapenas para poupar algumas linhas de código.Caso nossa implementação do lambda venha a ser deváriaslinhas,éumfortesinaldequedeveríamosterumaclasseapartesomenteparaela.

.

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.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Da necessidade de dois computadores se comunicarem, surgiram diversos protocolos quepermitissemtaltrocadeinformação:oprotocoloquevamosusaraquiéoTCP(TransmissionControlProtocol).

AtravésdoTCP,épossívelcriarumfluxoentredoiscomputadores-comoémostradonodiagrama

APÊNDICE-SOCKETS

19.1MOTIVAÇÃO:UMAAPIQUEUSAOSCONCEITOSAPRENDIDOS

JáconheceoscursosonlineAlura?

19.2PROTOCOLO

.

abaixo:

É 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 usar TCP, em vez de criar nosso próprio protocolo de bytes, é que oTCP vaigarantir 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?

Todas as aplicações que estão enviando e recebendodados fazem isso através damesma conexãofísica, mas o computador consegue discernir, durante a chegada de novos dados, quais informaçõespertencemaqualaplicação.Mascomo?

19.3PORTA

.

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 formaro endereçodaaplicação.Por exemplo,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.

19.4SOCKET

.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Iniciandoummodelodeservidordechat,oserviçodocomputadorquefuncionacomobasedeve,primeiro,abrirumaportaeficarouvindoatéalguémtentarseconectar.

importjava.net.*;

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");//acontinuaçãodoservidordeveserescritaaqui

}}

Seoobjeto for realmente criado, significaque aporta 12345 estava fechada e foi aberta. Seoutroprogramapossuiocontroledestaportanesteinstante,énormalqueonossoexemplonãofuncione,poiselenãoconsegueutilizarumaportaquejáestáemuso.

Após abrir a porta, precisamos esperar por um cliente através do método accept daServerSocket.Assimqueumclienteseconectar,oprogramacontinuará,porissodizemosqueessemétodoéblocante,seguraathreadatéquealgoonotifique.

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());//imprimeoipdocliente

Porfim,bastalertodasasinformaçõesqueoclientenosenviar:

SaberinglêsémuitoimportanteemTI

19.5SERVIDOR

.

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());while(s.hasNextLine()){System.out.println(s.nextLine());}

s.close();servidor.close();cliente.close();}}

Anossatarefaécriarumprogramaclientequeenviemensagensparaoservidor...oclienteéaindamaissimplesdoqueoservidor.

O código a seguir é a parte principal e tenta se conectar a um servidorno IP 127.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),e jogá-lasnobufferdesaída:

PrintStreamsaida=newPrintStream(cliente.getOutputStream());

19.6CLIENTE

.

Scannerteclado=newScanner(System.in);while(teclado.hasNextLine()){saida.println(teclado.nextLine());}saida.close();teclado.close();

Reparequeusamosos conceitodejava.io aquinovamente, para leiturado teclado e enviodemensagensparaoservidor.ParaasclassesScannerePrintStream, tantofazdeondequese lêouescreveosdados:oimportanteéqueessestreamsejaumInputStream/OutputStream.Éopoderdasinterfaces,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());

while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();cliente.close();}}

Paratestarosistema,precisamosrodarprimeirooservidore,logodepois,ocliente.Tudooquefordigitadonoclienteseráenviadoparaoservidor.

.

MULTITHREADING

Paraqueoservidorsejacapazdetrabalharcomdoisclientesaomesmotempoé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();

}

AsocketdoclientetemumInputStream,querecebedoOutputStreamdoservidor,e temumOutputStream, que transfere tudo para o InputStream do servidor. Muito parecido com umtelefone!

Reparequeclienteeservidorsãorótulosqueindicamumestado.Ummicro(oumelhor,umaJVM)podeserservidornumcaso,maspodeserclienteemoutrocaso.

19.7IMAGEMGERAL

.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

1. Crieumprojetosockets.

Vamosfazerumpequenosistemaemquetudoqueédigitadonomicroclienteacabaaparecendonomicroservidor.Istoé,apenasumacomunicaçãounidirecional.

CrieaclasseServidorcomovimosnessecapítulo.AbusedosrecursosdoEclipseparanãoterdeescrevermuito!

packagebr.com.caelum.chat;

importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Scanner;

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();}}

AprendasedivertindonaAluraStart!

19.8EXERCÍCIOS:SOCKETS

.

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. RodeaclasseServidor:reparenoconsoledoEclipsequeoprogramaficaesperando.RodeaclasseCliente:aconexãodeveserfeitaeoEclipsedevemostrarosdoisconsolesparavocê(existeumpequenoíconenaviewdeConsoleparavocêalternarentreeles).

Digitemensagensnoclienteevejaseelasaparecemcorretamentenoservidor.

4. Testeseuprogramacomumcolegadocurso,usandocomunicaçãoremotaentreasduasmáquinas.Combinementresiquemvairodaroclienteequemvairodaroservidor.Quemforrodaroclientedeve 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çaocliente lerdeumarquivochamadoarquivo.txt (crie-o!)e faça

.

comqueoservidorgravetudoquerecebenumarquivoquechamarecebido.txt.

Quandooservidoraceitaumclientecomachamadaaoaccept, ele poderia chamarnovamenteeste método para aceitar um novo cliente. E, se queremos aceitar vários clientes, simultâneos, bastachamaroacceptváriasvezesetratarcadaclienteemsuaprópriaThread(senãoométodoacceptnã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.Logodepoisqueoservidoraceitarumcliente novo, crie um PrintStream usando o OutputStream dele e adicione na lista. E, quandoreceberumamensagemnova,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);

19.9DESAFIO:MÚLTIPLOSCLIENTES

19.10DESAFIO:BROADCASTDASMENSAGENS

.

}}

Masnossoclientetambémrecebemensagens.EntãoprecisamosfazercomqueoCliente,alémdelermensagensdotecladoeenviarparaoservidor,simultaneamentetambémpossarecebermensagensdeoutrosclientesenviadaspeloservidor.

Ouseja,precisamosdeumasegundaThreadnaclasseClientequeficarecebendomensagensdoInputStreamdoservidoreimprimindonoconsole.

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çacomoaprimeiralinhaenviadapeloclientesejasempreonickdele.Equandooservidorenviaramensagem,façaeleenviaronickdecadaclienteantesdamensagem.

Equandoumclientedesconectar?Comoretirá-lodalista?

Édifícil fazeroenviodearquivospelonossosistemadechats?Sabendoquea leituradeumarquivo é feita pelo FileInputStream , seria difícil mandar esse InputStream peloOutputStreamdaconexãoderede?

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

19.11SOLUÇÃODOSISTEMADECHAT

.

Umasoluçãoparao sistemadechatcliente-servidorcommúltiplosclientespropostonosdesafiosacima. Repare que a solução não está nem um pouco elegante: o main já faz tudo, além de nãotratarmosasexceptions.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êmsgsdotecladoemandaproservidorScannerteclado=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ávelporcuidardecadaclienteconectadonosistema:

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);

//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();}}

.

CAPÍTULO20

"Quempoucopensa,engana-semuito."--LeonardodaVinci

OusodeThreadscomeçaaficarinteressanteecomplicadoquandoprecisamoscompartilharobjetosentreváriasThreads.

Imagineaseguintesituação: temosumBancocommilhõesdeContasBancárias.Clientessacamedepositamdinheiro continuamente, 24 horas por dia.No primeiro dia de cadamês, o Banco precisaatualizar o saldo de todas as Contas de acordo com uma taxa específica. Para isso, ele utiliza oAtualizadorDeContasquevimosanteriormente.

OAtualizadorDeContas,basicamente,pegaumaaumacadaumadasmilhõesdecontasechamaseumétodoatualiza.Aatualizaçãodemilhõesdecontaséumprocessodemorado,quedurahoras;éinviávelpararobancoportantotempoatéqueasatualizaçõestenhamcompletado.Éprecisoexecutarasatualizaçõesparalelamenteàsatividades,dedepósitosesaques,normaisdobanco.

Ouseja,teremosváriasthreadsrodandoparalelamente.Emumathread,pegamostodasascontasevamoschamandoométodoatualizadecadauma.Emoutra,podemosestarsacandooudepositandodinheiro.Estamoscompartilhandoobjetosentremúltiplasthreads(ascontas,nonossocaso).

Imagineaseguintepossibilidade(mesmoquemuitoremota):noexatoinstanteemqueoatualizadorestáatualizandoumaContaX,oclientedonodestaContaresolveefetuarumsaque.Comosabemos,aotrabalharcomThreads,oescalonadorpodepararumacertaThreadaqualquer instanteparaexecutaroutra,evocênãotemcontrolesobreisso.

VejaessaclasseConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){doublesaldoAtualizado=this.saldo*(1+taxa);

APÊNDICE-PROBLEMASCOMCONCORRÊNCIA

20.1THREADSACESSANDODADOSCOMPARTILHADOS

.

this.saldo=saldoAtualizado;}

publicvoiddeposita(doublevalor){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}

ImagineumaContacomsaldode100reais.Umclienteentranaagênciaefazumdepósitode1000reais.IssodisparaumaThreadnobancoquechamaométododeposita();elecomeçacalculandoonovoSaldo que passa a ser 1100 (linha 13). Só que por algum motivo que desconhecemos, oescalonadorpáraessathread.

Nesteexatoinstante,elecomeçaaexecutarumaoutraThreadquechamaométodoatualizadamesmaConta,porexemplo,comtaxade1%.IssoquerdizerqueonovoSaldopassaavaler101reais(linha8).E,nesseinstanteoescalonadortrocadeThreadsnovamente.Eleexecutaalinha14naThreadquefaziaodepósito;osaldopassaavaler1100.Acabandoodeposita,oescalonadorvoltapraThreaddoatualizaeexecutaalinha9,fazendoosaldovaler101reais.

Resultado:odepósitodemilreaisfoitotalmenteignoradoeseuClienteficarápoucofelizcomisso.Perceba quenão é possível detectar esse erro, já que todo o código foi executadoperfeitamente, semproblemas.Oproblema,aqui,foioacessosimultâneodeduasThreadsaomesmoobjeto.

EoerrosóocorreuporqueoescalonadorparounossasThreadsnaquelesexatos lugares.Podeserquenossocódigofiquerodando1anosemdarproblemaalgumeemumbelodiaoescalonadorresolvealternar nossas Threads daquela forma. Não sabemos como o escalonador se comporta! Temos queprotegernossocódigocontraesse tipodeproblema.Dizemosqueessaclassenãoé threadsafe, issoé,nãoestáprontaparaterumainstânciautilizadaentreváriasthreadsconcorrentemente.

OquequeríamoseraquenãofossepossívelalguématualizaraContaenquantooutrapessoaestádepositandoumdinheiro.QueríamosqueumaThreadnãopudessemexeremumaConta enquantooutraThreadestámexendonela.Nãohácomoimpediroescalonadordefazertalescolha.Então,oquefazer?

.

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

CasadoCódigo,LivrosdeTecnologia.

Uma ideia seria criar uma trava e, no momento em que uma Thread entrasse em um dessesmé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 em cimadesse objeto, isto é, se umaThread entrar emumbloco que foi definido comosincronizadoporesse lock,apenasumaThreadpoderáestar ládentroaomesmotempo,poisachaveestarácomela.

Apalavrachavesynchronizeddáessacaracterísticaaumblocodecódigoerecebequaléoobjetoqueseráusadocomochave.AchavesóédevolvidanomomentoemqueaThreadquetinhaessachavesair do bloco, seja por return ou disparo de uma exceção (ou ainda na utilização do métodowait())..

Queremos,então,bloquearoacessosimultâneoaumamesmaConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){synchronized(this){doublesaldoAtualizado=this.saldo*(1+taxa);this.saldo=saldoAtualizado;

Seuslivrosdetecnologiaparecemdoséculopassado?

20.2CONTROLANDOOACESSOCONCORRENTE

.

}}

publicvoiddeposita(doublevalor){synchronized(this){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}}

Observeousodosblocossynchronized dentrodosdoismétodos.Eles bloqueiamumaThreadutilizandoomesmoobjetoConta,othis.

Essesmétodossãomutuamenteexclusivosesóexecutamdemaneiraatômica.Threadsquetentampegarumlockquejáestápego,ficarãoemumconjuntoespecialesperandopelaliberaçãodolock(nãonecessariamentenumafila).

SINCRONIZANDOOBLOCOINTEIRO

Écomumsempresincronizarmosummétodointeiro,normalmenteutilizandoothis.

publicvoidmetodo(){synchronized(this){//conteúdodometodo}}

Paraestemesmoefeito,existeumasintaxemaissimples,ondeosynchronizedpodeserusadocomomodificadordomé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.3VECTOREHASHTABLE

.

Duas collections muito famosas são Vector e Hashtable, a diferença delas com suas irmãsArrayListeHashMapéqueasprimeirassãothreadsafe.

Vocêpodeseperguntarporquenãousamossempreessasclassesthreadsafe.Adquirirumlocktemumcusto,ecasoumobjetonãováserusadoentrediferentesthreads,nãoháporqueusaressasclassesqueconsomemmaisrecursos.Masnemsempreéfácilenxergarsedevemossincronizarumbloco,ousedevemosutilizarblocossincronizados.

Antigamenteocustodeseusar lockseraaltíssimo,hojeemdia issocustapoucoparaaJVM,masnãoémotivoparavocêsincronizartudosemnecessidade.

VocêpodemudaraprioridadedecadaumadesuasThreads,masistotambéméapenasumasugestãoaoescalonador.

ExisteummétodostopnasThreads,porquenãoéboapráticachamá-lo?

Um tópicomais avançado é a utilização dewait,notifiy e notifyAll para que asThreadscomuniquem-sedeeventosocorridos,indicandoquepodemounãopodemavançardeacordocomcondições

O pacote java.util.concurrent foi adicionado no Java 5 para facilitar o trabalho naprogramação concorrente. Ele possui uma série de primitivas para que você não tenha detrabalhardiretamentecomwaitenotify,alémdeterdiversascoleçõesthreadsafe.

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

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Exercícios só recomendados se você já tinha algum conhecimento prévio de programação

20.4UMPOUCOMAIS...

Agoraéamelhorhoraderespirarmaistecnologia!

20.5EXERCÍCIOSAVANÇADOSDEPROGRAMAÇÃOCONCORRENTEELOCKS

.

concorrente,locks,etc.

1. Vamosenxergaroproblemaaoseusarumaclassequenãoéthread-safe:aArrayListporexemplo.

Imaginequetemosumobjetoqueguardatodasasmensagensqueumaaplicaçãodechatrecebeu.VamosusarumaArrayList<String> para armazená-las.Nossa aplicação émulti-thread, entãodiferentes threads vão inserir diferentesmensagens para serem registradas.Não importa a ordemqueelassejamguardadas,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();

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.

.

CAPÍTULO21

"Quempoucopensa,engana-semuito."--LeonardodaVinci

Como vimos antes, aVM é apenas uma especificação e devemos baixar uma 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"yuminstalljava-1.7.0-openjdk".

SevocêjátiveroutrasversõesinstaladasnoseuUbuntu,podeutilizarsudoupdate-alternatives--configjavaparaescolherentreelas.

Umainstalaçãomaisbraçal,semusarrepositório ,podeserfeitabaixandooinstaladornoprópriosite da Oracle. É um tar.gz que possui um .bin que deve ser executado. Depois, é necessário

APÊNDICE-INSTALAÇÃODOJAVA

21.1INSTALANDONOUBUNTUEEMOUTROSLINUX

.

apontarJAVA_HOMEparaessediretórioeadicionarJAVA_HOME/binnoseuPATH.

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

CasadoCódigo,ebookcompreçodeebook.

OMacOSXjátrazoJavainstaladojuntocomosistemaoperacionalatéaversão10.6.Asversõesmaisnovas,doLionemdiante,o instaladordoMacvaiperguntar sevocêdesejabaixá-loquando forrodarsuaprimeiraaplicaçã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/

EditoraCasadoCódigocomlivrosdeumaformadiferente

21.2NOMACOSX

21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS

.

Dêumcliqueduplonoarquivojdk-<versão>-windows-i586-p.exeeespereatéeleentrarnowizarddeinstalação.

AceiteospróximosdoispassosclicandoemNext.Apósumtempo,o instaladorpediráparaescolher emquediretório instalaroSDK.Pode serondeele jáoferececomopadrão.Anotequalfoiodiretórioescolhido,vamosutilizaressecaminhomaisadiante.Acópiadearquivosiniciará:

Instalação

.

O instalador instalará também o JavaFX 2. Após isso, você será direcionado à uma páginaondevocêpode,opcionalmente,criarumacontanaOraclepararegistrarsuainstalação.

Precisamosconfiguraralgumasvariáveisdeambienteapósainstalação,paraqueocompiladorsejaacessível via linha de comando. Caso você vá utilizar diretamente o Eclipse, provavelmente não seránecessáriorealizaressespassos.

CliquecomobotãodireitoemcimadoíconeComputadoreselecioneaopçãoPropriedades.

Escolhaaaba "ConfiguraçõesAvançadasdeSistema"edepois cliquenobotão "VariáveisdeAmbiente"

Configurandooambiente

.

Nesta tela, você verá, na parte de cima, as variáveis de ambiente do usuário corrente e,embaixo,asvariáveisdeambientedocomputador(servemparatodososusuários).CliquenobotãoNovo...dapartedebaixo.

EmNomedaVariáveldigiteJAVA_HOMEe,emvalordavariável,digiteocaminhoquevocê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ánomesmo),ecliquenobotãodebaixo"Editar".

.

Não altere o nome da variável! Deixe como está e adicione no final do valor;%JAVA_HOME%\bin,nãoesqueçadoponto-e-vírgula-assim,vocêestáadicionandomaisumcaminhoàsuavariávelPath.

Abraoprompt,indoemIniciar,Executaredigitecmd.

Noconsole,digitejavac-version.OcomandodevemostraraversãodoJavaCompilerealgumasopções.

VocêpodeseguirparaainstalaçãodoEclipse,conformevistonoseucapítulo,ouutilizarumeditordetextosimplescomooblocodenotasparaosprimeiroscapítulosdeapostila.

Qualquerdúvida,nãohesitedepostá-lanoGrupodeUsuáriosJava:

http://www.guj.com.br.

.

CAPÍTULO22

"Olhoporolho,eomundoacabarácego."--MohandasGandhi

Debugging(emportuguês,depuraçãooudepurar)éumprocessodereduzirouencontrarbugsnoseusistema.Deumaformageral,debuggingnãoéumatarefa fácildeserexecutada.Muitasvariaçõ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.Veremosqueelas sãonecessáriasnoscasosquenossos testesdeunidadede loggingnão foramsuficientesparaencontrararazãodeumproblema.

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

Business!Ex-alunodaCaelumtem15%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éamelhorhoraderespirarmaistecnologia!

22.2DEBUGANDONOECLIPSE

.

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, imaginequedesejamosdebugaro comportamentodométodosaca daclasseConta,mais especificamentedoif que verifica se saldo émenorqueo valor a 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{publicstaticvoidmain(String[]args){Contaconta=newConta();conta.saca(200);}}

.

O processo normal para executarmos esse código seria clicar no menu Run -> 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 casosmuito

22.3PERSPECTIVADEDEBUG

.

específicos.

Dentro da perspectiva de debug, temos uma aba chamada Variables. São exibidas todas asvariáveisencontradasdentrodocódigoquevocêestádebugando.Porexemplo,nodebugquefizemosserãoexibidasasvariáveisdométodosaca,nestecaso,valor.Alémdosatributosde instânciadoobjeto.

Podemosexibirmais informaçõessobreasvariáveis,bastaadicionarmosascolunasquedesejamosnatabelaexibida.

.

Épossíveltambémadicionarmosconstantesevariáveisestáticasdaclassequeestásendodebugada.

.

NaabaBreakpointssãoexibidostodososbreakpointsqueseuworkspacepossui.Masporqueissoéimportante?Éimportanteporquepodemosvertodosospontosdedebugpresentesemelhor,podemosdesabilitá-los um a um ou todos de uma só vez. Você pode até mesmo pedir para exportar osbreakpoints.

Paradesabilitar ouhabilitar todosbreakpoints basta clicarmosno íconeSkipAllBreakpoints. Sequisermosdesabilitarumaum,bastadesmarcarocheckboxeobreakpointserádesativado.Àsvezes,encontrarocódigoondeobreakpointfoicolocadopodesercomplicado,naabaBreakpointsissoficabemfácildefazer,bastadarumduplocliquenobreakpointeoeclipseautomaticamentenosmostraaclasse"dona"dele.

Quandoestamosdebugandocódigo,muitasvezeséinteressantesaberovalordealgumaexpressãooumétodo.Porexemplo,umacondiçãodentrodeumif,this.saldo>valor.Essevalornãoestáemumavariável,eleestáemumaexpressão,oquepodetornarsaberovalordelacomplicado.Afeaturede Expressions descomplica esse processo para nós. Na perspectiva de Debug temos a abaExpressions.Bastaclicarcomodireitodentrodaaba,eclicaremAddExpression:

.

Eoresultadodaexpressãoéexibido.

TemosoutraabaimportantechamadadeDebug.Dentreasfunçõesdelaestão:

Threads-Exibeasthreadsqueestãosendoexecutadas,emelhor,mostraqualthreadefetuouachamadaparaométodoondeestáodebug.Alémdissomostraapilhadeexecução,oquenospermitevoltarachamadadeummétodoBarradenavegação-Quepermitealterarmososcaminhosqueodebugseguirá.

.

Alistaaseguirmostraralgumasteclasebotõesquealteramocaminhonaturaldosnosssdebug:

F5 - Vai para o próximo passo do seu programa. Se o próximo passo for ummétodo, eleentraránocódigoassociado;F6 -Tambémvaiparaopróximopasso,porémseopróximopasso forummétodo,elenãoentraránocódigoassociado;F7-Voltaráemostraráométodoquefezachamadaparaocódigoqueestásendodebugado.NonossocasovoltaráparaométodomaindaclasseTestaConta;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.

22.4DEBUGAVANÇADO

.

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,porexemplo.

.

Obreakpoint, neste caso, somente será ativadoquandoo argumentovalor que foi passado aométodosaca formaior que 100.O importante aqui énotarmosquedevemos retornar sempre umvalorbooleano,senãoofizermos, teremosumerroemtempodeexecução.EssapropriedadeéválidaquandoqueremoscolocaraquelesfamososSystem.out.println("entrounoiftal")paraefeitode log, podemos fazer isso colocando o log dentro da expressão condicional nas propriedades dobreakpoint.

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,instanciarobjetosdessaclasse,utilizarif's,for's,while's,todososrecursosdoJava,alémdepoderutilizarasvariáveis,métodos,constantesdaclassequeestamosdebugando.

Umexemploclássicoéquandoestamosemdebuggingequeremossaberoretornodealgummétododoqualnãotemosacesso,oquefaríamosantesseriacolocarumamontoadodeSystem.out.println,poluindo extremamente nosso código.Nodisplay o que fazemos é efetuar a chamadadesse código eautomaticamenteosresultadossãoexibidos.

Para vermos um efeito real disso, vamos alterar umpouco o comportamento da classeConta, demodoqueagoraosaldoparasaquetenhaqueserosaldorealmaisovalordolimite.Nossocódigofica

.

assim:

publicclassConta{

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;}}

Reparequeoif queverifica seo saldoé suficienteparaefetuarmoso saquechamaummétodoisSaldoSuficiente,oquepodeserumproblemaquandoestamosdebugando,afinalacondiçãodoiféummétodo.SeutilizarmosodisplaypodemosfazerachamadadométodoisSaldoSuficiente,verseuresultadoeomelhor,nãoafetamosodebug,apenasqueremosveroresultadodométodo,porexemplo.

Para exibirmos a abaDisplay é bem simples. TecleCtrl+ 3, digiteDisplay e a aba será exibida.Quandorodarmosnossocódigoemmododebug,podemosirnodisplay,digitarmosumachamadaparaométodoisSaldoSuficiente, executamos esse código que foi digitado selecionando-o dentro dodisplayeteclandoCtrl+Shift+Deoresultadoseráimpresso,assimcomonaimagemabaixo:

.

Muitasvezesqueremos "seguir"algumavariávelde instância,ouseja,qualquerchamadaparaessavariável(leituraouescrita)queremossernotificadosdisso.Podemosusarowatchpoint,quefaránossoprogramaentraremmododebug,quandoqualqueralteraçãonavariávelqueestamosseguindoocorrer,oprogramaentraráemdebugexatamentenalinhaquefezaalteração.Paracolocarmosumwatchpoint,bastadarumduplocliquenoatributodeinstânciaquedesejacolocá-lo.

.

Épossívelalteraressecomportamentopadrão,edefinirsevocêquerqueowatchpointsejaativadoparaleituraousomenteparaescrita.

.

Aidé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:

publicclassTestaConta{publicstaticvoidmain(String[]args){Contaconta=null;conta.saca(10);}}

Quando rodarmos o código acima, teremos uma NullPointerException. Pode ser útil nessescasosdebugaresaberondeaexceçãoestáocorrendodefato,emquallinhamaisespecificamente.Parafazermos isso podemos criar um Exception Breakpoint, que debugará códigos que eventualmentelancemumaNullPointerException,porexemplo.BastaabrirmosaabaBreakpointseclicarmosnoíconeabaixo:

.

Seráabertaumajanelaondepodemosbuscarporumaexceçãoespecífica.

Podemosdefinirumbreakpointqueé ativadoouantesoudepoisqueométodoé chamado.Paradefinirmosele,bastaestaremqualquerpartedométodoquedesejamosdebugar,clicarnomenuRun->ToogleMethodBreakpoint.Podemoseditaraspropriedadesdessebreakpointdizendosequeremosqueele seja ativado antes(default) ou depois da execução do método. Basta acessar as propriedades domethodbreakpointealterá-las.

.

Éutilquandodesejamosqueumbreakpointsejaativadoquandoumaclasseespecíficaforcarregadapelaprimeiravez, chamamosessebreakpointdeClassBreakpoint. Basta clicarmosnomenuRun ->AddClassLoadBreakpoint,umajanelaseráabertaebastadigitarmosonomedaclasseeadicionarmos:

.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessã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".

Umadasferramentasquenosauxiliamnaquestãodenãootimizarnossocódigoprematuramente,sãoas ferramentasdeprofiling,que tornamaparentes,porexemplo,osproblemasdememóriaecpu,quepodemfazercomqueotimizemosnossocódigo.Atualmentedevidoastécnicasqueutilizamosparaentregaralgodevalorparaocliente,focamosprincipalmentenaqualidade,aspectosfuncionais,testes,etc.Porém,muitosproblemasquenão fazempartedosrequisitos funcionaispodemacontecerapenasquandoaaplicaçãoestáemprodução,nestepontoasferramentasdeprofilingtambémnosajudam.

JuntamentecomoEclipsetemosaopçãodeinstalareutilizarumaferramentadeprofilingconhecidacomoEclipseTPTP(EclipseTest&PerformanceToolsPlatform),quenosforneceopçõesparaisolareidentificarproblemasdeperformance,taiscomo:memória(memoryleak),recursoseprocessamento.OTPTPnospermiteanalisardesimplesaplicaçõesjavaatéaplicaçõesquerodamemmúltiplasmáquinaseemmúltiplasplataformas.

EditoraCasadoCódigocomlivrosdeumaformadiferente

22.5PROFILING

22.6PROFILINGNOECLIPSETPTP

.

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é utilizandooUpdate Site doEclipse que resolve as possíveis dependências e nos possibilita escolherquaisfeaturesqueremosinstalar.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 queacabamosdeadicionareaversã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ãoconhecema fundo,éaquestãodopooldeStringsquepodeeventualmenteficarmuitogrande.Esteproblemapodesercausado

.

porqueobjetosdotipoStringsãoimutáveis,sendoassim,sefizermosconcatenaçõesdeStringsmuitasvezes,cadaumadessasconcatenaçõesproduziráumanovaString,queautomaticamenteserácolocadanopooldaJVM.

A alternativa neste caso, seria trabalhar com objetos do tipo StringBuilder ou StringBuffer quefuncionam 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.

.