Escolar Documentos
Profissional Documentos
Cultura Documentos
Java Fundamentals
Java Fundamentals
Criando e importando pacotes................................................................................3-9 Static import................................................................................................................3-11 Criando objetos .........................................................................................................3-12 O que a referncia null? .......................................................................................3-13 Atribuindo referncias...............................................................................................3-15 Visibilidade aplicada a classes ...............................................................................3-16 Definindo operaes ................................................................................................3-18 Comando return ........................................................................................................3-21 Visibilidade para operaes ...................................................................................3-22 Definindo atributos ....................................................................................................3-25 Visibilidade aplicada a atributos ............................................................................3-26 Acessando atributos .................................................................................................3-32 Comentrios no cdigo fonte.................................................................................3-33 Escopo das variveis.................................................................................................3-36 Passando Tipos Primitivos para Mtodos ...............................................................3-39 Passando Referncias para Mtodos ....................................................................3-40 Exerccios.....................................................................................................................3-42
Java Fundamentals
Exemplos de variveis e mtodos estticos .........................................................5-22 O mecanismo de herana entre classes ..............................................................5-23 Herdando estrutura e comportamento.................................................................5-24 Especificando herana em Java ...........................................................................5-25 Objetos de subclasses...............................................................................................5-26 Chamando construtores da superclasse...............................................................5-27 Overloading e Overriding de mtodos..................................................................5-29 Redefinindo mtodos overriding..........................................................................5-30 Referncia super........................................................................................................5-33 Invocando mtodos da superclasse......................................................................5-35 Visibilidade protected ..............................................................................................5-36 Varargs ........................................................................................................................5-37 Polimorfismo................................................................................................................5-39 Modificador final........................................................................................................5-41 Enums...........................................................................................................................5-43 Exerccios.....................................................................................................................5-46
Java Fundamentals
A classe Hashtable ....................................................................................................6-34 A classe LinkedList......................................................................................................6-35 Generics ......................................................................................................................6-36 Autoboxing .................................................................................................................6-39 Exerccios.....................................................................................................................6-43
IV
Java Fundamentals
1-1
Objetivos
Compreender os fundamentos da tecnologia Java Discutir vantagens da tecnologia Entender o funcionamento da JVM (Java Virtual Machine) Configurar o ambiente de desenvolvimento para o programador
1-2
O que Java?
Linguagem orientada a objetos, simples, portvel, interpretada, distribuda, robusta, segura, dinmica, de alto desempenho, multi-thread e independente de plataforma Projetada pela Sun Microsystems inicialmente para dispositivos eletrnicos Utilizada posteriormente em navegadores web, para permitir que uma aplicao pudesse ser desenvolvida e executada na web. Aqui o nascimento da tecnologia applet Uma linguagem muito utilizada atualmente para desenvolvimento de sistemas que precisam rodar na web bem como sistemas desktop
Breve Histrico
Java comeou em 1991, quando um grupo de analistas da Sun, liderados por Patrick Naughton e James Gosling, procurou desenvolver uma linguagem de computador que fosse usada em equipamentos domsticos, tais como comutadores de canais para TV a cabo, videocassetes e outros. Como estes equipamentos no dispem de muita memria ou velocidade, a linguagem tinha de ser reduzida e gerar cdigo eficiente. Alm disto, como diferentes fabricantes poderiam escolher diferentes CPUs, tal linguagem no poderia se restringir a uma nica arquitetura. O projeto ficou conhecido como Green Project.
Visando satisfazer todas estas exigncias, a equipe de analistas optou por uma linguagem que gerasse cdigo intermedirio (os famosos bytecodes Java), e que a interpretao deste cdigo no fosse feita diretamente pelo hardware e sim por uma mquina virtual disposta sobre ele (conhecida hoje como JVM Java Virtual Machine). Esta linguagem foi batizada inicialmente com o nome Oak (que, em portugus significa carvalho). Possivelmente o nome escolhido por Gosling se deve a um carvalho que existia em frente a sua janela na Sun MicroSystems. 1-3
Posteriormente se descobriu que Oak j era o nome de uma outra linguagem, e o nome foi ento trocado para Java. Java no obteve muito sucesso como linguagem de controle de eletrodomsticos (e isto ns podemos muito bem atestar :-). Em vo, a equipe do Green Project tentou vender a idia para fabricantes de tais dispositivos. Dissolvida a equipe, por absoluta falta de xito econmico, alguns dos antigos componentes perceberam que uma das possveis utilidades para tal linguagem seria embuti-la em navegadores, como os encontrados no mercado. Tais aplicativos exigiam justamente uma linguagem independente de plataforma, confivel, segura e em tempo real: todas as caractersticas estranhas que Java possua.
1-4
Decidiram ento simplificar: A linguagem no seria compilada para uma plataforma nativa e sim para uma mquina virtual. Esta tcnica que d ao java a possibilidade de rodar em mltiplas plataformas foi baseada no Smalltalk No haveria programao genrica (na poca, mas a partir da verso 1.5 este recurso j suportado) No haveria sobrecarga de operadores Herana mltipla seria substituda pelo mecanismo de interfaces, mais simples e com poder de expresso equivalente A velha sintaxe, tomada de emprstimo da linguagem C, seria enxugada, de modo a conter somente as palavras reservadas necessrias
Destas idias iniciais surge ento a tecnologia Java. Claro que h muito mais coisas presentes no java do que as listadas acima. Atualmente o java uma tecnologia to completa que permite voc desenvolver aplicaes para rodar na Web, em mquinas cliente, Celulares, Palm Tops e muito mais.
1-6
Erro de Ponteiro?
Um dos principais objetivos dos projetistas da linguagem era conseguir conciliar a flexibilidade e o poder da orientao por objetos com a segurana e a robustez da checagem de tipos e erros em tempo de compilao. Java uma linguagem fortemente tipada. E o que queremos dizer com isto? Que, em tempo de compilao, so checados todos os problemas referentes passagem de parmetros e atribuies de variveis no que diz respeito compatibilidade de tipos entre a varivel que recebe o valor e a varivel atribuda. Outra importante caracterstica da linguagem Java fato de no possuir apontadores, com o sentido que tal termo possui em C ou em C++. Em C ou C++ perfeitamente possvel navegarmos despreocupadamente pela memria do processo: basta, para tal, declararmos um apontador para uma regio de memria e sairmos a increment-lo ou decrement-lo. Toda a aritmtica com apontadores no s permitida pela linguagem, como tambm incentivada. Em Java no h apontadores explcitos, nem tampouco aritmtica de apontadores, mas sim referncias feitas a objetos criados. Objetos so criados atravs do operador new e o espao de memria que ocupam automaticamente gerenciado por um sistema de coleta de lixo (garbage collection) , que o libera to logo no haja mais referncias a um objeto.
1-7
Com isto, no existem em Java os erros de ponteiro (dangling pointers, memory leak e outros) to conhecidos de linguagens como C e C++.
1-8
Multiplataforma e interpretada
Ao contrrio das outras tecnologias onde os programas so compilados para um sistema operacional especfico, os fontes Java so compilados para uma mquina virtual. Isto significa que aps a compilao os mesmos, so executados por uma mquina virtual (JVM) e no diretamente pelo sistema operacional. Abaixo veja a forma tradicional de compilao dos programas e mais abaixo a forma como funciona o Java.
Em linguagens tradicionais como C, C++ ou pascal, o cdigo fonte convertido para um conjunto de instrues de mquina da plataforma de hardware onde a compilao teve lugar. Este programa executado diretamente pela CPU da mquina e est vinculado plataforma em que foi compilado: s poder ser executado por CPUs que compartilhem o mesmo conjunto de instrues, o que geralmente significa ficar limitado a um determinado fabricante de hardware ou a uma famlia de produtos.
1-9
Java adota uma filosofia diferente. Os fontes Java no so convertidos diretamente para instrues de mquina. Ao contrrio, a partir da compilao dos fontes so gerados arquivos contendo cdigo intermedirio que independe de plataforma. O cdigo intermedirio Java, conhecido como bytecode Java, foi projetado para uma mquina hipottica. Contm instrues similares a de uma mquina real (operaes aritmticas, controle de fluxo, etc.), mas no tem em vista, e nem se limita, a uma determinada arquitetura de computador. Em vez de ser executado diretamente pelo hardware, este cdigo interpretado por uma JVM (Mquina Virtual Java Java Virtual Machine). Desta forma, em qualquer arquitetura onde exista uma JVM ser possvel executar um programa Java sem a necessidade de se re-compilar os fontes. Os binrios Java (cdigo intermedirio ou Java bytecode) so independentes de plataforma ou, dito de outra maneira, neutros quanto arquitetura da mquina. Os fontes Java so armazenados em arquivos com a extenso .java. A compilao dos arquivos .java trar como resultado arquivos com a extenso .class. Arquivos com a extenso .class contm somente Java bytecodes e so tambm conhecidos como binrios Java. Cabe novamente ressaltar que os binrios Java (arquivos .class) no so executados diretamente pelo hardware e sim interpretados pela JVM. Sem a JVM no h como executar nenhum programa Java.
1-10
Desta forma, as requisies feitas por um programa Java a recursos do sistema so mapeadas pela JVM em requisies feita ao SO sobre o qual a JVM executa. O SO responde a tais requisies e estas respostas so encaminhadas ao cdigo Java em execuo. Uma vez compilado um programa Java, os binrios (bytecodes Java) podem ser executados em toda a plataforma para a qual j a JVM j tenha sido portada. Atualmente, a grande maioria dos sistemas operacionais conhecidos possui uma implementao da JVM (Solaris, Windows98, WindowsNT, Linux, MacOS, HP-UX, AIX, etc.).
1-11
A JVM pode ser implementada atravs de um programa avulso, pode estar embutida em um navegador, fazer parte do ncleo de um banco de dados, ou mesmo integrar o kernel de um SO. A nica exigncia que se faz execuo de um aplicativo Java a existncia da JVM para aquele ambiente.
A linguagem Java orientada a objetos, com linhas de execuo (threads) dinmicas e muitos outros recursos. Mas o que faz a diferena o modo como os programas Java so executados. Eles rodam dentro de mquinas virtuais (virtual machines), que ficam dentro do computador. Por isso, um programa Java no tem contato com o computador real, ele conhece apenas a mquina virtual. Logo, os programas Java so independentes de plataforma. Se voc j precisou desenvolver programas para vrios sistemas operacionais, sabe que isso uma grande vantagem. Quando voc escreve um programa Java e o compila, ele est pronto para ser executado em qualquer PC que contenha a mquina virtual Java. De certa forma, voc est escrevendo para apenas uma plataforma: a mquina virtual. A virtual machine determina o que os programas Java podem ou no fazer. Os programas escritos em linguagens compiladas, como C ou C++, so executados diretamente pelo sistema operacional. Assim sendo, eles tm acesso direto a todos os recursos do sistema, incluindo memria e sistema de arquivos. Como os programas Java so executados de dentro da mquina virtual, as pessoas (programadores e desenvolvedores) que criam a mquina virtual podem decidir o que um programa pode ou no fazer no computador. O ambiente criado para os programas Java chama-se ambiente de runtime. A mquina virtual age como um firewall (barreira) entre o computador e o programa Java. Um programa nunca acessa os dispositivos de entrada e sada, o sistema de arquivos ou mesmo a memria do seu computador. Em vez disso, ele pede que a mquina virtual faa isso. Quando rodamos as applets, elas so descarregadas para uma mquina virtual que probe o acesso ao sistema de arquivos. Assim, ela s permite acesso indireto aos recursos do sistema. Por ser uma linguagem interpretada, isso explica a independncia de plataforma Java.
1-12
1-13
Durante a execuo de um programa Java, a JVM pode importar cdigo de qualquer lugar. A fim de tornar, a linguagem segura, necessrio ou nos certificarmos de que o local de onde o cdigo se origina seguro, ou policiarmos constantemente o cdigo inseguro contra eventuais violaes de segurana. A primeira opo implementada atravs de sistemas de assinatura digital de cdigo. A segunda opo, por sua vez, de responsabilidade do sistema de runtime. Cabe a este policiar a execuo dos bytecodes Java, verificando se no h, entre eles, nenhuma instruo no autorizada, que viole as regras de segurana estabelecidas pela linguagem.
1-14
O carregador de classes do sistema de runtime assegura que classes com origem em uma fonte local (classes Built-in) e classes provenientes da rede sejam armazenadas separadamente. Durante a execuo, o sistema de runtime sempre procura resolver primeiro uma referncia nas classes locais. Isto garante que classes locais no sejam substitudas por classes carregadas a partir da rede (fonte insegura). Elimina a possibilidade de sobrescrita de classes seguras (spoofing) por classes no confiveis. O acesso ao sistema de arquivos locais e aos recursos de rede controlado por classes da linguagem (Built-in classes). Estas classes so restritivas por default. Se cdigo importado e classificado como inseguro tenta acessar o sistema de arquivos, os mecanismos de segurana avisam imediatamente ao usurio.
1-15
Aspectos de segurana
Talvez pelo fato de Java estar fortemente associado Internet, um dos aspectos mais divulgados da linguagem sua segurana. Isso natural: sem a certeza da segurana, provavelmente ningum iria querer baixar cdigo de um site desconhecido na Internet e deixar que ele rodasse em seu computador.E no entanto, isso j est sendo feito todos os dias com os applets Java. Java foi projetado com a segurana em mente. Por isso, oferece vrias camadas de controles de segurana que protegem contra cdigo malicioso, permitindo que os usurios rodem tranqilamente programas de origem desconhecida, como os applets. No nvel mais baixo, a segurana uma conseqncia da robustez de Java. Como j vimos, os programas Java no podem forjar ponteiros para a memria, nem estourar arrays, nem ler memria que esteja fora das fronteiras de um array ou string. Esses recursos so uma das principais defesas de Java contra cdigo malicioso. Ao impedir totalmente qualquer acesso direto memria, toda uma enorme classe de ataques segurana evitada. A segunda barreira contra cdigo malicioso o processo de verificao do bytecode que executado pelo interpretador Java sobre qualquer cdigo de origem desconhecida que carregado. Essa verificao assegura que o cdigo seja bem formado isto , que ele no avance na memria que fica acima ou abaixo dos limites da pilha (stack overflow ou underflow), nem implemente bytecode ilegal. Se esse passo de verificao do bytecode no existisse, cdigo corrompido por incompetncia ou m f poderia tirar partido de pontos fracos na implementao de um interpretador Java. Outra camada de proteo para segurana comumente chamada de modelo de caixa de areia (sandbox): o cdigo de origem desconhecida pode rodar, mas mantido isolado dentro de uma caixa de areia, onde pode rodar em segurana sem causar qualquer dano ao "mundo real", que o ambiente Java como um todo. Quando um applet, ou outro cdigo de origem desconhecida est rodando dentro da caixa de areia, ele fica submetido a diversas restries sobre o que pode fazer. A mais bvia dessas restries que ele no tem acesso de nenhum tipo ao sistema de arquivos local. Existem ainda vrias outras restries caixa de areia. Na verdade, existe uma classe, chamada SecurityManager, especialmente para cuidar da implementao dessas restries. Para assegurar o funcionamento do modelo de segurana, todas as classes do ncleo Java que executam operaes de risco, como acesso ao sistema de arquivos, primeiro pedem permisso ao SecurityManager atualmente instalado. Se a chamada est sendo feita, direta ou indiretamente, por cdigo de origem desconhecida, o gerenciador de segurana lana uma exceo, impedindo a operao. 1-16
A verso Java 1.1, implementa um recurso adicional questo da segurana: a assinatura digital. Anexando uma assinatura digital ao cdigo Java, a origem desse cdigo pode ser estabelecida de uma forma criptograficamente segura e impossvel de falsificar. Desta forma, o usurio pode definir que uma determinada pessoa ou organizao merece sua confiana. A partir da, o cdigo que traz a assinatura digital dessa entidade merece confiana mesmo que seja carregado atravs da rede, podendo rodar sem as restries do modelo de caixa de areia. Porm, quando se trata de segurana, preciso ser realista. Da mesma forma que nunca se pode garantir que um programa seja 100% livre de bugs, nenhuma linguagem ou ambiente pode ter a garantia de ser 100% seguro. Dentro desses limites, Java com certeza oferece um bom nvel de segurana para a maioria das aplicaes prticas. Java antecipa e se defende contra a maioria das tcnicas que tm sido usadas para fazer com que software tenha comportamento malicioso. A segurana de Java foi intensamente testada por experts em segurana e tambm por hackers. Desta forma, foi possvel sanar alguns furos de segurana encontrados nas primeiras verses de Java. igualmente razovel esperar que quaisquer furos que venham a ser descobertos no futuro sejam sanados com a mesma rapidez.
1-17
A JVM transforma os bytecodes Java em instrues nativa de mquina. Se um bloco de cdigo executado diversas vezes, a JVM tem o trabalho reinterpretar este mesmo bloco de cdigo toda vez que o fluxo de execuo o atingir. Mas porque interpretar um bloco de cdigo que no muda e j foi uma vez interpretado? Uma nova tcnica, conhecida como compilao sob demanda (Just-inTime Compilation ou JIT Compilation), foi ento desenvolvida para contornar este tipo de situao. Compiladores JIT, quando encontram um bloco de bytecodes Java pela primeira vez, o traduzem de maneira definitiva para instrues nativas de mquina. Se o mesmo bloco executado novamente, no h porque novamente interpret-lo: as instrues nativas de mquina resultado da compilao Just-inTime assumem o controle da execuo, dispensando a necessidade de interpretao. Compiladores JIT aumentam o desempenho de programas Java, fazendo-os rodar mais rapidamente, uma vez que dispensam a necessidade de tradues sucessivas e inteis de um mesmo bloco de bytecodes Java. Os ganhos de desempenho so mais significativos quando da otimizao de laos e funes recursivas, em que um mesmo bloco de cdigo exaustivamente repetido.
1-18
Abaixo temos uma figura que mostra toda a plataforma java de desenvolvimento. Observe que existem muitas tecnologias presentes nesta plataforma. Voc no precisa saber todas elas para trabalhar com java. Colocamos esta figura de forma que voc possa ver algumas importantes, as quais listamos abaixo:
[ javac ] Compilador Java, traduz programas Java para bytecodes [ java ] Interpretador de bytecodes, para executar programas java [ appletviewer ] Visualizador de applets, l uma pgina HTML, carrega o applet referenciado pela pgina e o executa, mostrando em sua prpria tela a entrada e sada do applet [ javadoc ] Gerador de documentao, ferramenta que gera automaticamente documentao em HTML a partir dos comentrios do cdigo fonte Java [ jar ] Empacotador de aplicaes java, para a gerao e manuteno de archives (jar). O formato de arquivos JAR possibilita o agrupamento de mltiplos arquivos em um nico, que recebe o nome de Java Archive (ou .jar). Desta forma, um nico arquivo .jar tipicamente contm vrios binrios Java (arquivos .class) e arquivos auxiliares de recursos utilizados pelo applet ou application Java [ javap ] Disassembler, ferramenta recebe como entrada um binrio Java (arquivo .class) e fornece como sada uma lista de comandos assembly da mquina virtual Java referentes ao binrio analisado, ou uma lista de prottipos de classes encontradas no binrio [ Swing ] Framework para criao de interfaces drficas [ Java Web Start ] Tecnologia para distribuio de software [ JDBC ] Framework para conexo com banco de dados
1-19
1-20
1-21
Configurando o ambiente
Para trabalhar com a linguagem java na sua mquina preciso configurar algumas coisas antes de escrever o promeiro programa. Estas configuraes no so necessrias na mquina do usurio que ir rodar a sua aplicao, sendo configuraes somente para a mquina do desenvolvedor. Voc precisar adicionar as seguintes variveis de ambiente ao sistema operacional que estiver utilizando:
1) JAVA_HOME - local onde foi instalado o java na sua mquina. Esta varivel utilizada por programas para localizar a mquina virtual java e o compilador 2) CLASSPATH esta varivel contm o caminho onde esto as classes/bibliotecas java que o programa ir utilizar. Se voc baixar algum pacote jar da internet com classes que desejar utilizar, ser necessrio colocar o caminho deste pacote nesta varivel para que as classes do mesmo sejam localizadas no momento da compilao
3) PATH esta varivel importante estar configurada para poder rodar os programas que esto localizados dentro do diretrio bin da sua instalao do java
1-22
APIs da linguagem
Java possui um conjuntomuito grande classes para serem utilizadas no desenvolvimento de palicaes. Estas classes esto organizadas em pacotes que fazem parte do JDK. Abaixo voc tem alguns dos principais pacotes que sero utilizados para o desenvolviemtno de aplicaes. Para ter uma viso do todo basta acessar a documentao do JDK atravs de um browser. Siga o seguinte link para isto: http://java.sun.com/j2se/1.5.0/docs/api/
java.applet
Fornece as classes necessrias para a criao de um applet e para a comunicao que posteriormente se estabelece entre o applet e o contexto em que executa. Contm todas as classes para a criao de interfaces grficas do usurio e controle de imagens. Contm as classes relacionadas aos desenvolvimento de Java Beans. Permite entrada e sada atravs de data streams, serialization e sistema de arquivos. Classes relacionadas ao prprio projeto da linguagem Java, referindo-se manipulao e converso de tipos, strings, threads e ambiente de execuo. Classes utilizadas para aritmtica de inteiros de preciso arbitrria (BigInteger) e para a aritmtica de decimais de preciso arbitrria (BigDecimal) Classes contendo facilidades de comunicao em rede (manipulao sockets, resoluo de nomes, estabelecimento de canais de comunicao). Classes e interfaces relacionadas s questes de segurana. Classes que permitem interface com o banco de dados (JDBC) Classes e interfaces para manipulao de texto, datas, nmeros e mensagens. Miscelnea de classes auxiliares: tratamento do tempo, gerador de nmeros aleatrios, vetores de bits, internacionalizao do aplicativo, manipulao de archives Java, etc. Conjunto de componentes visuais peso leve que, com o mximo grau de compatibilidade possvel, funcionam da 1-23
java.math
java.net
javax.swing
1-24
1-25
Java Fundamentals
2. Tipos e Operadores
2-1
Tipos e operadores
Objetivos
Compreender as seguintes estruturas: o Variveis o Tipos Primitivos o Literais Compreender os tipos de dados primitivos: o char o boolean o byte, short, int, long o float, double Compreender os tipos de dados compostos Apreender converses de tipos Conceituar expresses e operadores Definir precedncia e associatividade entre estruturas
2-2
Tipos e operadores
Variveis
Java uma linguagem fortemente tipada. Isto significa que a utilizao de qualquer varivel deve ser compatvel com a sua prvia definio. Compete ao compilador da linguagem verificar, antes mesmo da execuo do programa (isto , de maneira esttica), se h a referida compatibilidade entre definio e uso de uma varivel. Os contextos em que uma varivel pode ser validamente empregada so determinados pelo seu tipo. O tipo determina a utilizao: restringe as operaes aplicveis e concede sentido ao resultado de uma operao vlida (semntica da operao). Seria contra-senso somarmos um tipo booleano com outro tipo booleano ou, ainda pior, multiplicarmos um booleano por um nmero fracionrio. Qual a resposta esperada para estas operaes? No h resposta, porque a operao frente aos tipos carece de coerncia. Ao definirmos um inteiro (ou um nmero real, ou um booleano, etc.), estamos a dizer quais operaes so vlidas quando aplicadas a este inteiro (real, booleano, etc.) e quais simplesmente carecem de sentido. Decorrem do fato de Java ser fortemente tipada: Todas as variveis em Java devem ter um tipo associado (a fim de que se possa avaliar futuramente se os empregos dados a esta varivel so ou no corretos) A utilizao de uma varivel deve ser posterior sua definio As converses foradas de tipo (casts) devem ser rigidamente controladas pela linguagem, tanto sob o aspecto esttico (no se permitindo converses entre tipos distintos, e autorizando to somente a converso entre tipos derivados), quanto sob o aspecto dinmico (controle em tempo de execuo das converses de tipo efetuadas). No se permitem converses implcitas de tipo. Todas as converses de tipo devem ocorrer de maneira expressa.
2-3
Tipos e operadores
Tipos primitivos so aqueles tipos j embutidos na linguagem java e estudados no captulo anterior, enquanto tipos compostos so todas as classes da linguagem java ou classes que voc venha a criar. Variveis de tipos primitivos so tratadas de uma maneira bem diferente de variveis de referncias para objetos ( variveis de tipos compostos). bastante importante saber quais so estas diferenas e porque Java foi projetada desta forma.
Quando voc declara uma varivel de um tipo primitivo, Java aloca um pedao de memria que grande o suficiente para guardar valores do tipo primitivo declarado. Se voc define uma varivel de tipo primitivo como uma varivel de instncia, a varivel inicializada para 0 se for inteira, para false se for booleana e para '\0' se for caractere. Variveis de tipos primitivos armazenam o seu valor diretamente. Se voc, por exemplo, declara uma varivel do tipo int e atribui um valor 3 para esta varivel, o valor armazenado diretamente nos quatro bytes reservados para a varivel.
Quando voc declara uma varivel de referncia, voc tambm recebe um pedao de memria, mas esta memria grande o suficiente para armazenar apenas uma referncia para o objeto. Talvez seja til pensar em uma referncia como um apontador para o objeto. Como mencionado antes, declarar uma varivel de referncia no cria um objeto do tipo especificado. Conseqentemente, uma varivel de instncia inicializada para null a fim de indicar que ainda no recebeu referncia para nenhum objeto ainda.
2-4
Tipos e operadores
Use o operador de atribuio para fazer com que uma varivel de referncia se refira a uma instncia de uma classe. A atribuio pode ser para um objeto existente ou para um objeto recm criado atravs do operador new.
2-5
Tipos e operadores
Tipos Primitivos
Tipos primitivos so aqueles fornecidos diretamente pela linguagem, ou seja, tipos j embutidos na linguagem. So tipos atmicos, indivisveis e sobre os quais a linguagem, de ante mo, j oferece operaes pr-definidas. Exemplos de tipos primitivos so inteiros e booleanos. Para us-los, basta associ-los a uma varivel. A maior parte das linguagens permite ao programador criar tipos compostos. Tipos compostos procuram representar de maneira conjunta e unificada os vrios atributos de uma entidade modelada. Um catlogo telefnico pode ser representado dentro de um programa como uma lista de Strings contendo nomes, outra contendo os endereos e, por fim, uma outra contendo os telefones. Todas as informaes necessrias pesquisa ou manipulao do catlogo esto presentes em tais listas. Mas esta definitivamente no a melhor maneira de se representar um catlogo telefnico. Se perguntarmos a algum o que um catlogo, dificilmente ouviremos como resposta uma lista de nomes, endereos e telefones. A resposta mais provvel uma lista de assinantes. Um assinante, por sua vez, identificado pelo nome que possui ou endereo onde reside. Ao procurarmos descobrir o telefone de um assinante, pesquisaremos pelas chaves que o identificam: nome ou endereo. A representao estruturada da informao , em si, informao relevante. Ao modelarmos um catlogo como uma lista de assinantes e identificarmos um assinante pelo seu nome ou endereo, estamos trazendo para dentro do programa no apenas informao contida em um catlogo, mas tambm a prpria estrutura de um catlogo: informao sobre como a informao organizada. Os tipos compostos no so apenas armazns de dados. A sua funo principal no conter o dado, pois para isto j temos tipos primitivos. O seu objetivo principal organizar a informao. Aproximar a estrutura empregada na confeco do modelo da estrutura existente no mundo real modelado. Tornar a tarefa de programar mais intuitiva, permitindo uma relao direta entre o modelo e o objeto modelado. A representao do dado dentro do programa facilita a compreenso do prprio programa como modelo. No basta fazer um programa (modelo) que funcione. necessria tanto uma compreenso do mundo real atravs do programa, quanto uma compreenso do prprio programa como modelo do mundo real. Tipos compostos so construdos tendo como blocos construtores tipos primitivos ou, de maneira recursiva, outros tipos compostos. Em ltima anlise, os tipos primitivos so os nicos responsveis pela construo dos tipos compostos. Um tipo composto nada mais que um conjunto organizado de tipos primitivos. Tipos compostos sero vistos em captulos posteriores. 2-6
Tipos e operadores
Java possui oito tipos primitivos: boolean, char, byte, short, int, long, float e double. Cada um destes tipos ser estudado de maneira mais detalhada nas sees seguintes. A tabela abaixo apresenta um resumo dos tipos primitivos encontrados na linguagem Java. Cumpre observar que o tamanho do tipo em bytes e a sinalizao fazem parte da especificao da linguagem. Ou seja, um char em Java ocupar sempre 16 bits, um int 32 bits, um long 64 bits, e assim por diante, independente da plataforma em que o programa esteja sendo executado.
2-7
Tipos e operadores
Tipo
boolean
Contm
true ou false
char
caracter Unicode
\u0000
16 bits
byte
8 bits
short
16 bits
int
32 bits
long
64 bits
float
ponto flutuante
0.0
32 bits
double
ponto flutuante
0.0
64 bits
Ao contrrio do que acontece com outras linguagens de programao, as caractersticas dos tipos de dados listados acima idependem da plataforma em que o programa dever ser executado. Dessa forma, os tipos de dados primitivos so realmente nicos e garantem a capacidade de intercmbio de informaes entre diversos tipos de
2-8
Tipos e operadores
computadores, aliviando o programador da preocupao e da rdua tarefa de converter dados em formatos apropriados para a portagem.
2-9
Tipos e operadores
So oito os tipos primitivos de Java: boolean, char, byte, short, int, long, float e double. Quarenta e quatro so os operadores que podem ser utilizados na manipulao destes tipos primitivos. Declarar e inicializar uma varivel de um tipo primitivo extremamente fcil. Basta, a exemplo da seguinte linha de cdigo, associar ao identificador escolhido pelo usurio para a varivel um dos tipos acima, atribuindo, logo em seguida, um literal para esta varivel.
2-10
Tipos e operadores
Os programas Java so escritos usando o conjunto de caracteres Unicode. Ao contrrio da codificao de 7 bits ASCII, que til somente para a lngua inglesa, e codificaes de 8 bits, tais como ISO Latin-1, que til somente para a maior parte das lnguas da Europa Ocidental, a codificao Unicode, de 16 bits, consegue representar praticamente todas as linguagens de uso freqente no planeta. Entretanto, poucos editores de texto suportam caracteres Unicode, e na prtica, a maior parte dos programas so escritos em ASCII. Os caracteres Unicode, de 16 bits, so usualmente escritos em arquivos usando uma codificao conhecida como UTF-8, que converte os caracteres de 16 bits em uma seqncia de bytes. O formato projetado de forma que um texto escrito em ASCII ou em ISO Latin-1 so seqncias de bytes UTF-8 vlidas. Desta forma, voc pode simplesmente escrever programas em ASCII e eles se comportaro, graas s caractersticas de projeto da codificao UTF-8, como textos Unicode vlidos. Se voc quiser inserir um caracter Unicode dentro de um programa Java escrito em ASCII, basta usar a seqncia de escape especial para caracteres Unicode \uxxxx. Isto , uma contrabarra mais a letra u em minscula seguida de quatro caracteres hexadecimais. A seqncia de escape \u0020 representa caracter de espao, e a seqncia \u3c00 o caracter . Voc pode usar caracteres Unicode em qualquer lugar em um programa Java, incluindo comentrios e nome de variveis. Podemos encontrar a tabela unicode no seguinte endereo: http://www.unicode.org
2-11
Tipos e operadores
Voc pode, claro, usar qualquer caracter Unicode como um literal caracter, sendo necessrio to somente o emprego de seqncias de escape \uxxxx Unicode. Java suporta tambm vrias outras seqncias de escape que facilitam a representao de caracteres ASCII no visveis, tais como nova linha ou backspace, e permitem o escape na construo de literais contendo caracteres de pontuao com significado especial, tais como aspas duplas ( ) e aspas simples ( ). Por exemplo:
char tab = \t, apostrofe = \, nulo = ; char unicode = \u05D0; Cdigo 2-3: Exemplos de char especiais
2-12
Tipos e operadores
A tabela abaixo mostra os caracteres de escape que podem ser utilizados na construo de um literal caracter.
Seqncia de escape Valor do caracter
\b \t \n \f \r \ \ \\ \uxxxx
backspace tabulao horizontal nova linha alimentao de formulrio retorno de carro aspas duplas aspas simples contrabarra Caracter Unicode com codificao xxxx, onde xxxx so quatro dgitos hexadecimais.
Estas seqncias de escape podem tambm ser usadas em literais para Strings. Valores do tipo char no podem ser convertidos para e a partir de tipos inteiros. Ao contrrio de byte, short, int e long, o tipo char um tipo no sinalizado (unsigned). A classe Character vrios mtodos estticos (static methods) para trabalhar com caracteres, incluindo isLowerCase() e toUpperCase().
2-13
Tipos e operadores
Errado
int i = 10; while(i) { ... i--; } int i = 10; while(i!=0) { ... i--; }
Correto
No h (como ocorre com C e C++) converso, implcita ou forada, entre booleanos e inteiros (ou outro tipo primitivo qualquer).
2-14
Tipos e operadores
Literais inteiros podem ser expressos tambm em notao octal ou hexadecimal. Um literal que comea com 0x ou 0X interpretado como um nmero hexadecimal, valendo-se das letras A a F (ou a a f) para os dgitos restantes requeridos em nmeros de base 16. Literais inteiros que tm um dgito 0 em seu incio so interpretados como nmeros octais (base 8) e, portanto, entre os dgitos subseqentes no podem figurar os algarismos 8 e 9. Java no permite que literais inteiros sejam expressos em notao binria (base 2). Literais inteiros octais e decimais vlidos:
0xff 0377 // decimal 255 expresso em hexa // mesmo nmero expresso em octa
Literais inteiros exprimem valores de 32 bits, a menos que terminem com o caracter L ou l, indicando, neste caso, serem tais literais valores de 64 bits.
1234 1234L 0xffL // um valor int // um valor long // outro valor long
2-15
A aritmtica inteira em Java modular. No h transbordo ou estouro na manipulao de nmeros inteiros. Ao contrrio, ao exceder a faixa de um determinado tipo inteiro, em uma das extremidades, o resultado da operao avana de maneira circular sobre a extremidade oposta. Por exemplo:
byte b1 = 127, b2 = 1; byte sum = b1 + b2; // sum = -128, que o menor byte
Nem o compilador Java, nem a JVM avisar quando ocorrer transbordo em aritmtica inteira. Desta maneira, ao manipular inteiros, voc deve ter certeza que o tipo que est usando grande o suficiente para os propsitos que tem em mente. Que a faixa de nmeros oferecida pelo tipo larga o suficiente para as operaes pretendidas. Divises inteiras por zero e operaes mdulo zero no so aceitas e lanam a exceo ArithmeticException. Cada tipo inteiro tem uma classe invlucro correspondente (wrapper classes): Byte, Short, Integer e Long. Cada uma dessas classes define as constantes MIN_VALUE e MAX_VALUE que descrevem as extremidades da faixa de nmeros suportada pelo tipo. Estas classes tambm definem vrios mtodos estticos extremamente teis, tais como Byte.parseByte() e Integer.parseInt(), empregados na converso de strings para inteiros.
2-16
Tipos e operadores
Literais de ponto flutuante tambm podem ser representados atravs de notao cientfica, na qual um nmero seguido pela letra e ou E (assinalando o expoente) e por um outro nmero. Este segundo nmero representa a potncia de dez pela qual o primeiro nmero multiplicado. Por exemplo:
1.2345E02 // 1.2345 x 102 ou 123.45 1e-6 // 1 x 10-6 ou 0.000001 6.02e23 // No. de Avogrado 6.02 x 1023 Cdigo 2-9: Literais float em notao cientfica
Nmeros de ponto flutuante so double por default. Para representar um literal de ponto flutuante float em um programa, basta acrescentar o caracter f ou F no final do nmero.
double d = 6.02e23; float f = 6.02e23f; Cdigo 2-10: Literais float e double em notao cientfica
Literais de ponto flutuante no podem ser representados em notao hexadecimal ou octal. A maior parte dos nmeros reais, pela sua natureza, no 2-17
Tipos e operadores
pode ser representada exatamente em um nmero finito de bits. Portanto, importante se lembrar que os valores double e float so apenas aproximaes dos nmeros que eles procuram efetivamente representar. Um float uma aproximao de 32 bits, o que resulta em pelo menos 6 dgitos decimais significativos, e o double uma aproximao de 64 bits, o que, por sua vez, resulta em pelo menos 15 dgitos decimais significativos. Na prtica, estes tipos so suficientes para a maior parte das computaes de ponto flutuante.
2-18
Tipos e operadores
Literais Strings podem conter qualquer uma das seqncias de escapes permitidas para um valor char. Utilize a seqncia \" para incluir aspas duplas dentro de um literal String. String e literais Strings sero discutidos com mais detalhes a seguir.
2-19
Tipos e operadores
A nica exceo a esta regra que voc pode atribuir um literal inteiro (portanto, um valor int) para uma varivel byte e short, se o literal pertencer faixa de representao desta varivel. Se voc precisa de converses de reduo e est confiante que o pode fazer sem perda de informao ou preciso, voc pode forar Java a executar a converso usando uma construo da linguagem conhecida como cast (converso explcita). A converso explcita feita colocando-se o nome do tipo pretendido entre parnteses antes da varivel a ser convertida. Por exemplo:
int i = 13; byte b = (byte) i; i = (int) 13.456;
2-20
Casting de tipos primitivos so mais freqentes em converses de nmeros reais para inteiros. Quando isto ocorre, a parte fracional do nmero real simplesmente truncada (o valor de ponto flutuante arredondado para zero e no para o inteiro mais prximo). Os mtodos Math.round(), Math.floor() e Math.ceil() permitem outros tipos de arredondamento.
short s = (short) 0xffff; char c = '\uffff'; int i1 = s; int i2 = c; Cdigo 2-14: Atribuio de valores implcitos e expressos
O tipo char funciona como um tipo inteiro a maior parte das vezes, podendo, portanto, ser usado em qualquer lugar em que se espere um int ou long. Lembre-se, no entanto, que o tipo char no sinalizado e se comporta de maneira diferente do tipo short, embora ambos possuam 16 bits.
2-21
Tipos e operadores
Tipos de referncia
Alm dos oito tipos primitivos, Java define duas outras categorias de tipos: classes e vetores. Programas em Java so construdos atravs de definies de classes; cada classe define um novo tipo de dado que pode ser manipulado por programas Java. Um programa pode, por exemplo, definir uma classe chamada Ponto e usla para armazenar coordenadas (x,y) de um sistema cartesiano de coordenadas. Com isto, Ponto passa a ser um novo tipo de dado em um programa. Um tipo vetor representa uma lista de valores de um determinado tipo. int um tipo de dado, e um vetor de valores do tipo int outro tipo de dado, escrito em Java como int[]. Um vetor de objetos do tipo Ponto tambm um tipo, escrito como Ponto[]. E um vetor de vetores de Ponto tambm um outro tipo, escrito em Java como Ponto[][]. Como voc pode ver, h um nmero infinito de tipos de dados de classes e vetores possveis. Basta o programador defini-los. Estes tipos so conhecidos coletivamente como tipos de referncia. A razo para este nome ficar clara logo a seguir. Por enquanto, importante compreender apenas que classes e vetores so tipos de dados diferentes dos tipos primitivos. Tipos de dados de classes e vetores so conhecidos como tipos compostos. Um tipo de dado primitivo guarda somente um nico valor. Classes e vetores so tipos agregados que contm vrios valores. O tipo Ponto, por exemplo, armazena dois valores double representando as coordenadas x e y do ponto. Classes e vetores sero retomados logo adiante.
2-22
Tipos e operadores
Expresses e operadores
At o presente momento, aprendemos sobre os tipos primitivos que os programas Java so capazes de manipular e vimos como construir literais para cada um destes tipos. Utilizamos tambm variveis, nomes simblicos que representam e armazenam um valor. Literais e variveis so importantes tokens com os quais programas so construdos em Java. Expresses so o prximo nvel de estrutura de um programa Java. O interpretador Java (JVM) avalia uma expresso para determinar o seu resultado. As expresses mais simples so chamadas expresses primrias e consistem de apenas um literal ou uma varivel. So exemplos de expresses primrias:
1.7 'A' true sum Cdigo 2-16: Expresses primrias
Quando o interpretador Java avalia uma expresso literal, o resultado da avaliao o prprio literal. Quando o interpretador avalia uma expresso contendo uma varivel, o resultado da avaliao o resultado armazenado nesta varivel. Expresses primrias no so muito interessantes. Expresses mais complexas so construdas utilizando operadores para combinar expresses primrias. Por exemplo, a seguinte expresso usa o operador de atribuio ( = ) para combinar duas expresses primrias uma varivel e um literal de ponto flutuante em
sum = 1.7
Mas operadores no so usados apenas com expresses primrias; eles tambm podem ser usados com expresses de qualquer nvel de complexidade. As seguintes construes so, portanto, expresses vlidas.
sum = 1 + 2 + 3 * 1.2 + (4 + 8) / 3.0; sum = (sum / Math.sqrt(3.0 * 1.234) ); sum = (int) (sum + 33);
2-23
2-24
Tipos e operadores
Sumrio de operadores
Os tipos de expresses que voc pode escrever em uma linguagem de programao dependem completamente do conjunto de operadores que a linguagem disponibiliza. A tabela abaixo apresenta sntese dos operadores disponveis em Java. A colunas P e A desta tabela indicam, respectivamente, a precedncia e a associatividade de cada grupo de operadores correlatos. Neste curso veremos alguns operadores listados na tabela abaixo, os demais sero vistos a medida do estudo da linguagem.
Operadores Tipo de operando
objeto, membro vetor, inteiro mtodo, lista de args varivel varivel nmero inteiro booleano
Operao executada
. [] ( args )
ps incremento, ps decremento pr incremento, pr decremento mais unrio, menos unrio complemento (NOT bit a bit) NOT booleano
classe, lista de args criao de objetos tipo, qualquer coisa nmero, nmero nmero, nmero string, qqr coisa nmero, nmero nmero, nmero referncia, tipo primitivo, primitivo primitivo, primitivo cast (converso explcita de tipo)
multiplicao, diviso e resto adio e subtrao concatenao de strings menor que, menor que ou igual maior que, maior que ou igual comparao de tipos igual (o mesmo valor) no igual (valores diferentes)
2-25
Tipos e operadores == referncia, referncia referncia, referncia inteiro, inteiro booleano, booleano inteiro, inteiro booleano, booleano inteiro, inteiro booleano, booleano booleano, booleano booleano, booleano booleano, qqr coisa, qqr coisa varivel, qqr coisa igual (o mesmo objeto)
!=
& &
^ ^
| |
&&
||
? :
*=, /=, %=, +=, varivel, qqr coisa -=, <<=, >>=, >>>=, &=, ^=, |= Tabela 2-4:Sumrio de Operadores
2-26
Tipos e operadores
Precedncia
O operador de multiplicao tem prioridade mais alta que o operador de adio, logo a somado ao resultado da multiplicao de b e c. A precedncia de um operador pode ser pensada como uma medida de quo firmemente est ligado o operador aos seus operandos. Quanto maior a precedncia de um operador, mais firmemente ele est ligado aos seus operandos. A precedncia default de um operador pode ser afastada atravs do uso de parntesis, de forma a explicitar a ordem exata das operaes. A expresso anterior pode ser rescrita como se segue, determinando explicitamente que a adio deve ocorrer aqui antes da multiplicao.
(a + b) * c Cdigo 2-20: Expresso utilizando parntesis
A precedncia default dos operadores de Java foi escolhida procurando torn-la compatvel com C. Os projetistas de C, ao determinar a precedncia default de cada um dos operadores, tiveram em mente a maneira mais fcil e direta de se escrever expresses sem a necessidade do uso de parntesis. H apenas algumas expresses em Java em que se faz necessria a presena de parntesis.
2-27
Tipos e operadores
Associatividade
Quando uma expresso contm vrios operadores que tm a mesma precedncia, a associatividade dos operadores indicaro a ordem na qual as operaes sero executadas. A maior parte dos operadores tem associatividade da esquerda para direita, o que significa que as operaes so feitas da esquerda para a direita. Operadores unrios e de atribuio possuem, entretanto, associatividade da direita para esquerda. Os operadores aditivos possuem associatividade da esquerda para direita, sendo a expresso a+b-c avaliada da esquerda para direita: (a+b)-c. Operadores unrios e de atribuio so avaliados da direita para a esquerda. Considere a seguinte expresso:
int a = 5; int b = 4; int c = a++ + b++ Cdigo 2-21: Associatividade com incremento
A associatividade, assim como a precedncia, estabelece a ordem default de avaliao para uma expresso. Esta ordem default pode ser afetada com o uso de parnteses. Entretanto, a escolha da precedncia e da associatividade conduz a uma sintaxe mais natural, e raramente voc precisar alter-la.
2-28
Tipos e operadores
2-29
Tipos e operadores
2-30
Tipos e operadores
2-31
Java Fundamentals
3-1
Objetivos
Definir classes, atributos e operaes Trabalhar com pacotes Conhecer padres para codificao Aplicar visibilidade a classes, atributos e operaes Comentar os cdigos fonte Gerar documentao do cdigo fonte Estudar o escopo das variveis
3-2
Classes e Objetos
Uma classe um gabarito utilizado para criar mltiplos objetos. Uma classe encapsula todos os dados e comportamentos que definem um objeto. Quando voc pede ao interpretador Java para criar ou instanciar um objeto, Java usa a definio de classes como gabarito para a criao de novos objetos. Uma classe pode conter atributos que so atribudos a todos os novos objetos desta classe. Atributos so informaes ou dados que descrevem, categorizam ou quantificam um objeto. Cada novo objeto de uma dada classe ter seu prprio conjunto de atributos de classe. Um objeto da classe Cliente, por exemplo, ter um nome, um endereo e um nmero telefnico como atributos. Dados armazenados em um objeto podem ser tanto primitivos, tais como inteiros ou caracteres, ou referncias para outros objetos. Uma classe pode conter tambm mtodos ou funes que especifiquem o comportamento ou aes que a classe consegue realizar. A classe Cliente, por exemplo, pode alugar um carro, efetuar um pagamento ou alterar o seu endereo. Java utiliza pacotes para agrupar classes que esto logicamente relacionadas. Pacotes consistem de classes fisicamente localizadas em um mesmo diretrio. Pacotes tambm so usados para controlar o acesso de classes definidas fora do pacote.
3-3
O bloco contendo a definio de uma classe comea pela palavra reservada class. No cdigo abaixo temos a criao de uma classe para reprensentar um Produto.
class Produto { }
Uma classe o bloco de construo bsico para uma linguagem orientada a objetos uma coleo de dados e de mtodos que manipulam estes dados. A classe um modelo abstrato, a partir do qual sero criadas instncias desta classe, contendo os dados e os mtodos nela definidos. Observe que a definio da classe acima muito simples e a mesma feita atravs da palavra reservada class. O par de chaves utilizado serve para delimitar o corpo da classe, ou seja, onde iremos colocar as operaes e atributos da mesma. Veremos mais adiante como colocar os atributos e operaes Os dados referentes a uma classe so armazenados em variveis e as operaes efetuadas sobre estes dados so implementadas atravs de mtodos. Seguindo os passos contidos nesta lio voc conseguir criar e executar sua primeira Java Application. Para isto vamos adicionar um mtodo especial nesta classe que nos permitir executar a mquina virtual e executar algum cdigo. Tomaremos como exemplo, para a primeira Java Application, o consagrado Hello World. Este programa, bastante simples, imprime na tela do computador a mensagem Hello World. Usando um editor de texto, crie um arquivo de nome HelloWorld.java contendo as seguintes linhas.
class HelloWorld { public static void main( String[] args ) { System.out.println( "Hello World!" ); } } Cdigo 3-2: Exemplo de HelloWorld Java
3-4
O arquivo fonte pode ser compilado atravs de seu IDE ou usando o compilador javac atravs de linha de comando como mostrado abaixo
C:\> javac HelloWorld.java Cdigo 3-3: Compilando uma classe Java
Obtendo xito na compilao, o arquivo HelloWorld.class, contendo os bytecodes Java, ser criado pelo compilador no mesmo diretrio em que se encontra o arquivo fonte. Caso o compilador tenha reportado alguma falha, verifique se no digitou algo incorretamente, prestando ateno para o uso de maisculas e minsculas. Certifique-se tambm de ter dado ao arquivo o nome correto. Execute a aplicao Java usando a mquina virtual fornecida pelo JDK (java):
C:\>java HelloWorld Hello World! Cdigo 3-4: Executando uma classe Java sem pacote
3-5
Padres
A linguagem java segue padres para escrita de cdigo especificados pela Sun, empresa criadora da linguagem java. Desenvolvedores devem procurar seguir estes padres, uma vez que todo cdigo de APIs que existem seguem este padro para facilitar o endendimento dos mesmos bem como a leitura destes cdigos. O compilador Java (javac), bem como todas as demais ferramentas do JDK, diferenciam maisculas de minsculas. Este recurso chamado de case-sensitive. Portanto, bastante cuidado ao grafar o nome de classes, mtodos, variveis e pacotes. Erros comuns decorrem muitas das vezes de problemas envolvendo grafia, em que um nome, por exemplo, definido em maisculas, e depois, logo adiante, utilizado em minsculas. O compilador simplesmente alegar que tal varivel, mtodo, classe ou pacote no foi definido. Abaixo so apresentados alguns padres:
Nomes de arquivos
Arquivos contendo os fontes Java terminam com a extenso .java. Todo arquivo fonte Java deve ter no mximo uma nica classe public. Pode haver mais de uma classe por arquivo, porm somente uma pblica. O nome do arquivo fonte java case-sensitive, ou seja, deve respeitar letras maisculas e minsculas, devendo tambm ter o mesmo nome da classe publica declarada dentro do mesmo. Exemplo: Produto.java
Nomes de classes
Escolha nomes significativos, de tal forma que a simples leitura do nome j crie uma expectativa acerca do que se pode esperar da classe. Use para isto um ou mais substantivos. O primeiro caractere de cada palavra utilizada para o nome da classe deve ser maisculo. Quando o nome de uma classe tiver mais de uma palavra as mesmas devem estar concatenadas. Exemplo: NotaFiscal, Cliente, Item
3-6
Nomes de operaes
Conselho similar pode ser dado escolha dos nomes dos mtodos: use nomes significativos. Use verbos ou estruturas verbais que captem a ao principal contida no mtodo. O nome deve representar a real utilidade desempenhada pelo mtodo. A primeira letra do nome de uma operao deve ser em minscula e a primeira letra de todas as demais palavras que compem o nome da operao, caso existam, em maisculo. Exemplo: getDescricao(), setPrecoFinal(), imprimirRelatorio()
Nomes de atributos/variveis
Use nomes curtos, mas que no sejam crticos. A primeira letra do nome da varivel deve ser em minscula e a primeira letra de todas as demais palavras presente no nome deve ser maiscula. Evite usar nomes de variveis com uma nica letra. O que voc esperaria de uma varivel de nome r ou x? O nome deve ser representativo e a simples leitura do mesmo leva compreenso do papel desempenhado pela varivel no aplicativo. A nica exceo aceitvel para contadores em laos, ou variveis temporrias de uso restrito. Exemplo: nome, descricao, precoFinal, idade, dataNascimento
Nomes de constantes
O nome de constantes definido de uma forma um tanto diferente. Toda constante tem o seu nome escrito sempre com todos os caracteres em maisculo, e se o nome for composto por mais de uma palavra, as mesmas devem ser separadas pelo caractere _. Veja abaixo um exemplo: Exemplo: TAMANHO_MAXIMO_VETOR = 100, BORDA = 4
Caracteres especiais
Nmeros, sublinhado e dlar podem ser usados em nomes. A nica restrio que o nome deve sempre comear por um caractere que seja diferente de um nmero. Mas evite o mau uso de tais caracteres especiais.
3-7
Nome de pacotes
Pacotes devem possuir nomes significativos e no devem ter seus nomes separados por caracteres como _. Seus nomes devem ser escritos sempre com todas as letras em minsculo e os nomes de pacotes seprados pelo caractere ponto (.). Veja o exemplo abaixo: Exemplo: com.targettrust.database Observe que o nome do pacote foi iniciado com a palvra com e em seguida com a palavra targettrust. Normalmente comeamos o nome de um pacote com o inverso do domnio da empresa. Isto explica o porque utilizar com.targettrust no incio do nome do pacote.
3-8
Compilando e executando:
C:\> javac d . HelloWorld.java C:\> java com.targettrust.java.HelloWorld Hello World! Cdigo 3-6: Compilando um classe com pacote e realizando sua execuo. A opo d indica o deretrio de destino para o byte-code
package com.targettrut.java; import import import import java.sql.*; java.io.*; java.net.*; javax.swing.JFrame;
3-9
3-10
Static import
Este recurso presente a partir da verso 1.5 do java extremamente til para simplificar e facilitar a escrita de cdigo. Permite utilizarmos os membros (atributos ou mtodos) static sem que tenhamos que prefixar os membros com o nome da classe. Veja o exemplo abaixo:
System.out.println( Math.random() ); System.out.println( ( raio * raio) * Math.PI );
Cdigo 3-8: Uso de operaes static sem a importao dos membros static
Veja que o cdigo acima fica mais claro e fcil de ser escrito. Esta facilidade de escrita do cdigo deve ser utilizada mas com cuidado para no ser abusada, pois pode prejudidar a legibilidade do cdigo das suas aplicaes. Sempre que muitos membros static de uma classe forem ser utilizados til este recurso, mas se somente um ou dois membros forem ser utilizados o uso deste recurso no aconselhvel. A importao dos membros static pode ser feito de forma genrica ou especfica como mostra o cdigo abaixo:
1 import static java.lang.Math.PI; 2 import static java.awt.BorderLayout.*; Cdigo 3-10: Importando a estrutura estatica de uma classe
Com o static import da linha 2 possvel se utilizar todas as constantes da classe BorderLayout. Isto evita termos que escrever portanto o nome da classe cada vez que uma constante for utilizada.
3-11
Criando objetos
Neste momento do seu aprendizado iremos mostrar como pode ser criao um objeto de uma determinada classe para que voc possa aproveitar melhor os passos seguintes do curso. No iremos ainda aqui nos aprofundar neste assunto, visto que a criao de objeto algo que merece um tempo maior de estudo. Veremos ento como pode ser criado um objeto.
... Produto prod; prod = new Produto(); ... Cdigo 3-11: Criando um objeto da classe Produto
Observe no cdigo acima a criao de um objeto que ser referenciado por prod. Na primeira linha estamos fazendo a declarao de uma referncia para um futuro objeto da classe produto. Esta referncia ir receber um objeto que est sendo criado na linha segunte. A palavra reservada new a responsvel por alocar memria e construir o objeto da classe Produto. Logo depois de construdo este objeto o endereo do mesmo ;e atribudo para a referncia prod. Para criar um objeto precisamos da classe e no momento de criao do mesmo veja que logo depois deste nome de classe colocamos os sinais de parnteses. Esta criao tambm pode ser feita em uma nica linha de cdigo para simplificar o processo, como mostrado abaixo:
... Produto prod = new Produto(); ... Cdigo 3-12: Criand objeto da classe Produto em uma nica linha
Agora em uma nica linha voc esta declarando uma referncia para o objeto, criando o objeto e atribuindo o endereo de memria do mesmo para esta referncia.
3-12
Ele declara uma varivel/referncia prod e a inicializa com null. Isto indica que a varivel de referncia prod no se refere a nenhum objeto ainda, em outras palavras, ela somente foi delarada. null uma palavra reservada na linguagem Java. Voc pode us-la com o operador de igualdade para verificar se uma varivel de referncia j recebeu uma referncia vlida a um objeto ou mesmo para saber se duas referncias
if( prod == null ) { ... ... } ... prod == prodRef ...
Quando voc tiver terminado de usar um objeto, voc pode atribuir o valor null para a varivel que o referencia. Isto indica que a varivel no mais se refere ao objeto. Quando nenhuma referncia houver para um objeto, o objeto ser marcado como inacessvel e ser considerado pelo coletor de lixo (garbage collector). Iremos estudar com mais detalhes o coletor de lixo nos prximos captulos. Na prtica, somente em casos muito especiais voc precisa atribuir null para uma varivel. A JVM automaticamente decrementa o nmero de referncias ativas para um objeto sempre que a varivel que o referencia recebe 3-13
o valor null, sai de fora de escopo ou ento recebe o valor de uma referncia para outro objeto.
3-14
Atribuindo referncias
Como mencionamos antes, quando voc declara uma varivel de referncia para um objeto, esta varivel tem o seu valor inicializado para null. Antes que voc possa usar esta varivel (ou seja, acessar o objeto a que ela referencia), voc tem de inicializ-la. Todos os atributos de uma classe que forem de tipos compostos (Classes) sero inicializados automaticamente pela JVM no momento da criao de um objeto da classe para o valor null. Quandor declaramos uma referncia para um objeto e na mesma linha j criamos este objeto, estamos inicializado a referncia com um valor diferente de null, ou seja, o endereo do objeto criado.V eja cdigo abaixo:
Produto prod = new Produto(); Cdigo 3-15: Criao do produto prod
Podemos tambm fazer atribuio de referncia, para isto basta utiliza o operador de atribuio. Neste caso as duas referncias iro apontar para o mesmo objeto. Veja o cdigo abaixo:
Produto prod1 = prod2; Cdigo 3-16: Atribuio da referncia prod1 para prod2
Esta sintaxe est perfeitamente correta, mas vale frisar que h apenas um objeto Produto criado. Quando voc atribui uma referncia para um objeto para outra referncia, voc termina com duas referncias para o mesmo objeto, e no uma cpia do objeto. Voc pode acessar o mesmo objeto atravs de ambas as referncias, entretanto, h apenas um nico objeto. Este objeto conhecido como objeto de referncia. importante se lembrar disto, principalmente ao passar uma referncia para uma operao . Isto ser visto em maiores detalhes adiante. Voc pode alterar uma referncia (mudando o valor da varivel de referncia), sem que isto afete a outra referncia (o valor da outra varivel de referncia). Caso voc precise de um outro objeto, ao invs de ter mltiplas referncias para o mesmo objeto, voc ter de criar este novo objeto.
3-15
Encapsulamento uma das palavras-chave para a orientao a objetos. Uma classe bem defina deve separar completamente a sua interface pblica da implementao interna. Neste momento do estudo iremos mostrar quais so so tipos de encapsulamentos que uma classe pode receber. Certos de que a esta altura dos estudos voc j conhece os tipos de encapsulamentos existentes vamos agora aplicar os mesmos para classe. A palavra visibilidade tambm pode ser aplicada para este assunto, uma vez que de acordo com o modificador que utilizaremos iremos tormar mais ou menos visvel uma classe.
pacote/default
Esta visibilidade a visibiliade padro quando no se especifica nenhuma visibilidade. Ao contrtio de ontras linguagen onde a visibilidade padro public java define a visibilidade pacote/default. Se uma classe possuir esta visibilidade isto significa que a mesma pode ser utilizada somente por outras classes que estiverem dentro do mesmo pacote. Classes que estiverem em pacotes diferentes do pacote onde esta classe estiver no sabero que a mesma existe. No exemplo abaixo a classe email poder ser utilizada somente por classes do pacote com.targettrust.comunicacao e nenhum outro pacote mais
package com.targettrust.comunicacao; class Email { ... ... } Cdigo 3-17: Visibilidade de package aplicada a classes
3-16
public
Uma classe normalmente declara como sendo pblica, isto deixa a classe visvel, ou seja, capaz de ser utilizada por qualquer outra classe do sistema, idependente do pacote onde a mesma se encontra. Recomenda-se que a classe sempre seja pblica a no ser que voc queira restringir o acesso de uso a esta classe. Quando em um arquivo fonte for delcarado mais de uma classe o nome do arquivo fonte deve levar o mesmo nome da classe pblica que foi declarado neste. Lembre-se que no possvel declarar mais de uma clase pblica em cada arquivo fonte. Veja o exemplo abaixo de uma classe pblica:
public class Email { ... ... } class Produto { ... ... } Cdigo 3-18: Duas classes declaradas no mesmo arquivo fonte
3-17
Definindo operaes
Quando voc define uma classe necessrio definir tambm as operaes que faro parte desta classe. As operaes so definidas dentro das chaves das classes. Cada operao ter uma implementao especfica que conhecida como mtodo. Um mtodo, portanto, a implementao de uma operao. Um mtodo em Java equivalente a uma funo, procedimento ou subrotina em outras linguagens, com a diferena que ele deve ser definido dentro da declarao da classe. Em outras palavras, no existe em Java mtodos globais (completamente desvinculados de uma classe). Todo mtodo deve ser definido dentro de uma classe. Anteriormente quando criamos uma classe, definimos uma operao chamada main, agora iremos estudar a anatomia das operaes bem como definir outras operaes em uma classe.
Modificador de acesso: utilizados para restringirem o acesso as operaes. Pode ser public, default, protected ou private.
3-18
Tipo de retorno: pode ser um tipo primitivo (como int ou char tipos primitivos sero estudados mais adiante), ou um tipo composto (um objeto String ou Produto, por exemplo), ou mesmo no haver retorno algum. Neste caso dever constar void como tipo de retorno. Em resumo: toda operao em java deve indicar o tipo de retorno.
Nome da operao: O nome da operao deve expressar o que a operao faz. Normalmente este nome deve ser um verbo ou estar no imperativo dando a idia de uma ao.
Parmetros: representam os valores que podemos passar para a operao. Toda operao pode receber parmetros, sendo assim a operao pode definir logo aps o seu nome um ou uma lista de parmetros. Se o mtodo recebe vrios parmetros, cada um deles deve ser separado dos demais por vrgula. Uma operao tambm pode no receber parmetros. Havendo ou no parmetros, os mesmos devem ser representados entre parnteses.
3-19
Corpo da operao: o local onde fica a implementao da mesma. Este cdigo deve ficar entre chaves, que representam o incio e fim do bloco.
public void foo(String arg, int cod) { System.out.println( arg ); System.out.println( cod ); }
Cdigo 3-24: Corpo da operao. Impresso dos valores passados como parmetros
3-20
Comando return
O comando return utilziado na linguagem java para que as operaes possam retornar valores. Um comando return aceita um valor simples ou uma expresso que deve ser compatvel com o tipo de retorno do mtodo em que este comando est
public class Produto { public String getDescricao() { return "Nome: " + nome + " Preo: R$ " + preco; } public void setNome( String n ) { nome = n; return; } }
inserido.
Cdigo 3-25: Comando return para retorno de mtodo com ou sem valor de retorno.
Quando um comando de return encontrado, o fluxo de execuo abandona o mtodo imediatamente, ignorando quaisquer comandos que existam entre o comando de return e o final do mtodo (o fecha chaves do corpo do mtodo). Esta alterao do fluxo de execuo pode ser usada mesmo em mtodos que no retornam nenhum valor (mtodos cujo tipo de retorno void), com a finalidade de abandonar o mtodo imediatamente. Neste caso especial, o comando return no aceitar nenhum valor de retorno ou expresso (afinal o mtodo void).
3-21
public
Esta visibilidade expe as operaes para serem chamadas de outros objetos. Acima quando criamos as operaes voc pode observar que as mesmas foram definidas como sendo pblicas. Uma operao definida sempre, por padro, como sendo pblica, veja o cdigo abaixo:
package com.targettrust.java; public class Produto { public void foo() { } }
A operao foo() mostrada acima pode ser chamada a partir de qualquer outra classe independende do pacote onde se encontrar esta classe. Veja o cdigo abaixo onde criamos um objeto para poder chamar esta operao:
package com.targettrust.vendas; import com.targettrust.java.*; public class CriaObjetos { public static void main(String[] args) { Produto prod = new Produto(); prod.foo(); } } Cdigo 3-27: Criando um objeto de uma classe e chamando a iperao pblica
3-22
private
A visibilidade private restringe o acesso a esta operao ao prprio objeto que a contm. Uma operao privada portanto no pode ser acessada por outro objeto a no ser aquela que a definiu. Operaes privadas no so comuns e se existirei representam um servio interno do prprio objeto. Veja abaixo como pode ser definida uma operao privada:
public class Produto { private void foo() { } } Cdigo 3-28: Visibilidade provada
Esta operao foo() uma operao que pode ser chamada somente atravs de outras operaes da prpria classe, veja abaixo:
public class Produto { private } void foo() {
public void salvar() { foo(); } } Cdigo 3-29: Chamando operao com visibiliade privada
3-23
O cdigo abaixo no permitido, pois veja que agora a operao foo() esta definida com sendo privada.
public class CriaObjetos { public static void main(String[] args) { Produto prod = new Produto(); prod.foo(); } } Cdigo 3-30: Chamada de operao privada fora da classe
protected
O uso desta visibilidade, assim como para os atributos est ligada ao uso de herana, desta forma iremos deixar este tipo de visibilidade para ser demonstrado mais adiante quando estudarmos o mecanismo de herana. Uma operao protegida uma operao visvel para objetos de classes que esto no mesmo pacote daquela classe que define a operao ou para uma classe filha desta classe que contm a operao protegida.
package/defalut
Uma operao com visibilidade de pacote/default uma operao que tem comportamento de pblica dento do pacote que a contm. Normalmente uma operao no definida como package, mas sim como public ou private. Para definir uma operao com esa visibilidade no se deve especificar nenhum modificador de acesso, isto a tornar default/package. Veja abaixo na classe Produto como ficaria a operao com esta visibilidade:
public class Produto { void foo() { } } Cdigo 3-31: Visibilidade default
3-24
Definindo atributos
Os atributos de uma classe definem a estrutura dos objetos. Estes atributos so declarados dentro do bloco que define a classe. Veja no exemplo abaixo a declarao de alguns atributos para a classe produto:
public class Produto { String descricao; float preco; boolean emVenda; } Cdigo 3-32: Atributos da classe produto
Observe que na declarao acima os atributos ficam dentro do bloco de cdigo da claase. Estes atributos so atributos com visibilidade default. Logo estudaremos os tipos de visibilidade que podem ser aplicadas aos atributos. Estes atributos especificados acima so conhecidos como atrubutos de intncia e para serem acessados precisam que um objeto da classe que os contm seja criado. Um atributo pode ser inicializado com valores j no momento da sua declarao como mostrado no cdigo abaixo. Isto far com que quando um objeto da classe que o contm for criado o mesmo j possua um determinado valor. O atributo emVenda ir possuir o valor true, neste caso, para todos os objetos criados
public class Produto { String descricao; float preco; boolean emVenda = true; } Cdigo 3-33: Inicializao do atributo
3-25
public
Esta visibiliade ir tornar o acesso ao atributo disponvel para qualquer outra classe que estiver em qualquer outro pacote. Isto significa que objetos gerados a partir desta classe que define o atributo pblico podero ter os valores destes atributos modificados por qualquer outro objeto. Este tipo de encapsulamento/visibilidade no o recomendado para atributos. Veja o exemplo abaixo com os atributos para a classe Produto sendo pblicos:
public class Produto { public String descricao; public float preco; public boolean emVenda; } Cdigo 3-34: Visibilidade pblica para os atributos
Veja agora como seria o acesso a estes atributos em um pseudo-cdigo. Observe que a palavra prod utilizada para referenciar um objeto da classe Produto criado.
public class Consulta { public static void main(String[] args) { Produto prod = new Produto(); prod.descricao = Notebook; prod.preco = 3500.0f; prod.emVenda = false; } } Cdigo 3-35: Acessando atributos com visibiliade pblica
3-26
3-27
private
A visibilidade provate a visibilidade recomendada pela orientao a objetos para os atributos de uma classe. Voc estudou estes tipos de visibilidade e a importncia do uso das mesmas nos cursos anteriores, ento vejamos agora como ficaria esta visibilidade aplicada aos atributos.
public class Produto { private String descricao; private float preco; private boolean emVenda; } Cdigo 3-36: Definindo atributos provados
O acesso agora aos atributos no poderia mais ser feito de forma direta como na visibilidade pblica. Veja o cdigo abaixo e observe que nas linhas onde tentamos acessar os atributos teramos um erro sendo reportado pelo compilador dizendo que o atributo privado e no pode ser acessado desta forma.
public class Consulta { public static void main(String[] args) { Produto prod = new Produto(); prod.descricao = Notebook; prod.preco = 3500.0f; prod.emVenda = false; } } Cdigo 3-37: Acessando atributos privados
Como ento deve ser feito o acesso a atributos privados. O acesso a atributos com visibilidade privada deve ser feito atravs de operaes pblicas que sero especificadas na classe. J vimos como definir operaes, ento veja agora como ficaria o acesso a estes atributos.
Primeiramente teramos que modificar a classe Produto adicionando mtodos pblicos para fazer este acesso. Veja abaixo:
3-28
public class Produto { private String descricao; private float preco; private boolean emVenda; public void setDescricao(String novaDescricao) { descricao = novaDescricao; } public String getDescricao() { return descricao; } ... } Cdigo 3-38: Definindo operaes para acesso aos atributos
Logo depois de modificarmos a classe Produto podemos fazer acesso a seus atributos atravs das operaes. Veja abaixo:
public class Consulta { public static void main(String[] args) { Produto prod = new Produto(); prod.setDescricao(Notebook); prod.setPreco(3500.0f); prod.setEmVenda(false); } } Cdigo 3-39: Utilizando as operaes para acesso aos atributos
3-29
package/default
Um atributo com visibilidade de pacote/default um atributo que pode ser acessado diretamente como se fosse pblico por classes que estiverem no memo pacote. Para definir um atributo com esta visibilidade no necessrio colocar modificador antes do mesmo. Este o modificador padro para visibilidades quando as mesmas no forem definidas. Abaixo veja a nova verso da classe Produto:
package com.targettrust.java; public class Produto { String descricao; float preco; boolean emVenda; } Cdigo 3-40: Visibilidade default
Observe que a classe acima est dentro de um pacote chamado com.targettrust.java e que a mesma ser utilizada por outra classe que est no mesmo pacote.
package com.targettrust.java; public class Consulta { public static void main(String[] args) { Produto prod = new Produto(); prod.descricao = Notebook; prod.preco = 3500.0f; prod.emVenda = false; } } Cdigo 3-41: Acesso a visibilidade defalut
3-30
Agora se movermos a classe Consulta para outro pacote e fizermos a importao do pacote com.targettrust.java para tentar acessar os atributos na teremos sucesso.
package com.targettrust.exemplo; import com.targettrust.java.*; public class Consulta { public static void main(String[] args) { Produto prod = new Produto(); prod.descricao = Notebook; prod.preco = 3500.0f; prod.emVenda = false; } } Cdigo 3-42: Acessando atributo default fora do pacote
O cdigo que temos para acessar os atributos o mesmo que temos quando a classe pblica, mas agora como a classe Consulta est em pacote diferente, e os atributos de Produto tem a visibilidade de pacote/default o acesso no pode mais ser feito de forma direta. Neste caso se tivssemos interesse em acessar os atributos a partir de outra classe fora do pacote teramos que fornecer mtodos pblicos para isto.
protected
Esta visibiliade para ser entendida necessita o estudo do mecanismo de herana entre classes. Vamos deixar para mais tarde quando mostrarmos aqui este mecanismo para ento dar exemplos de cdigos com protected. Um atributo protegido um atributo que ter visibilidade de pacote, mas tambm ir permitir o acesso direto a ele para classes que estiverem em pacotes diferentes daquele pacote onde est a classe que o define, desde que a classe fora do pacote seja filha da que contm o atributo.
3-31
Acessando atributos
O acesso a atributos de uma classe deve ser feito somente por operaes definidas na mesma classe que contm este atributo. Desta forma devemos tornar os atributos de uma classe por padro privados e as operaes que iro acess-los pblicas. Cada atributo ir possuir um par de mtodos que chamamos de mtodos de leitura e escrita ou getter e setter. Veja abaixo como ficaria a classe produto:
public class Produto { private int codigo; private String descricao; private float preco; public void setCodigo(int novoCodigo) { codigo = novoCodigo; } public int getCodigo() { return codigo; } public void setDescricao(String novaDescricao) { descricao = novaDescricao; } public String getDescricao() { return descricao; } public void setPreco(float novoPreco) { preco = novoPreco; } public float getPreco() { return preco; } } Cdigo 3-43: Definio da classe Produto
3-32
Os comentrios de cdigo fonte esto presentem em todas as linguagens de programao, e como java no poderia ficar de fora o mesmo possui 3 tipos de comentrios. Os comentrios so importantes pois so um mecanismo para o programador explicar dentro do fonte com as suas prprias palavras o que significa ou faz os elementos que o mesmo est escrevendo. Java possui um tipo de cometrio que pode ser utilizado por um gerador de documentao a fim do mesmo criar um conjunto de pginas HTML com informaes sobre a classe. O programador interessado em utilizar aquela clase no precise olhar o fonte da mesma para saber do que ele dispe, mas sim basta olhar em qualquer browser esta documentao em formato HTML. Na linguagem java existem os seguintes tipos de comentrios: 1 Comentrio de linha 2 Comentrio de mltiplas linhas 3 Comentrio de documentao
Comentrio de linha
O comentrio de linha um comentrio bastante prtico e muito utilizado. Seve para podermos colocar em qualquer ponto do cdigo uma documentao. No entanto esta documentao feita somente em uma linha, no podendo haver mltiplas linhas como no anterior. Veja o exemplo abaixo:
public class Produto { public float calcularPreco() { // para calcular o preo deve ser descontado o desconto preco = preco desconto; ...
3-33
Comentrio de documentao
Este tipo de cometrio deve ser colocado antes do elemento que se quer documentar, ou seja antes da definio de uma classe ou operao. As marcaes /** e */ indicam o incio e fim de um comentrio de documentao. Todo o contedo colocado dentro destas marcaes ser capturado pelo utilitrio javadoc para montar a documentao da classe em formato HTML.
/** Classe para representar um produto da loja. Um produto deve conter sempre um cdigo e uma descrio Criada dia 05-05-2005 */ public class Produto { /** Mtodo para mostrar os dados de um produto */ public void imprimir() { } } Cdigo 3-46: Comentrio de documentao para classe e operao
3-34
Os comentrios de documentao podem ter algumas marcaes especiais para serem capturadas pelo javadoc e adicionadas na documentao HTML da classe. Estas marcao so as seguintes: @return @param Representa o tipo de retorno de uma operao. Pode conter texto para explicar o que o tipo de retorno Representa o parmetro de uma operao. Deve conter uma descrio do que significa este parmetro.
3-35
Este um assunto muitas vezes no abordado em materiais sobre java, porm de extrema importncia. Nesta linguagem as variveis quando forem declaradas iro estar visveis dentro de um determinado escopo de cdigo. Este escopo delimitado por chaves que representam blocos de cdigos. Isto significa que uma varivel declarada dentro de um bloco de cdigo visvel somente aquele bloco de cdigo bem como a outros blocos que estiverem dentro deste. Normalmente existe um bloco de cdigo delimitado por chaves para representar o corpo de cdigo de uma classe (veja na figura abaixo o escopo de classe) e de uma operao (veja abaixo escopo de mtodo). Isto significa que se declararmos uma varivel dentro do bloco da classe a mesma ser visvel a cdigos que se encontrarem dentro daquele escopo de classe (no estamos aqui levando em considerao os tipos de encapsulamento). Dentro de um corpo de cdigo para classes podemos ter operaes definidas e estas operaes possuem tambm seus blocos de cdigos (escopo de mtodo). Isto significa que se dentro do bloco de cdigo de uma classe definirmos uma varivel, esta varivel poder ser acessada normalmente dentro de qualquer bloco de cdigo de uma operao que foi definido dentro do bloco da classe. Isto tudo pode ser resumido da seguinte maneira: uma operao pode chamar qualquer outra operao da classe ou mesmo acessar uma varivel desta classe. Podemos tambm definir dentro do escopo de um mtodo outros blocos de cdigo. Isto pode ser feito atravs do uso de chaves. No normal definirmos blocos de cdigo desta maneira, mas esta mesma idia pode ser utilizada para os comandos que possuem blocos de cdigos como o if, for, while, etc... Veja abaixo na figura a representao dos escopos.
3-36
public class Produto { private float preco; public void setPreco(float novoPreco) { preco = novoPreco; } } Cdigo 3-48: Acessando a varivel preco
Observe no cdigo acima o escopo onde foi definido o preo. Esta varivel (podemos tambm chamar de atributo) foi definido dentro do escopo da classe, ou seja, dentro das chaves da classe. Pode, portanto, ser acessado por qualquer operao que estiver tambm definda dentro do escopo de classe, como a operao setPreco(...). Veja agora o cdigo abaixo ao qual adicionamos mais variveis e outro escopo.
public class Produto { private float preco; public void setPreco(float novoPreco) { preco = novoPreco; x = 34; // Erro } public void foo(int y) { int x = 10; if ( x > y) { int res = x + y; } System.out.println( res ); // Erro } } Cdigo 3-49: Acessando variveis fora de escopo
No cdigo acima temos a declara de uma varivel inteira x dentro do bloco de cdigo da operao foo(...). Isto significa que esta varivel somente poder ser acessada por outros cdigos que estiverem dentro desta mesma operao. Este tipo de varivel conhecida como varivel local. Observe que na linha onde atribudo o valor 34 ao x teremos um erro. 3-37
Neste mesmo cdigo mostrado acima podemos observar que foi declarado um comando condicional if dentro da operao e que dentro deste comando declaramos uma varivel res. Esta varivel uma varivel local ao comando condicional, ou seja, vlida somente dentro deste comando, no podendo ser acessada fora do mesmo. Veja a linha onde tentamos imprimir o contedo da varivel res, nesta linha teremos um erro de acesso. Podemos definir x e res como sendo variveis locais, enquanto preo pode ser definido como sendo uma varivel de instncia. Par6ametros de mtodos tambm so considerados como sendo variveis locais.
3-38
arg 100
O cdigo esquerda declara uma varivel int chamada preco e atribui o valor 150 a esta varivel. Quando preco passada para foo(), uma cpia de seu valor corrente preencher o parmetro arg, que ter o valor inicial de 100. Dentro de foo(), arg recebe o valor 55. Quando foo() termina, o parmetro arg descartado e o fluxo de execuo retorna ao chamador. A varivel preco, definida no contexto do chamador, no foi afetada e tem ainda o valor de 100. A sada do programa ser, portanto, a seguinte:
arg = 55 preco = 100
3-39
prod
nome:"CD" codigo: 2
Cdigo 3-51: Escopo de execuo do objeto prod public void food(Produto ref) { ref.setCodigo( 2 ); ref.setNome( "CD" ); } ref.
ref
3-40
3-41
Exerccios
1. Neste exerccio voc ir criar uma classe para representar um Produto com a estrutura (atributos) descrita abaixo. Esta classe estar associada com outra classe, a ItemPedido. Item pedido possui o produto e a sua quantidade. No final voc ir criar uma classe com mtodo main para testar sua aplicao. Siga os passos abaixo para realizar o exerccio.
Passo 1: Crie uma classe chamada Produto dentro de seu projeto. Esta classe dever pertencer ao pacote com.targettrust.java.
Passo 3: Crie operaes pblicas para acessar estes atributos permitindo que os mesmos possam ser lidos e modificados. Passo 4: Documente o cdigo escrito por voc. Use comentrio de documentao para mostrar o que as operaes realizam bem como seus parmetros e tipo de retorno. Passo 5: Crie uma outra classe pblica com o nome classe deve pertencer ao pacote com.targettrust.venda. ItemPedido. Esta
Passo 7: Crie operaes pblicas para acessar estes atributos de forma que seja possvel modificar e ler os seus valores. Passo 8: Crie uma nova classe chamada Aplicao no pacote com.targettrust.java. Dentro desta classe declare o mtodo main mostrado anteriormente na apostila. O mtodo main aquele que permite executar a classe.
3-42
Passo 9: Dentro do mtodo main crie objetos da classe ItemPedido e Produto e em seguinda associe estes objetos. Lembre-se que um ItemPedido possui uma referncia para um Produto. Defina valores para os outros atributos dos objetos. Passo 10: Crie na classe Aplicacao uma operao que seja capaz de receber como parmetro um ItemPedido e faa a impresso das informaes do objeto que esta operao receber. Passo 11: Gere a documentao utilizando o javadoc para as classes criadas no exerccio.
3-43
Java Fundamentals
4. Comandos da Linguagem
4-1
Comandos da Linguagem
Objetivos
Conhecer os comandos da linguagem java Compeender os comandos e saber o contexto no qual podem ser utilizados So estudados os seguintes comandos: switch while do for for-each break continue if else if Operador ternrio
4-2
Comandos da Linguagem
Comandos
Os comandos da linguagem so comandos comuns a maioria das linguagens de programao. O objetivo deste captulo adaptar o aluno a sintaxe destes comandos na linguagem java. Para isto abxaixo aprensentamos os comandos:: switch, while, do, for, for-each, break, continue, return, if e else if.
4-3
Comandos da Linguagem
O comando if o principal comando de controle de fluxo. Ele possibilita ao programador Java tomar decises ou, mais precisamente, executar um comando somente quando uma determinada condio for verdadeira. O comando if sempre vem sempre acompanhado de uma expresso (que a condio que pende sobre a execuo do comando) e um comando (que somente ser executado se a expresso anterior for avaliada para verdadeiro). Se a expresso for verdadeira o comando executado. Se a expresso for falsa, o comando saltado. Por exemplo:
if(usuario == null) { usuario = "admin"; } Cdigo 4-1: Comando if simples.
Embora parea um pouco estranho, os parntesis que envolvem a expresso so exigidos pela sintaxe do comando. Como j foi mencionado, um bloco de comandos delimitados por chave (comando composto) comporta-se como um comando simples, e pode ser sempre colocado onde um comando simples esperado. Desta forma, o comando if tambm pode ser escrito assim:
if( (endereco == null) || (endereco.equals("") ) ) { endereco = "[desc.]"; System.out.println("Endereo no encontrado"); } Cdigo 4-2: Comando if com expresso lgica e bloco de comandos.
Um comando if pode opcionalmente incluir a palavra reservada else seguida de um comando (simples ou composto). Neste caso, a expresso condicional avaliada e, se for verdadeira, o comando que segue a palavra reservada if executado e o comando que segue a palavra else pulado. Se a expresso for falsa o contrrio ocorrer: o comando que segue a palavra reservada if pulado e o comando que segue a palavra reservada else executado.
4-4
Comandos da Linguagem if(usuario != null) { System.out.println("Ol! " + usuario); }else { usuario = getNomeUsuario(); System.out.println("Ol! " + usuario + "Esta sua primeira sesso" ); }
Quando h vrios comandos if/else aninhados necessrio alguma precauo para garantir que a clusula else se refere ao comando if correto. Considere as seguintes linhas:
if(i == j) if(j == k) System.out.println("i igual a k"); else System.out.println("i no igual a j"); // ERRADO Cdigo 4-4: Comando if mal identado.
Infelizmente no est claro com qual if a clusula else faz par. A identao sugere ser o primeiro if o par da clusula else. E sugere erradamente, levando o programador a uma situao de erro. A regra para o casamento dos pares if/else bem simples. A clusula else sempre faz par com o comando if mais prximo. Corrigindo a identao, para que represente corretamente os pares if/else, teremos:
if(i == j) if(j == k) System.out.println("i igual a k"); else System.out.println("i no igual a j"); // ERRADO Cdigo 4-5: Comando if mal identado.
4-5
Comandos da Linguagem
Muito cuidado deve ser tomado, pois no h erro de sintaxe nos dois exemplos acima. So construes perfeitamente legal. S no ocorre o que o programador deseja. Ao trabalhar com comandos ifs aninhados use chaves a fim de tornar o cdigo mais legvel.
if(i == j) { if(j == k) { System.out.println("i igual a k"); } }else { System.out.println("i no igual a j"); // CORRETO } Cdigo 4-6: Comando if identado corretamente.
4-6
Comandos da Linguagem
No h nada de especial no cdigo acima. apenas uma seqncia de comandos ifs, onde cada if parte da clusula else do comando anterior. No entanto, escrito desta forma o cdigo fica bem mais legvel e claro do que se fosse escrito com sucessivos aninhamentos (basta dar uma olhada no exemplo
if(n == 1) { // executa bloco de cdigo 1 } else { if(n == 2) { // executa bloco de cdigo 2 } else { if(n == 3) { // executa bloco de cdigo 3 } else { // se todas as condies acima falham, ento // executa bloco de cdigo 4 } } }
abaixo). 4-7
Comandos da Linguagem Cdigo 4-8: Comando if em sequncia identado em relao a blocos de cdigo.
4-8
Comandos da Linguagem
Operador ternrio
Java tambm define um operador ternrio, chamado freqentemente de operador condicional. Funciona como um comando if dentro de uma expresso. Seus trs operandos so separados por um ponto de interrogao ? e por dois pontos :. O segundo e o terceiro operando devem ser do mesmo tipo. Veja o cdigo abaixo:
int x, y; ... String res = ; if ( x > y ) { res = X maior que Y; }else { res = Y maior que X; } ... System.out.println( res ); Cdigo 4-9: Comando if else a ser transformado em operador ternrio
Observe que o cdigo bem mais enxuto para este caso de if..else
4-9
Comandos da Linguagem
Comando switch
O comando if provoca um desvio no fluxo de execuo de um programa. Voc pode usar mltiplos comandos ifs, como mostrado na seo anterior, para executar desvios mltiplos de execuo. Entretanto, esta nem sempre a melhor soluo especialmente quando todos os desvios dependem do valor de uma nica varivel. Neste caso ineficiente conferir repetidas vezes o valor de uma mesma varivel em mltiplos comandos ifs. Uma soluo melhor usar o comando switch. Embora a sintaxe deste comando no possua a mesma elegncia apresentada por outros comandos da linguagem, a praticidade deste tipo de construo o torna extremamente til. Se voc no est familiar com este comando, talvez j conhea, no entanto, a idia que est por detrs dele. O comando switch possui uma expresso inteira e um corpo que contm vrios pontos de entrada numerados. A expresso avaliada e o fluxo de execuo salta para o ponto de entrada especificado com o valor avaliado. O comando switch seguinte equivalente ao uso repetido de comandos if e
switch(n) { case 1: // comea aqui se n == 1 // executa bloco de cdigo 1
break; // para aqui
default: // se todas as condies acima falham, ento // executa bloco de cdigo 4 break; // para aqui }
Como voc pode ver a partir deste exemplo, os vrios pontos de entrada do comando switch so rotulados ou com a palavra reservada case seguida de um valor inteiro e dois pontos, ou ento da palavra reservada default seguida de dois pontos. 4-10
Comandos da Linguagem
Quando o comando switch executado, o interpretador Java calcula o valor da expresso entre parntesis e ento procura pelo rtulo case que tenha especificado este valor. Se ele consegue encontrar tal rtulo, o fluxo de execuo transferido para o bloco de cdigo que tem incio no primeiro comando aps o rtulo. Se ele no encontra um rtulo com o valor da expresso avaliada, o fluxo de execuo salta para o primeiro comando aps o rtulo especial default. Ou, caso um rtulo default no tenha sido definido, o fluxo de execuo salta totalmente para fora do comando switch. Observe o uso da palavra reservada break ao final de cada rtulo case no exemplo anterior. O comando break ser descrito mais adiante, mas, neste caso, ele faz com que o fluxo de execuo salte para fora do corpo do comando switch. Os rtulos case em um comando switch especificam somente o ponto de entrada para o bloco de cdigo a ser executado. Os rtulos cases no so blocos independentes de cdigo, e no possuem um ponto de trmino implcito. Portanto, voc deve especificar o fim de cada rtulo com um comando break ou equivalente. Na ausncia de um comando break, a expresso avaliada e o fluxo de execuo salta para o bloco de cdigo que tem seu incio logo aps o rtulo que define a expresso avaliada, e a execuo continua at o final do comando switch. Em raras ocasies se revela til escrever cdigo em que a execuo atravessa mais de um rtulo. Em 99% dos casos, depois de encontrado o rtulo e executado o bloco de cdigo associado a este, a execuo deve deixar o comando switch por fora de um comando break. Lembre-se, portanto, de sempre verificar se h um comando break aps cada rtulo, garantindo a sada correta do comando e impedindo que o fluxo de execuo passe por todos os rtulos do comando. Um comando switch pode ter mais de uma clusula case rotulando um mesmo comando. Considere o seguinte mtodo:
boolean respostaSimOuNao( char resposta ) { switch( resposta ) { case 's': case 'S': return true; case 'n': case 'N': return false; default: return false; //por default a resposta ser false } }
4-11
Comandos da Linguagem Cdigo 4-12: Comando switch de char sem utilizao de break e com comando return.
H algumas importantes restries sobre o comando switch e os rtulos cases. A expresso associada com o comando switch deve ter um tipo byte, char, short ou int. Valores booleanos ou reais no so suportados, nem o tipo long, apesar de ser um tipo inteiro. Os valores associados com cada rtulo case devem ser ou constantes, ou expresses constantes avaliveis em tempo de compilao. Um rtulo case no pode conter expresses avaliveis em tempo de execuo, tais como variveis ou chamadas de mtodos. Os valores presentes nos rtulos cases devem estar compreendidos na faixa de valores do tipo usado na expresso do comando. Por fim, dois rtulos cases no podem ter o mesmo valor, nem um comando switch pode ter mais de uma clusula default.
4-12
Comandos da Linguagem
Comando while
Assim como o comando if o principal comando de controle de fluxo, permitindo ao programador tomar uma entre vrias decises, o comando while o principal comando de iterao da linguagem Java e permite ao programador executar um bloco de cdigo reiteradas vezes. Ele possui a seguinte sintaxe:
while(expressao) { comandos } Cdigo 4-13: Estrutura do comando while.
O comando while comea por avaliar a expresso entre parntesis. Se esta expresso avaliada para falso, o fluxo de execuo pula o corpo do comando while e passa a executar o prximo comando definido no programa. Se, no entanto, a expresso verdadeira, o corpo do lao while executado e a expresso entre parntesis reavaliada. Este ciclo continua enquanto a avaliao da expresso resultar verdadeiro. Quando a expresso se tornar falsa, a execuo do comando while termina e o fluxo de execuo passa para o prximo comando. Voc pode criar um lao infinito com a sintaxe while(true) (pois a expresso sempre verdadeira). Um exemplo de um lao que imprime os nmeros de 0 a 9:
int i = 0; while(i < 10) { System.out.println(i); i++; } Cdigo 4-14: Comando while com teste lgico para impresso de inteiros entre 0 e 9.
Como voc pode ver, a varivel cont comea em 0, neste exemplo, e incrementada cada vez que o corpo do lao executado. Aps o lao ter sido executado 10 vezes, a expresso do comando while se torna falsa (i assume o valor 10), o comando while termina, e o fluxo de execuo passa para o prximo comando do programa. A maior parte dos laos tem uma varivel contadora, como i. Os nomes de variveis: i, j e k so usados, na maioria das vezes, para tais variveis contadoras, embora voc possa escolher um nome mais claro. 4-13
Comandos da Linguagem
Comando do
O comando do bastante similar ao comando while. A diferena que, no comando do, o teste da expresso feito no final do lao. Isto significa que o corpo do lao executado pelo menos uma vez. Eis a sintaxe do comando:
do { comandos } while(expressao); Cdigo 4-15: Estrutura do comnado do/while.
H algumas diferenas a se observar entre o lao presente no comando do e o lao presente no comando while. O lao do comando do requer tanto a palavra reservada do para marcar seu incio, quanto a palavra reservada while para marcar o seu trmino e introduzir a expresso condicional do lao. Ao contrrio do lao do comando while, o lao do comando do sempre termina com um ponto e vrgula. Isto obviamente ocorre pelo fato de a expresso condicional ser colocada no final do comando. O lao abaixo gera a mesma sada que o cdigo apresentado para o comando while:
int i = 0; do { System.out.println( i ); i++; } while( cont < 10 ); Cdigo 4-16: Comando do/while com teste lgico no final para impresso de inteiros entre 0 e 9.
Observe que o comando do bem menos usado que o comando while. Isto acontece porque, na prtica, incomum encontrarmos situaes em que se deseje que o corpo do lao seja executado pelo menos uma nica vez.
4-14
Comandos da Linguagem
Comando for
O comando for fornece uma construo de iterao que , na maioria das vezes, mais conveniente que os laos while e do. O comando for tira vantagem de haver um padro de iterao bastante freqente. A maior parte dos laos possui um contador, ou algum tipo de varivel de estado, que inicializado antes da execuo do lao e incrementado, ou de alguma forma alterado, aps o trmino da execuo do corpo do lao e antes da reavaliao da expresso condicional associada ao lao. Os passos de inicializao, teste e atualizao constituem as principais manipulaes feitas sobre as variveis do lao e integram a sintaxe do comando
for( declarao e inicializao; teste; atualizao ) { }
for.
Cdigo 4-17: Estrutura do comando for
Colocar as expresses de inicializao, teste e atualizao no incio do lao algo que facilita a compreenso do que est ocorrendo no corpo do lao, e evita erros tais como esquecer de inicializar as variveis do lao. O interpretador Java descarta os valores das expresses de inicializao e atualizao, logo, para que estas expresses sejam teis, elas devem ter efeitos colaterais. A expresso de inicializao tipicamente uma expresso de atribuio, enquanto a expresso de atualizao usualmente uma expresso de incremento, decremento ou atribuio. O seguinte lao imprime os nmeros de 0 a 9, como os exemplos anteriormente colocados para os comandos while e do:
for( int i = 0; i < 10; i++ ) { Sytem.out.println( i ); } Cdigo 4-18: Comando for com teste lgico e incremento para impresso de inteiros entre 0 e 9.
Observe como esta sintaxe coloca todas as informaes importantes sobre a varivel do lao em uma nica linha, facilitando a compreenso do que ocorre no corpo do lao. 4-15
Comandos da Linguagem
Colocar a expresso de atualizao da varivel do lao na sintaxe do prprio comando for simplifica tambm o corpo do lao, permitindo que este possa ser expresso, muita das vezes, atravs de um nico comando simples, sem a necessidade do uso de um bloco de cdigo entre chaves. O comando for suporta sintaxes alternativas que ajudam ainda mais facilitar o seu uso. Pelo fato da maioria dos laos usar as variveis de lao apenas dentro do corpo do lao, o comando for permite que a expresso de inicializao contenha uma declarao completa de variveis. O escopo das variveis declaradas na expresso de inicializao de um comando for se restringe ao corpo do lao e tais variveis no mais podem ser acessadas fora do comando.
for( int i = 0; i < 10; i++ ) { Sytem.out.println( i ); } Cdigo 4-19: Comando for com escopo de varivel local (i).
Alm do mais, a sintaxe do comando no restringe a utilizao do comando a laos com apenas uma varivel. Tanto a expresso de inicializao quanto a de atualizao podem conter, em verdade, a inicializao e atualizao de mais de uma varivel, desde tais variveis venham separadas por vrgulas. Por exemplo:
for( int i = 0, j = 10; i < 10; i++, j-- ) { sum += i * j; } Cdigo 4-20: Comando for com expresso utilizando o ndice e variveis locais.
Muito embora todos os exemplos de utilizao do comando apresentem contadores numricos, os laos construdos com o comando for no se restringem apenas utilizao de contadores. As expresses de inicializao, teste e atualizao do comando for so todas elas opcionais. O caractere de ponto e vrgula que separa tais expresses , no entanto, obrigatrio. Se a expresso de teste omitida, presume-se que ela sempre verdadeira. Com isto, um lao infinito pode ser escrito desta forma:
for( ;; ) // for infinito
4-16
Comandos da Linguagem
4-17
Comandos da Linguagem
Comando for-each
O novo for um lao de repetio mais fcil e bonito de escrever. Este substitui o lao for atual de uma forma mais elegante para iterar sobre colees. Observe o cdigo abaixo que nos permite iterar uma coleo de alunos atravs do lao for tradicional:
Collection<Aluno> c = new ArrayList<Aluno>(); ... for (Iterator<Aluno> i = c.iterator(); i.hasNext(); ) { System.out.println( i.next().getNome() ); } Cdigo 4-22: Comando for a ser transformado em for-each
Veja que uma simples tarefa de iterar uma coleo demanda um volume considervel de cdigo. Agora observe a mesma verso deste cdigo utilizando o lao for-each juntamente com o novo import static:
Collection<Aluno> c = new ArrayList<Aluno>(); ... for ( Aluno a : c ) { out.println( a.getNome() ); } Cdigo 4-23: Comando for-each, mais simples que for
O sinal de : lido com em. Desta forma o cdigo acima pode ser lido da seguinte forma: Para cada aluno a em c. For-each tambm pode ser aplicado a arrays. Neste caso voc pode iterar um array da seguinte forma:
int[] notas = {2, 5, 7, 9, 4, 18}; int total = 0; for( int n : notas) { total += n; } out.println( total ); Cdigo 4-24: For-each para somar notas
4-18
Comandos da Linguagem
Comando break
O comando break utilizado para transferir o controle para fora do corpo do comando de lao ou switch mais prximo, transferindo imediatamente o controle para o primeiro comando aps o corpo do lao ou switch. usado, assim, para prematuramente sair de qualquer tipo de lao. Este comando muito til para abortar um lao quando algum evento ocorre durante a execuo do corpo deste lao.
break; Cdigo 4-25: Estrutura do comando break
O seguinte trecho de cdigo utiliza o comando break junto ao comando while. Ele imprime nmeros que juntos somam um valor menor que 200, iniciando
int i = 0; int total = 0; while( i < 100 ) { total += i; // total = total + i; if( total >= 200 ) { break; } System.out.println( i ); i++; }
em 0.
Cdigo 4-26: Comando break finalizando um loo while
O comando break tambm utilizado junto ao comando switch, para sair do corpo do comando. O trecho a seguir demonstra este uso.
switch( resposta ) { case 's': case 'S': System.out.println("Resposta SIM."); break; case 'n': case 'N': default: } Cdigo 4-27: Comando break finalizando um comando switch System.out.println("Resposta NO."); break; System.out.println("Resposta no reconhecida.");
O comando break pode ser utilizado tambm seguido por um label que especifica um comando presente no mtodo. Com o uso do comando break 4-19
Comandos da Linguagem
associado a um label, possvel interromper qualquer lao dentro da definio do mtodo, e no somente o lao mais prximo. Para utilizar o comando break com label, o label deve ser inserido antes do comando que se deseja interromper. O label pode ser qualquer identificador vlido, seguido por :. Um comando break especificando este label causar um pulo para o primeiro comando aps o fim do corpo do comando com este label.
label: comando { ... break label; ... } Cdigo 4-28: Estrutura de comando break para quebra de laos nomeados
O trecho de cdigo a seguir exemplifica este uso. Aps o mltiplo dos inteiros i e j atingir um valor maior que 200, o comando for associado ao label comandoFor interrompido (comando for mais externo) e a linha indicando que o mltiplo foi atingido ser impressa.
comandoFor: for( int i = 0; i < 100; i++ ) { for( int j = 0; j < 100; j++ ) { System.out.println(i*j); if (i * j >= 200) { break comandoFor; } } } System.out.println( "Fim do Comando FOR" ); Cdigo 4-29: Comando break para quebra de lao for externo comandoFor.
O comando break com label muito utilizado para interromper laos aninhados. Contudo, embora este seja um mecanismo vlido, ele pode levar a um cdigo que no claro e de difcil manuteno, sendo melhor evit-los repensando a lgica do lao.
4-20
Comandos da Linguagem
Comando continue
O comando continue usado para transferir o controle para o fim do corpo do lao, antes da re-avaliao da expresso de teste. Causa, assim, a interrupo da interao do lao corrente e o pulo para a prxima interao do lao.
continue; Cdigo 4-30: Estrutura do comando continue.
O trecho a seguir exemplifica o seu uso. Neste exemplo, o comando continue utilizado para interromper a execuo do resto do corpo do comando for em todos os nmeros pares. Ao final, a soma de todos os nmeros mpares positivos menores que 10 apresentada.
int total = 0; for( int i=0; i < 10; i++ ) { if( i % 2 == 0 ) { continue; } total = total + i; } System.out.println( total ); Cdigo 4-31: Comando continue reiniciando o lao for na prxima iterao de i
O comando continue deve ser utilizado com cuidado, pois o algoritmo resultante se torna pouco estruturado e de difcil manuteno. O comando continue pode, assim como o break, ser utilizado com um label. Um comando continue com label causar a interrupo da interao corrente e o pulo para a prxima interao do lao associado ao label.
forExterno: for( int i = 0; i < 100; i++ ) { for( int j = 0; j < 100; j++ ) { System.out.println( i*j ); if( i * j >= 200 ) { continue forExterno; } } } System.out.println( "Fim do FOR Externo" );
4-21
Comandos da Linguagem Cdigo 4-32: Comando continue para reincio de lao for externo forExterno no prximo ndice de i
4-22
Comandos da Linguagem
4-23
Comandos da Linguagem
Exerccios
1. Este exerccio far com que voc altere as classes criadas no captulo anterior adicionando algumas validaes as suas operaes. Passo 1: Na classe Produto faa uma validao do parmetro passado para operao que altera o preo do Produto. No permita preos negativos. Valide tambm o cdigo do Produto. Este deve possuir no mximo 6 caracteres. Passo 2: Na classe ItemPedido, no permita atribuir atravs do mtodo set um item do pedido ao produto se este no estiver em vendas. Faa o objeto item pedido recusar (no realizar a atribuio) o produto. Passo 3: Agora faa uma alterao na classe Aplicacao para que a mesma ao imprimir os atributos booleanos imprima as palavras Sim e No ao invs de true/false. Para isto utilize o operador ternrio. Compile e teste a aplicao. Passo 4: Altere um dos objetos produto que voc criou para que o mesmo no esteja mais em vendas. Rode novamente a sua aplicao e verifique que para o pedido com o qual voc tentou associar um produto que no estava em venda no sair dados do produto. Nesta execuo a JVM lancar tambm uma exception (NullPointerException). Passo 5: Altere o cdigo agora que faz a impresso das informaes de um ItemPedido na classe Aplicacao para que quando um ItemPedido no tenha um produto seja impresso uma string mostrando isto.
2. Crie uma classe com o nome GeradorSenhas para que nesta seja possvel gerar senhas atravs de um lao de repetio. Passo 1: Crie uma classe pblica chamada GeradorSenhas no pacote com.targettrust.java e nesta classe declare o mtodo main para que a mesma possa ser executada. Passo 2: Utilizando um lao de repetio a sua escolha (for, while, ..) faa a gerao de 10 senhas randmicas com no mximo 8 dditos.
Dica para gerar nmeros randomicamente: Utilize a classe Math do pacote java.lang. Esta possui um mtodo chamado random() que gera nmeros aleatrios entre zero e um, excluindo o inteiro um. Veja a documentao JAVADOC para mais detalhes. 4-24
Comandos da Linguagem
4-25
Comandos da Linguagem
4-26
Java Fundamentals
5-1
Objetivos
Estudar overloading e overriding Como utulizar mtodos construtores Compreender a referncia this Estudar o mtodo destrutor finalize Criar operaes com escopo de classe e instncia Compreender o mecanismo de herana Utilizar o recurso de varargs Aplicar o polimorfismo Compreender o modificador final Estudar as enumerations
5-2
Viso Geral
Mtodos de instncia so o fundamento para o encapsulamento de classes e peas chaves para fornecer uma interface consistente. Classes definidas atravs de tcnicas adequadas de encapsulamento fornecem mtodos de instncias como o nico meio de se acessar e alterar o estado de um objeto. Permitir o acesso direto s variveis de instncia de uma classe, sem que seja necessrio invocar mtodos para tal, uma tcnica de programao perigosa, pois no garante um estado sempre consistente para o objeto (o usurio no fica restrito s regras de negcios definidas na manipulao do objeto). A sobrecarga permite que uma chamada a um mtodo possua diferentes comportamentos de acordo com os parmetros passados. Suponha, por exemplo, a classe Cliente. O mtodo comprar() desta classe pode ter comportamentos distintos dependendo dos parmetros recebidos. Se a chamada for comprar(dinheiro), o comportamento invocado ser provavelmente um pagamento vista, enquanto se for comprar(cheque), outro ser o comportamento invocado, fazendo com que o dbito de pagamento possa ser realizado em um dia posterior. Sobrecarga uma tcnica poderosa, ao permitir que a classe tenha uma aparncia uniforme para o mundo externo. Construtores garantem que, a despeito de quem cria o objeto, o objeto ter as caractersticas esperadas para a classe. Ao se criar um objeto, o mtodo construtor implicitamente chamado, oferecendo um local adequado para as rotinas de inicializao. Isto ponto chave para programao orientada por objetos, j que impossvel saber quem criar novos objetos das classes que voc definiu.
5-3
Quando o usurio de uma classe chamar um mtodo sobrecarregado, o compilador escolher o mtodo correto a ser chamado analisando os parmetros passados na chamada e comparando tais parmetros com os esperados por cada um dos mtodos com aquele nome na definio da classe. Se o compilador no conseguir um casamento compatvel, mesmo aps efetuar as converses implcitas permitidas pela linguagem, um cdigo de erro ser retornado. Do contrrio, se mais de um casamento possvel, o compilador reclamar e assinalar erro de ambigidade na definio do mtodo. Mtodos sobrecarregados no podem ser diferenciados exclusivamente pelo tipo de retorno. Se a nica diferena entre a declarao de dois mtodos 5-4
for o tipo de retorno, o compilador retornar um erro e no aceitar a construo. A distino entre mtodos sobrecarregados deve sempre ter por base o nmero e os tipos de parmetros esperados.
public class Produto { private float preco; public float getPreco() { ... } sobrecarga de mtodo
public float getPreco( float desconto ) { ... } } Cdigo 5-2: Sobrecarga de mtodos.
5-5
Mtodos construtores
Mtodos construtores so chamados quando um objeto da classe estiver sendo criado. Podem ser utilizados para realizar algo no momento de criao do objeto, como por exemplo, inicializar atributos do mesmo para determinados valores. O construtor um mtodo especial chamado automaticamente pelo ambiente de execuo Java quando um objeto criado. Um construtor sempre tem o mesmo nome que a classe. Ele pode esperar nenhum, um ou vrios parmetros, mas no pode ter nenhum tipo de retorno. Veja no cdigo abaixo a declarao de um construtor:
O construtor acima conhecido como construtor default. O que acontece se um construtor no fornecido? Caso nenhum construtor seja fornecido, Java supre esta ausncia com um construtor default. Este construtor no recebe nenhum parmetro e no executa nenhuma tarefa de inicializao. possvel colocar dentro deste construtor um cdigo a ser executado no momento de criao do objeto. Assim quando o objeto da classe produto for criado utilizando o construtor acima este cdigo ser executado. Veja como pode ser criado um objeto utilizando o construtor acima:
public class CriaObjeto { public static void main(String[] args) { Produto prod = new Produto(); } } Cdigo 5-4 : Criando um objeto e chamando o construtor
Observe que o cdigo acima j havia sido utilizado anteriormente, mas agora voc pode perceber que estamos chamando o construtor default no momento da criao do objeto. 5-6
Se voc desejar, poder fornecer mais construtores na mesma classe. Desta maneira se fornecer algum construtor o compilador no mais ir;a gerar o construtor default. Entretanto, na maioria das vezes, ser necessrio declarar um ou mais construtores para a classe, a fim de permitir diferentes formas de criao do objeto, como mostrado no cdigo abaixo a criao de quatro objetos da classe produto de quatro formas diferentes:
= = = =
Para permitir que o usurio crie objetos desta maneira, ser necessrio fornecer os contrutores na classe Produto e que inicialize o estado do objeto Produto com as opes fornecidas. Construtores geralmente so declarados como public, salvo quando se deseja restringir quem pode criar objetos da classe. Veja abaixo um exemplo de construtor para a primeira e a segunda inicializao acima:
public class Produto { private String descricao; private int codigo; private float preco; public Produto(int c, String d, float p ) { codigo = c; descricao = d; preco = p; } public Produto(int c, String d) { codigo = c; descricao = d; } } Cdigo 5-6 : Construtores da classe Produto
Observe o cdigo acima e veja que alm de termos definido construtores na classe Produto para dentro dos mesmos fazer a inicializao de um produto, tambm temos overloading de construtores. 5-7
5-8
Referncia this
Esta referncia representa um objeto da prpria classe. O this referencia o objeto corrente. Todos os objetos possuem o this. Todos os mtodos de instncia recebem um parmetro implcito chamado this, que pode ser usado dentro do mtodo de instncia para se referir ao objeto corrente. O objeto corrente aquele cujo mtodo foi invocado. O parmetro this uma referncia implcita para objeto chamado e, como tal, no necessrio na maioria dos casos.
public class Produto { public void setNome(String nome) { this.nome = nome; } } public void metodo() { Produto p1 = new Produto(); Produto p2 = new Produto(); p1.setNome( "CD" ); p2.setNome( "DVD" ); }
this
p1
nome:"CD"
p2
nome:"DVD"
Dentro de um mtodo de instncia, todas as referncias no qualificadas para variveis de instncia ou mtodos de instncia esto implicitamente associadas com a referncia this. Os dois comandos dentro do mtodo setNome(), apresentados abaixo, so equivalentes:
public void setNome( String nome ) { nome = nome; // ERRO! this.nome = nome; // Forma correta }
5-9
O nome de uma varivel de instncia escondido por uma parmetro formal, de mesmo nome, do mtodo de instncia. Suponha, por exemplo, uma classe que tenha uma varivel de instncia nome, e um mtodo de instncia que recebe uma varivel tambm chamada nome. O parmetro formal nome deste mtodo esconde a varivel de instncia nome. Qualquer referncia para nome, dentro deste mtodo, acessar o parmetro formal, no varivel de instncia. Para acessar a varivel de instncia, voc deve usar this.nome.
Quando voc precisa passar uma referncia para o objeto corrente como parmetro de um outro mtodo
5-10
Um construtor pode chamar outro construtor da mesma classe usando a sintaxe this().
public class Produto { private String nome; public Produto() { this( ); } public Produto(String nome) { this.setNome( nome ); } } Cdigo 5-9: Referncia this invocando o construtor da prpria classe de acordo com os tipos de parmetros.
O primeiro construtor chama o segundo construtor passando vazio como parmetro. O segundo construtor copia a referncia para o objeto String na varivel nome. Esta tcnica garante que o nome default para todos os objetos Produto seja uma string vazia sem a necessidade de se duplicar cdigo em mltiplos construtores. A sintaxe this() minimiza a necessidade de se duplicar cdigo nos construtores. Esta tcnica especialmente til se a rotina de inicializao complexa. Toda a complexidade vai em um construtor que chamado pelos demais. Ao usar a sintaxe this() algumas regras de sintaxe devem ser observadas: A chamada para this() deve ser o primeiro comando do construtor Os parmetros de this() devem casar com os parmetros esperados por um construtor que no seja o chamador.
5-11
Em algumas linguagens como C++, uma classe pode fornecer um destrutor. Um destrutor similar a um construtor, sendo chamado automaticamente logo antes de o objeto ser destrudo. Um destrutor normalmente empregado para liberar recursos mantidos pelo objeto, tais como memria secundria alocada, arquivos abertos, etc. Java gerencia automaticamente a memria, logo um objeto no precisa explicitamente liberar memria que tenha alocado. Conseqentemente, Java no suporta destrutores. A fim de permitir que um objeto libere outro recurso que no memria (pois esta j automaticamente gerenciada), tais como arquivos abertos, Java permite que uma classe fornea um mtodo finalize(). O mtodo finalize() chamado automaticamente quando um objeto coletado pelo sistema coletor de lixo. Infelizmente, como vimos antes, no h como saber quando isto ocorrer, ou mesmo que ocorrer antes de o programa terminar. A falta de previsibilidade de quando o mtodo finalize() ser chamado inaceitvel se os recursos so escassos. A nica soluo gerenciar tais recursos manualmente. A fim de assumir o controle do processo, voc pode definir um mtodo pblico dispose() em sua classe, que os usurios da classe tero de chamar quando tiverem terminado de usar um objeto desta classe. Voc pode ainda manter o mtodo finalize() se quiser, como um ltimo esforo de liberar os recursos.
public class Produto { public void finalize() { // Libera todos os recursos alocados pela classe System.out.println( "Instncia sendo coletada pelo GC!" ); } } Cdigo 5-10: Mtodo finalize para liberao de recursos alocados pela objeto.
5-12
Variveis de instncia
Variveis de instncia so definidas dentro do bloco de cdigo da classe. As variveis de instncia so variveis que iro guardar valores especficos para cada instncia da classe. Normalmente definimos variveis/atributos como sendo de instncia. Pode-se chamar os atributos que declaramos at o momento como variveis de instncia. O padro quando declaramos atributos que os mesmos sejam de instncia. Veja o exemplo abaixo:
public class Cliente { /* Variveis/atributos de instncia */ private String codigo; private String nome; private char plano; /* Varivel de classe */ public static float desconto; } Cdigo 5-11 : Declarando vaiveis de instncia
Uma varivel/atributo de instncia pode ser acessado por um mtodo de instncia somente, ou pelo construtor da classe. Observe que no cdigo acima termos trs variveis de instncia e uma de classe declaradas no fonte. Cada varivel de instncia ter um valor especfico para o atributo. Veja a figura abaixo:
obj01
obj02
5-13
public class CriaCliente { public static void main(String[] args) { Cliente obj01 = new Cliente(); obj01.setCodigo(98) obj01.setNome(Rafael); obj01.setPlano(A); Cliente obj02 = new Cliente(); obj02.setCodigo(100) obj02.setNome(Walter); obj02.setPlano(B); } } Cdigo 5-12 : Criando objetos Cliente
5-14
Mtodos de instncia
De maneira anloga s variveis de instncias, voc utiliza o operador ponto para chamar um mtodo de instncia de um objeto. A sintaxe a
referenciaObjeto.nomeMetodo(parmetros ...);
seguinte:
Cdigo 5-13: Estrutura de chamada de um mtodo de instncia com parmetros.
Se o mtodo no espera nenhum argumento, voc deve se lembrar apenas de colocar os parntesis (uma lista vazia de parmetros):
referenciaObjeto.nomeMetodo();
No exemplo abaixo temos declaros na classe trs mtodos de instncia. Observe estes e veja que os mesmos acessam os atributos de instncia da classe.
public class Cliente { /* Variveis/atributos de instncia */ private String codigo; private String nome; private char plano; /* Mtodos de instncia */ public void setCodigo(String codigo) { this.codigo = codigo } public String getCodigo() { return this.codigo; } public boolean validar() { ... } }
5-15
Variveis de classe
Variveis de classe so variveis comparadas as variveis globais. Estas ao serem definidas iro possuir o mesmo valor para todos os objetos da classe. Uma varivel de classe, tambm chamada varivel esttica (varivel static), aquela que pertence classe e comum a todas as instncias desta classe. Em outras palavras, h somente uma instncia de uma varivel de classe, no importa quantas instncias da classe existam. Observe o cdigo que declaramos na sesso anterior quando estvamos estudando variveis de instncia. Havia uma varivel/atributo de classe. O cdigo o seguinte:
public class Cliente { /* Variveis/atributos de instncia */ private String codigo; private String nome; private char plano; /* Varivel de classe */ public static float desconto; } Cdigo 5-16 : Varivel de classe definida
5-16
O desconte seria o mesmo para ambos os objetos. Em outras palavras podemos dizer que um atributo/varivel de classe compartilhado por todos os objetos da classe. Veja como ficaria o cdigo para acesso a este atributo/varivel:
public class CriaCliente { public static void main(String[] args) { Cliente.desconto = 5.4f; Cliente obj01 = new Cliente(); obj01.setCodigo(98) obj01.setNome(Rafael); obj01.setPlano(A); Cliente obj02 = new Cliente(); obj02.setCodigo(100) obj02.setNome(Walter); obj02.setPlano(B); } } Cdigo 5-17: Acessando varivel de classe
Quando formos nos referencia a um atributo/varivel de classe devemos utilizar o nome da classe para tal e no o nome do objeto. Neste exemplo estamos acessando diretamente o atributo, porm iremos mostrar mais adiante como deve ser feito o acesso a ele via uma operao. Em Java variveis de classe so declaradas usando a palavra reservada static. No exemplo abaixo, ns declaramos a varivel de classe precoMinimo porque, obviamente, o preo mnimo se aplica a todas as instncias da classe Produto. Observe que precoMinimo foi declarada private, porque ela precisa ser acessada apenas pelos mtodos da classe Filme. Neste exemplo, a varivel precoMinimo compartilhada por todos objetos, ou seja, igual para todas as instncias de Filme, muito embora cada instncia possua sua prpria descrio e cdigo.
public class Produto { private static double precoMinimo; // var. de classe private String descricao; // var. de instncia private int codigo; // var. de instncia } Cdigo 5-18: Variveis de classe
5-17
5-18
Variveis de classe so inicializadas quando a classe carregada. Como construtores so utilizados para construir instncias (e, portanto, invocados toda vez que uma nova instncia criada), voc no pode utilizar construtores para inicializar variveis de classe. Variveis de classe possuem os mesmos valores de inicializao default que as variveis de instncia (na verdade qualquer varivel definida e no inicializada recebe um valor de inicializao default): inteiros recebem o valor 0, reais o valor 0.0, booleanos o valor false, caracteres o valor '\u0000' e referncias o valor null. Assim como as variveis de instncia, as variveis de classe tambm podem ser inicializadas com valores diferentes do valor default. Basta, para isto, utilizar
public class Produto { private static double precoMinimo = 30.50; private String nome = "CD"; private int codigo = 1234; ... }
inicializadores.
Cdigo 5-19: Declarao de variveis de classe
Rotinas complexas de inicializao de variveis de classe devem ser colocadas no bloco de inicializao esttico (tambm conhecido como inicializador esttico). Um inicializador esttico no possui nome, nem valor de retorno e comea com a palavra reservada static seguida por um bloco de cdigo delimitado por chaves (static {...}). Funciona de maneira similar a um construtor, com a diferena de que executado apenas uma nica vez e no depende das variveis de instncia de uma classe (no pode sequer referenci-las).
public class Produto { private static double precoMinimo; static { Date dataAtual = new Date(); precoMinimo = getPrecoMinimoDia( dataAtual ); } } Cdigo 5-20: Bloco static para inicializao de estruturas da classe
5-19
Mtodos de classe
Um mtodo de classe, tambm conhecido como esttico (mtodo static) , um mtodo que pertence classe e compartilhado por todas as instncia desta classe. Ao contrrio de um mtodo de instncia, uma mtodo de classe no atua sobre um nico objeto. Estes mtodos no recebem, portanto, a referncia implcita this. Um mtodo de classe pode acessar somente variveis de classe e invocar mtodos de classe. Mtodos de classe so ideais para acessar variveis de classe. De fato, eles so a nica maneira, caso no exista nenhuma instncia da classe (lembre-se: mesmo no existindo nenhuma instncia de uma classe, as variveis de classe j existem e tm um valor associado, pois so criadas quando a classe carregada pelo ambiente de execuo. No necessrio ter uma instncia da classe criada para poder acessar variveis de classe) No exemplo abaixo, o valor do preo mnimo alterado para todos os produtos, mesmo que nenhum objeto produto tenha sido criado
public class Produto { private static double precoMinimo; public static void setPrecoMinimo( float precoMinimo ) { Produto.precoMinimo = precoMinimo; } }
ainda.
Cdigo 5-21: Declarao de mtodo de classe
5-20
Voc pode chamar mtodos de classe usando uma referncia para um objeto e o operador ponto (da mesma maneira usada para mtodos de instncia), mas ainda assim, o mtodo de classe s poder acessar as variveis de classe.
5-21
variveis de classe.
Cdigo 5-24: Exemplos de mtodos estticos.
Se, no entanto, main() acessa variveis ou mtodos de instncia da prpria classe em que se encontra definido, necessrio, antes de mais que ele crie instncias desta classe. A classe Math fornece mtodos de classe para o clculo de muitas funes matemticas, tais como funes trigonomtricas e logaritmos. Fornece tambm vrias constantes de classe tais como e (2.71828) e (3.1415926). A classe System fornece vrios mtodos de classe que representam o estado de todo o sistema (ambiente computacional). System.out uma varivel de classe que se refere ao objeto PrintStream. Esta varivel de classe representa a sada padro de dados. println() um mtodo de instncia de PrintStream.
5-22
5-23
5-24
Se voc tem experincia com outras linguagens OO (orientada por objetos) tais como C++, observe que Java permite somente herana simples. Em outras palavras, uma classe pode especificar somente uma nica superclasse da qual herda. Lembre-se tambm que todas as classes em Java herdam automaticamente de uma classe raiz conhecida como Object, que se situa sempre no topo da rvore de herana. Se uma classe no especifica explicitamente uma superclasse, como no caso de Produto, ento esta classe forada a herdar diretamente de Object, sendo sua definio (implcita) equivalente seguinte definio explcita:
public class Produto extends Object { // Definio da classe Produto } Cdigo 5-26: Utilizando a clusula extends.
5-25
Objetos de subclasses
A superclasse define as variveis que so relevantes para todos os tipos de Produto, tais como nome e codigo. A subclasse CD herda estas variveis sem ter de fazer qualquer esforo, e precisa somente especificar as variveis que lhe so especficas, tais como durao. Suponha as seguintes classes:
Se voc cria um objeto Produto, ele apenas contm as variveis definidas para Produto:
Produto produto = new Produto(); Cdigo 5-27: Criando um novo Produto.
Entretanto, se voc cria um objeto CD, ele conter cinco variveis de instncia: as trs herdadas de Produto mais as duas que ele prprio CD definiu.
CD cd = new CD(); Cdigo 5-28: Criando um novo CD
Variveis de instncia devem normalmente ser declaradas private, o que significa que instncias de subclasses herdam os valores, mas no podem acesslos diretamente. Como visto anteriormente, voc deve definir, mtodos para acessar variveis privadas. Voc pode definir mtodos na subclasse ou herd-los da superclasse. 5-26
Ao invs de inicializar preco, nome e codigo explicitamente, tudo o que o construtor de CD deve fazer chamar o construtor de sua superclasse. Isto pode ser feito usando a palavra reservada super. A chamada super(...) deve ser o primeiro comando do construtor.
public CD(float preco, String nome, int codigo, String produtor, int duracao) { super( preco, nome, codigo ); setProdutor( produtor ); seDuracao( duracao ); } Cdigo 5-30: Invocando o construtor da superclasse a partir da referncia super.
Se voc no chamar explicitamente super(...) o compilador chamar automaticamente o construtor sem parmetros. Se a superclasse no tiver um construtor sem parmetros, o compilador acusar um erro.
public Produto(float preco, String nome, int codigo) { setPreco( preco ); setNome( nome ); setCodigo( codigo ); }
public CD(float preco, String nome, int codigo, String produtor, int duracao) { super( preco, nome, codigo ); setProdutor( produtor ); seDuracao( duracao ); }
5-27
5-28
Sobrecarga de mtodos quando voc define mltiplos mtodos com mesmo nome e diferentes assinaturas. Mtodos sobrecarregados so resolvidos em tempo de compilao (resolver um mtodo descobrir qual verso do mtodo deve ser chamada com base nas informaes dadas pelo programador), com base no nmero e tipo dos parmetros fornecidos.
Sobrescrita de mtodos quando voc fornece um mtodo com exatamente o mesmo nome e assinatura que este mtodo possui em uma superclasse. Mtodos sobrescritos so resolvidos em tempo de execuo. Esta tcnica conhecida como polimorfismo e ser discutida mais adiante.
5-29
O exemplo acima mostra alguns dos mtodos declarados pela subclasse e pela superclasse. A superclasse define mtodos que so relevantes para todos os tipos de Produto. A subclasse CD herda estes mtodos da superclasse, e tem de adicionar apenas os mtodos que lhe so especficos (relevantes para todos os objetos CD), tais como recuperao do produtor do CD e durao. Quando voc cria um objeto, voc pode chamar qualquer um dos seus mtodos pblicos (public), bem como qualquer mtodo declarado pblico em uma de suas superclasses. Se voc, por exemplo, cria um objeto Produto, voc pode chamar os mtodos pblicos definidos em Produto, bem como quaisquer mtodos pblicos de sua superclasse Object:
Produto produto = new Produto(); float preco = produto.getPreco(); // mtodo public de Produto Class classe = produto.getClass(); // mtodo public de Object Cdigo 5-33: Criando um Produto e acessando mtodos herdados.
5-30
Se voc cria um objeto CD, voc pode chamar mtodos pblicos definidos em CD, Produto e Object.
CD int float Class cd duracao preco classe = = = = new CD(); cd.getDuracao() // mtodo public de CD cd.getPreco(); // mtodo public de Produto cd.getClass(); // mtodo public de Object
Para sobrescrever um mtodo de uma superclasse, a subclasse define o mtodo exatamente com a mesma assinatura e tipo de retorno que o mtodo possui quando declarado na superclasse. O mtodo da subclasse efetivamente esconde o mtodo declarado na superclasse. importante ter certeza de que o mtodo na subclasse mantm a mesma semntica que o mtodo que est sendo sobrescrito. Qual mtodo chamado? No exemplo acima, a classe Produto fornece um mtodo getPreco() e a classe CD sobrescreve este mtodo com uma verso mais especializada. Se voc criar um objeto Produto e chamar getPreco(), o mtodo chamado ser a verso definida em Produto.
5-31
Se voc criar um objeto CD e chamar getPreco(), o mtodo chamado ser a verso especializada definida em CD.
5-32
Referncia super
A referncia super til quando a classe possui um ancestral. Uma subclasse herda todos os mtodos e variveis de sua superclasse, bem como define ela prpria. Mtodos da superclasse podem ser sobrescritos na subclasse, bastando a subclasse declar-los novamente e redefinir o seu comportamento (declarar novamente significa manter a assinatura do mtodo tal qual se encontra na superclasse alterando apenas o corpo do mtodo). A palavra reservada super permite que voc acesse mtodos da superclasse sobrescritos pela subclasse. Um dos usos mais comuns de super chamar os construtores da classe pai. Quando a superclasse foi projetada, um construtor provavelmente foi declarado para garantir a inicializao correta de qualquer novo objeto. Como a subclasse herda todas as variveis da superclasse, tais variveis precisaro ser inicializadas para objetos da subclasse tambm. A palavra reservada super permite que voc use o cdigo do construtor definido na superclasse sem ter que duplicar o cdigo em cada subclasse. Adicione a referncia super no construtor da subclasse a fim de acessar o
class SubClasse extends SuperClasse { ... public SubClasse(int param) { super(param); /* coloque aqui o cdigo especfico do construtor da subclasse */ } }
construtor da superclasse:
Cdigo 5-36: Estrutura de chamada explcita do construtor da superclasse
A regra de sintaxe que a palavra reservada super deve ser, neste caso, a primeira linha do construtor da subclasse. A palavra reservada super pode ser usada tambm para acessar os mtodos da superclasse. Exemplo de uso da referncia super:
public class Produto { private String nome; public Produto( String nome ) { super(); this.nome = nome; } }
5-33
public class Filme extends Produto { private int ano; public Filme( String nome, int ano ) { super( nome ); this.ano = ano; } Cdigo 5-37: Referncia super invocando o construtor da superclasse
No exemplo acima, h rotinas de inicializao que devem ocorrer para todos os objetos Produto. Estas rotinas so colocadas nos construtores de Produto. Tais rotinas devem sempre ser usadas, no interessando o tipo do Produto sendo construdo, seja ele um CD, um Filme ou um Livro (subclasses de Produto). H tambm construtores em cada uma das subclasses encarregados de rotinas de inicializao especficas destas subclasses. O construtor de Filme reutiliza o construtor de Produto ao referenci-lo com a palavra reservada super. Este comando o primeiro comando do construtor de Filme e pode ser seguido por quaisquer comandos que se fizerem necessrios para uma adequada inicializao de objetos Filme.
5-34
Se, por exemplo, o programa criar um objeto CD e chamar o mtodo getPreco(), ele sempre estar executando a verso de getpreco() definida
CD cd = new CD(); // Cria objeto CD float v = cd.getPreco(); // Executa verso getPreco() de CD
em CD.
Cdigo 5-39: Executando o mtodo getPreco()
Dentro do mtodo getPreco() definido na classe CD pode-se invocar o mtodo escondido de mesmo nome e assinatura, definido na superclasse Produto, atravs da palavra reservada super. A palavra reservada super similar a this, salvo que atua como referncia para o objeto corrente como uma instncia da superclasse. Chamar um mtodo escondido da superclasse usando super evitamos duplicar o cdigo contido no mtodo escondido. Ao reduzir o volume de cdigo duplicado, facilita-se a tarefa de manuteno do software.
5-35
Visibilidade protected
A visibilidade protected no foi demonstrada anteriormente pois o uso da mesma envolve o processo de herana. Agora que j vimos este recurso estamos aptos a estudar esta visibilidade. Vejamos o cdigo abaixo:
package com.targettrust.java; public class Funcionario { private String nome; protected float salario; ... } Cdigo 5-40: Visiblidade protected aplicada a atributos
O cdigo acima define uma classe Funcionrio, a qual possui na sua estrutura um nome e um salrio. Perceba que o nome privado enquanto o salrio protected. O atributo nome poder ser acessado somente por operaes definidas dentro da classe, porm o atributo salrio poder ser acessado diretamente por outras classes que forem filhas de Funcionario. Isto poder ser feito mesmo com a classe filha em outro pacote diferente do pacote onde estiver o Funcionrio. Veja exemplo abaixo:
package com.targettrust.rh; public class Vendedor extends Funcionario { private float comisssao; ... public void calcularSalario() { ... float total = salario + comissao; } } Cdigo 5-41: Acessando um atributo protected
Veja que o acesso ao atributo acessado na classe filha como se fosse declarado na mesma classe. J o atributo privado no pode ser acessado. Esta visibilidade tambm pode ser aplicada a operaes da classe, porm o uso dela nestes casos no comum.
5-36
Varargs
Varargs um recurso popular em algumas linguagens como C, C++ e linguagens derivadas. Este recurso permite passar um nmero varivel de parmetros a um mtodo sem a necessidade de encapsul-los manualmente em um array. Junto com varargs ser utilizado o recurso de autoboxing. Veja o exemplo abaixo utilizando este recurso:
public class Varargs { public static void main(String[] args) { foo("Java", "Oracle", "Linux"); foo("Porto Alegre", "Ijui", "So Leopoldo", "Cruz Alta"); } public static void foo(String... args) { for (int i=0; i<args.length; i++) { System.out.println(args[i]); } } } Cdigo 5-42: Usando varargs para receber mais de um parmetro
A declarao acima String... args equivale a String[] args, mas se utilizado este recurso deve ser o ltimo parmetro do mtodo. Quando este mtodo for chamado na chamada podem ser passados vrios parmetros separados por vrgula desde que os tipos sejam sempre Strings. O enpasulamento dos parmetros String em um vetor ser feito de forma automtica pelo compilador. Se o tipo de parmetro um Object, ento os parmetros se forem tipos primitivos sero transformados em objetos com o recurso de autoboxing. Para evitar este overhead da transformao de tipos primitivos nos objetos correspondentes utilizando o recurso de autoboxing, voc pode utilizar, por exemplo int... args. Se voc tentar passar parmetros com tipo incorretos, portanto no esperados pelo mtodo, o compilador ir perceber e avisar. Veja exemplo abaixo:
public class Varargs { public static void main(String[] args) { foo("Java", "Oracle", "Linux", 88); // Erro nesta linha! } public static void foo(String... args) { for (int i=0; i<args.length; i++) { System.out.println(args[i]); } } }
5-37
Aprofundando o estudo sobre classes Cdigo 5-43: Erro pois esta pasando inteiro e no String
5-38
Polimorfismo
Usando a tcnica de polimorfismo visualize a seguinte hierarquia de classes.
Ao projetar a aplicao de venda, no era sabido todo o tipo de produtos que seriam vendidos em longo prazo. Em programao no orientada por objetos, isto criaria um problema, que seria resolvido alterando o cdigo sempre que um novo tipo de item fosse adicionado. Em Java, ns podemos usar polimorfismo para resolver este problema. Eis como: O mtodo getPreco() da classe Produto sobrescrito pelas classes CD e DVD, cada qual fornecendo uma verso especializada do mtodo. A classe CarrinhoCompras possui um mtodo addItem(Produto produto) que chama o mtodo getPreco() atravs da referncia recebida a um objeto Produto. Em tempo de execuo Java interroga o parmetro de addItem() para descobrir o tipo real do objeto e se o objeto possui alguma funo sobrescrita. Se sim, Java usa o mtodo sobrescrito pela subclasse (CD ou DVD), ao invs de usar o mtodo definido pela superclasse (Produto).
5-39
O mais importante que as classes CarrinhoCompras e Produto no precisam ser modificadas quando novos tipos de itens de inventrios forem sendo adicionados ao negcio.
5-40
Modificador final
Por default todas as variveis e mtodos podem ser sobrescritos. Especificar uma varivel como final evita que seu valor seja alterado. Isto til para garantir que um determinado valor seja consistente entre todos os usurios de uma classe. Voc pode tambm declarar uma classe como final. Uma classe final no pode ser superclasse de nenhuma outra classe. Em outras palavras, no se pode herdar de uma classe final. Ao declarar uma classe como final voc est tomando uma importante deciso de projeto, pois est dizendo que tal classe completa o suficiente para atender todas as expectativas presentes e futuras de seus usurios, e que, portanto, nunca ser necessrio estend-la para fornecer alguma funcionalidade adicional. Um mtodo final no pode ser sobrescrito por nenhuma subclasse. Em outras palavras, se o programador herda de uma classe, no ser permitido que ele fornea uma verso alternativa de um mtodo declarado como final na superclasse. Esta uma tcnica til para evitar que programadores inadvertidamente ou maliciosamente redefinam mtodos essenciais que devem funcionar de uma maneira esperada. Resumindo: Uma varivel final uma constante Uma varivel final no pode ser modificada Uma varivel final deve ser inicializada Uma varivel final geralmente pblica (public), permitindo o acesso externo
public final class Color { public final static Color BLACK = new Color(0,0,0); // ... } Cdigo 5-45: Variveis final
Mtodos e classes so declarados final por suas razes principais: segurana e otimizao. 5-41
Se um mtodo executa alguma operao vital, tal como validao de identidade ou verificao de autorizao, ele deve ser declarado final, a fim de evitar que seja sobrescrito por um mtodo mal-intencionado que esteja procurando se esquivar das verificaes de segurana. Muitos dos mtodos definidos nas classes do pacote java.net so declaradas final. Se voc declara uma classe como final, ela no poder nunca mais ser estendida por nenhuma outra classe. Esta uma deciso de projeto importante, pois afirma que a classe atende a todas as necessidades presentes e futuras de seus usurios. Esta implicao clara: voc no precisa.
public final class Criptografia{ private String senha; public final void getSenha(String senha) { getCriptografia(senha, 128) // Chama Criptografia de 128 bits } } Cdigo 5-46: Definindo uma Classe e um mtodo final.
5-42
Enums
Enums uma forma mais fcil e segura para representar um conjunto de valores que so conhecidos em tempo de compilao e que no mudam com o passar do tempo. Estes valores so muitas vezes conhecidos como constantes de classe. A partir da nova verso do java, a verso 1.5, foi includo este novo tipo que trs algumas vantagens listadas abaixo. Veja inicialmente o padro que se costuma utilizar para representar constantes e guardar estaes do ano:
public static final public static final public static final public static final Cdigo 5-47: Constantes int ESTACAO_INVERNO int ESTACAO_PRIMAVERA int ESTACAO_VERAO int ESTACAO_OUTONO de classe = = = = 0; 1; 2; 3;
No seguro Uma vez que uma estao um int, voc pode passar qualqeur outro valor diferente dos especificados nas constantes acima, ou mesmo somar estas constantes, o que no faria sentido. Prefixar constantes Voc precisa prefixar as constantes com strings para evitar colises de nomes semelhantes. Este caso foram prefixadas com a palavra ESTACAO. Os valores impressos no so informativos Por serem constantes do tipo int estas constantes quando impressas no tem significado claro. Ao imprimi-la teremos um int e no um nome.
Tipos enum so cosiderados como objetos, acima temos a definio de um tipo Estacao. Uma enumeration herda da classe java.lang.Enum possuindo desta forma vrios mtodos para se poder manipular a estrutura. Mtodos de Object tambm esto presentes em uma Enum. Comparable e Serializable so interfaces implementadas pelas enumerations, permitindo que as mesmas portanto possam ser comparadas e serializadas.
5-43
Neste cdigo acima observe que definimos um tipo Estacao e o mesmo utilizado mais abaixo para passar valores ao mtodo foo. Quando desejarmos imprimir o nome da estao passada como parmetro atravs de enum podemos utilizar o mtodo name(), a ordem dos valores adicionada de forma automtica e comea em 0. possvel pegar de uma enumeration todos os seus valores atravs de um mtodo esttico values(). Este mtodo facilita bastante a impresso dos valores quando desejarmos. Veja o cdigo abaixo:
for(Estacao s : Estacao.values() ) { out.println( s.name() + " " +s.ordinal() ); } Cdigo 5-50: Percorrendo uma enumeration
5-44
5-45
Exerccios
1. Neste exerccio voc deve criar uma classe para representar um Curso. Esta classe ter mtodos sobrecarregados (overloading) e redefinidos (overriding), bem como ser uma classe filha da classe Produto e ter construtores para que seja possvel criar objetos da mesma j passando informaes na hora da criao. Passo 1: Crie uma classe pblica Curso no pacode com.targettrust.venda e faa com que esta classe extenda (herde) a classe Produto. Na classe Curso defina os seguines atributos e constante privados:
private int cargaHoraria; private char turno; private final float VALOR_HORA = 100f;
Passo 2: Defina na classe Curso um mtodo para calcular o preo do curso ( public float getPreco() {...} ). Observe que este tem o mesmo nome do mtodo que est sendo herdado da classe Produto. Na assinatura deste faa com que o mesmo possa receber um valor hora ( public float getPreco(float valorHora) {...} ) a ser levado em considerao no clculo do preo do curso. O preo do curso deve ser calculado multiplicando-se a carga horria pelo valor hora passado como parmetro no mtodo. Passo 3: Crie outro mtodo na classe Curso que seja capaz de redefinir o comportamento (overriding) do mtodo public float getPreco() herdado da classe Produto. Esta operao deve retornar o preo levando em considerao o valor hora e a carga horria do curso, para isto utilize o valor hora da constante. Passo 4: Na classe Produto, bem como na classe Curso, defina um construtor que permita criar um objeto destas classes passando valores para todos os seus atributos. Isto ir fazer com que o construtor default no seja adicionado pelo compilador java. Desta forma adicione tambm ele a estas classes. Passo 5: No construtor da classe Curso faa com que o mesmo repasse os parmetros que este receber e que devem ser atribudos para os atributos da classe Produto para o construtor da classe Produto. Use para isto a referncia super(...). Passo 6: Agora voc ir modificar as classes que criou at o momento para que as operaes sets da classe Produto, ItemPedido e Curso possam receber parmetros com o mesmo nome dos atributos. Use a referncia this nestas classes para referenciar o atributo na hora da atribuio e defina o nome do parmetro 5-46
com o mesmo nome do atributo. Gere novamente a documentao para estas classes e verifique as alteraes. Passo 7: Na classe Curso defina o mtodo destrutor finalize() e dentro deste faa a impresso de uma string sinalizando que o mesmo est sendo executado. public void finalize() { ... } Passo 8: Crie agora uma classe pblica TestaCurso no pacote com.targettrust.venda, declare nesta classe o mtodo main e dentro deste mtodo crie um objeto da classe Curso. Atribua informaes para este objeto atravs do mtodo construtor. Logo em seguida mostre os dados do objeto atravs dos seus mtodos de leitura, os gets. Passo 9: Atribua null para a referncia criada que representa o curso e logo em seguida chame o mtodo System.gc() para ativar o coletor de lixo e constatar a execuo do mtodo destrutor. Passo 10: Na classe Curso crie um bloco esttico de cdigo para sinalizar quando a classe est sendo carregada pela JVM. Neste bloco esttico imprima uma mensagem.
5-47
Java Fundamentals
6-1
Objetivos
Estudar a API Collection Utilizar classes StringBuffer e StringBuilder Converter e encapsular dados com Wrapper Classes Utilizar arrays Compreender o mecanismo de autoboxing Utilizar generics
6-2
Strings
Assim como na maioria das linguagens de programao, strings so usadas intensivamente em Java. Desta forma, a API Java fornece uma classe String para ajud-lo a manipular seqncias de caracteres. Literais de string so transformados pelo compilador Java em objetos String. Eles podem ento ser usados diretamente, passados como argumentos para mtodos ou atribudos a variveis do tipo String.
System.out.println( "Hello World!" ); String str = "Matrix"; Cdigo 6-1: Manipulao de Strings.
A classe String representa uma string imutvel. Isto significa que, uma vez criado um objeto String, voc no poder mais alter-lo. Se voc quiser modificar o contedo de uma string, voc dever usar a classe StringBuffer. Esta classe ser estudada logo adiante.
6-3
Criando Strings
A maneira mais fcil de se criar uma string a partir de uma constante colocada entre aspas duplas, como mostra o exemplo abaixo:
String produto = "Caneta"; Cdigo 6-2: Atribuio de valor String.
Voc pode usar o operador mais (+) para concatenar dois objetos String. Isto explicado em maiores detalhes adiante. Veja um exemplo do uso do operador mais (+) quando aplicado a objetos String:
String nomeEmp = primeiroNome + " " + ultimoNome; Cdigo 6-3: Concatenao de Strings entre variveis e String fixa.
A classe String fornece vrios construtores. Eis aqui alguns dos construtores mais teis: String() cria uma string vazia, com o valor "" String(String str) cria uma cpia do objeto String referenciado por str String(char[] arr) cria uma string a partir dos caracteres presentes no vetor arr
// uso de construtores String nomeEmp = new String( "Maria Isabel" ); Cdigo 6-4: Criao de String utilizando o construtor da classe String.
Voc encontrar uma lista de construtores na documentao do JDK para a classe String. A classe String parte do pacote java.lang. java.lang um pacote automaticamente importado por todas as classes Java. No preciso, portanto, declarar um comando explcito de import para poder usar a classe String em seu cdigo.
6-4
Concatenando Strings
Java usa o operador + para concatenao de strings. O mtodo concat() de String outra forma de se concatenar strings. O seguinte cdigo produz strings equivalentes:
// Concatenao String nome = "Carlos Silva"; nome = "Carlos " + "Silva"; nome = "Carlos ".concat("Silva"); Cdigo 6-5: Exemplos de concatenao de Strings.
O exemplo abaixo mostra um tipo primitivo (no caso um int) sendo concatenado com uma String. O tipo primitivo convertido implicitamente para String:
int codigo = getCodigo(); System.out.println("Cdigo: " + getCodigo() + "."); Cdigo 6-6: Converso de tipos primitivos para String.
Literais de string no podem se estender por mais de uma linha, mas voc pode concaten-los e produzir o mesmo efeito:
String soneto = "De tudo ao meu amor serei atento\n" + "Antes e com tal zelo, e sempre, e tanto\n" + "Que mesmo em face de maior encanto\n" + "Dele se encante mais meu pensamento.";
6-5
O mtodo charAt() retorna o caractere especificado pelo ndice passado como argumento para o mtodo (os ndices sempre comeam em 0).
// String s char c 01234 = "Maria"; = s.charAt(2); // c = 'r'
O mtodo substring() retorna uma substring especfica (dois argumentos so fornecidos a este mtodo: o ndice do primeiro caractere da substring e o ndice do caractere aps o ltimo caractere da substring desejada).
// 01234 String s = "Maria"; String sub = s.substring(2,4); // sub = "ri" String sub = s.substring(2); // sub = "ria" Cdigo 6-10: Produzindo substrings.
O mtodo toUpperCase() retorna uma nova string contendo uma verso da anterior com todos os caracteres convertidos para a forma maiscula. O mtodo toLowerCase() retorna uma nova string contendo uma verso da anterior com todos os caracteres convertidos para a forma minscula.
String s = "Maria"; String M = s.toUpperCase(); // M = "MARIA" String m = s.toLowerCase(); // m = "maria" Cdigo 6-11: Transformando uma String para maisculo e minsculo.
O mtodo trim() retorna uma nova string contendo uma cpia da string original com espaos em branco removidos tanto no incio quanto no final.
String s = " Cadastro de Clientes "; String t = s.trim(); // t = "Cadastro de Clientes" Cdigo 6-12: Truncando espaos de uma String.
6-6
O mtodo indexOf() retorna o ndice de uma determinada substring. O mtodo lastIndexOf() retorna o ndice da ltima ocorrncia de uma string determinada.
// 0 1 2 // 012345678901234567890 String s = "fbrica de brinquedos"; int iof = s.indexOf("bri"); // iof = 2 int liof = s.lastIndexOf("bri"); // liof = 11 Cdigo 6-13: Busca ndices de ocorrncias de substring dentro de uma String.
H vrias verses para cada um destes mtodos. D uma olhada na documentao da classe String para maiores detalhes sobre cada uma delas.
6-7
O mtodo equals() retorna true se as strings especificadas contm o mesmo texto. Caso a string passada como parmetro seja null, equals() retorna false. Importante: o mtodo equals() diferencia maisculas de minsculas!
String senha = getSenha(); if(senha.equals("brasil2010"))
O mtodo equalsIgnoreCase() similar a equals(), exceto que ignora diferena entre maisculas e minsculas.
String cat = getCategoria(); if(cat.equalsIgnoreCase("Drama")) Cdigo 6-15: Comparao de Strings case insensitive.
No use o operador == para comparar objetos String! O operador == retorna true dependendo da JVM quando ambas as variveis referenciarem o mesmo objeto.
6-8
O que acontece quando a classe no fornece o mtodo toString()? Se a classe no fornece o mtodo toString(), ela herda um da classe Object. A string produzida por Object.toString() no muito amigvel. Consiste do nome da classe da qual o objeto uma instncia e um nmero hexadecimal representando uma entrada hash.
6-9
Quando um tipo primitivo concatenado com uma string, ele automaticamente convertido para String atravs de String.valueOf(). Quando um tipo primitivo passado para System.out.println(), a verso apropriada de System.out.println() chamada. H uma verso para cada tipo primitivo.
6-10
Wrapper Classes
Para cada tipo primitivo, Java fornece uma classe invlucro (wrapper class) correspondente. Estas classes permitem que um tipo primitivo seja manipulado como se fosse um objeto. Cada classe invlucro fornece um mtodo esttico para converter uma string para o tipo primitivo correspondente.
Tipo Primitivo boolean char byte short int long double float
Classe invlucro correspondente Boolean Character Byte Short Integer Long Double Float
6-11
Quantidad Preo:
17 425.00
Cdigo 6-19: Convertendo String para o tipo primitivo correspondente de acordo com a Wrraper Class.
O que acontece se o usurio entra com um valor no inteiro no primeiro campo? Caso isto acontea, parseInt() ir falhar e levantar uma exceo. Para tratar esta situao, seria necessrio colocar cdigo adicional para capturar e tratar a exceo levantada, tanto por parseInt(), quanto por parseFloat(). Excees sero estudadas mais adiante. O cdigo acima poderia ser feito da
int qtd = Integer.parseInt(qtdCampo.getText()); float prc = Float.parseFloat(prcCampo.getText()); // Suprimimos a declarao de variveis
seguinte forma:
Cdigo 6-20: Convertendo String para o tipo primitivo correspondente de acordo com a Wrraper Class.
6-12
StringBuffer e StringBuilder
StringBuffer e StringBuilder representam strings que podem ser modificadas e estendidas em tempo de execuo. A primeira deve ser utilizada quando mais de uma thread estiver utilizando o objeto j a segunda quando somente uma thread estiver o utilizando pois o acesso a a mesma mais rpida. Estas estruturas permitem voc adicionar dados a um objeto sem que o mesmo precise ser recriado como o caso da String. Estas estruturas so estruturas mutveis ao contrrio da String que imutvel. O seguinte exemplo cria trs novos objetos String e copia todos os caracteres cada vez que um novo objeto String criado. Isto gera um overhead grande e deixa muitos objetos na memria para que o garbage collector os recolha.
String texto = "O texto comea com uma linha\n"; texto = texto + "E ganha outra linha\n"; texto = texto + "E mais uma...\n";
StringBuffer tambm fornece um comportamento semelhante a StringBuilder porm esta uma estrutura que possui os seus mtodos sincronizados, o que deixa o acesso aos mesmos mais lento quando temos somente uma thread acessando o objeto. Voc deve procurar utilizar StringBuilder em vez de StringBuffer. Veja abaixo um exemplo de StringBuilder e observe que a forma de uso dos mesmos igual.
StringBuilder sb = new StringBuilder(); sb.append("Java J2EE\n"); sb.append("Oracle\n"); sb.append("PostgreSQL\n"); System.out.println(sb); Cdigo 6-23: Utilizando StringBuilder
6-13
Arrays
Um vetor uma coleo de variveis do mesmo tipo. Cada elemento pode armazenar um nico item. Os itens de um vetor podem ser de tipos primitivos ou referncias para objetos. O comprimento de um vetor fixo, quando criado. Vetores so teis quando voc deseja um grupo de objetos que possam ser manipulados como um todo. Caso voc, por exemplo, escreva um programa para permitir a pesquisa por um filme, voc provavelmente armazenar a lista de categorias em um vetor.
6-14
De maneira esquemtica, temos: 1. Declare a varivel de referncia que ir receber a referncia para o objeto vetor
6-15
A maioria dos programadores Java usa o primeiro estilo porque ele separa o tipo da varivel (no exemplo acima int) do nome da varivel, tornando o cdigo mais legvel. Quando voc declara uma varivel de referncia para vetor, ela inicialmente recebe o valor null, at que o vetor seja efetivamente criado usando new.
6-16
Criando arrays
Vetores devem ser criados usando o operador new. O tamanho do vetor deve ser especificado entre colchetes.O tamanho deve ser um inteiro, mas no precisa ser necessariamente uma constante. Pode ser uma expresso avalivel somente em tempo de execuo. Uma vez que um vetor criado, o seu tamanho permanece o mesmo por toda a existncia do vetor.
Todos os elementos de um novo vetor de tipos primitivos recebem automaticamente o valor default para o tipo: Elementos char recebem '\u0000'; Elementos byte, short, int e long recebem 0; Elementos float e double recebem 0.0; Elementos boolean recebem false.
// CONSTRUES VLIDAS // exemplo 1: tamanho uma constante final int TAM = 4; int[] nums = new int[TAM]; // exemplo 2: tamanho conhecido apenas em tempo de execuo int[] notasExame; int n = getTotalAlunos(); notasExame = new int[n]; Cdigo 6-24: Contrues vlidas de vetores. // CONSTRUES INVLIDAS // exemplo 1: o tamanho no faz parte da declarao do vetor int nums[4]; // exemplo 2: n no foi devidamente inicializada int n; int[] nums = new int[n]; Cdigo 6-25: Contrues invlidas de vetores.
6-17
Inicializando arrays
Primeiro Mtodo: Atribua um valor para cada elemento
Para se referir a um elemento do vetor use um ndice entre colchetes como mostrado no exemplo abaixo. Os elementos de um vetor so indexados de 0 a n-1, onde n o nmero de elementos do vetor. Em outras palavras, o ndice do primeiro elemento de um vetor sempre 0 e no 1.
Figura 6-9: Declarao, criao e inicializao de vetor a partir de lista de valores int.
Inicializadores de vetor so muito teis para criar tabelas de pesquisa, como mostrado no seguinte exemplo:
int [] diasMes = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
Cdigo 6-26: Declarao, criao e inicializao de vetor a partir de lista de valores String.
6-18
Este mtodo til quando o valor de cada elemento conhecido quando o vetor criado.
6-19
Arrays de objetos
Os passos para criar um vetor de referncias so os mesmos que para criar um vetor de tipos primitivos, com uma nica exceo: voc deve sempre inicializar os elementos do vetor porque isto no feito automaticamente.
exemplo:
Cdigo 6-27: Declarao de vetor String.
exemplo:
Cdigo 6-28: Criao do vetor String com tamanho 3
A linha acima cria um objeto vetor do tipo String e de tamanho 3. Todos os elementos, no incio, recebem o valor null. 3. Inicializao: Inicialize os elementos do vetor para o valor que desejar. Isto ser visto com mais detalhes logo adiante.
6-20
6-21
// Inicializadores String[] produtos = {"CD", "DVD", "VHS", "MP3"} Cdigo 6-30: Criando vetor de String a partir de uma lista de Strings.
A Propriedade length
Cada vetor tem um atributo length que contm o nmero de elementos do vetor. Ao usar length, voc evita ter de armazenar o tamanho do vetor em outra parte de seu cdigo. A classe System fornece um mtodo til para copiar todo ou parte de um vetor para outro vetor. Para maiores informaes, consulte System.arrayCopy() na documentao do J2SDK.
6-22
6-23
Arrays e Excees
Excees so levantadas dependendo de como vetores so manipulados. Caso voc tente acessar uma posio invlida de um vetor, o programa ser interrompido pela exceo ArrayIndexOutOfBoundsException. Caso tente acessar um elemento de um vetor que no tenha sido inicializado, a exceo NullPointerException ser levantada.
// Exceo ArrayIndexOutOfBoundsException String[] lista = new String[4]; System.out.println(lista[5]); // Exceo NullPointerException Produto[] listaProdutos = new Produto[3]; String nomeProduto = listaProdutos[0].getNome(); Cdigo 6-32: Excees comuns a partir de vetores.
6-24
Arrays multidimensionais
Java suporta vetores multidimensionais, isto , vetor de vetores.
int[][] matriz = new int[4][2]; Cdigo 6-33: Declarando e criando uma matriz.
A linha acima declara e cria uma matriz bidimensional: a matriz contm cinco linhas e cada uma das linhas possui quatro colunas. Elementos individuais podem ser acessados da seguinte maneira:
matriz[indiceLinha][indiceColuna] = valor; Cdigo 6-34: Esquema de acesso a uma matriz.
O seguinte exemplo cria um vetor multidimensional com dez linhas, mas o nmero de colunas por linha diferente. A primeira linha possui apenas um elemento, a segunda dois, a terceira trs e assim por diante.
int[][] a = new int[10][]; for(int i=0; i<a.length; i++) { a[i] = new int[i+1]; } Cdigo 6-35: Criao de matriz com nmero de colunas diferentes.
6-25
Strings:
Cdigo 6-36: Recepo de parmetros utilizando J2SDK 1.5.
6-26
API Colletion
Em Java a API Collection referenciada como um framework. Este framework fornece um conjunto bem defindo de interfaces e classes para armazenar e manipular grupos de dados, conhecidos como colees. Este framework fornece uma conveniente API para muitos dos tipos de dados abstratos das estruturas: Map, Set, List, Tree, Array, Hashtable e outras colees. Este frameword est dentro do pacote java.util, desta forma este pacote deve ser sempre importado quando se desejar trabalhar com colees. Uma simples collection no coloca nenhuma restrio sobre os tipos de elemento, ordem dos elementos, ou repetio dos elementos dentro da collection. Em java,a interface java.util.Collection define a collection bsica de framework para todos tipos de collections. A Interface Collection possui mtodos que permitem voc adicionar itens, remover itens, pesquisar, e contar o nmero de elementos na collection.
Principais mtodos:
- boolean add(Object element) - boolean remove(Object element) - void clear() - int size() - boolean isEmpty() - Object[] toArray()
6-27
A interface Iterator
Um Iterator um objeto que pode ser utilizado para percorrer colees. Com os mtodos da interface Iterator, voc pode percorrer uma collection do incio ao fim e de forma segura remover os elementos da Collection. O iterator geralmente usa operaes de busca.
Veja abaixo o cdigo exemplo para percorrer uma coleo do tipo ArrayList utilizando a interface iterator
ArrayList lista = new ArrayList(); ... Iterator it = lista.iterator(); while ( it.hasNext() ) { String s = (String)it.next(); ... } Cdigo 6-37: Iterator
6-28
A interface Enumeration
A interface Enumeration permite voc percorrer todos os elementos de uma collection. Percorrer uma collection com uma Enumeration semelhante a percorrer com um Iterator. Emumeration no oferece suporte para remover elementos, coisa esta que voc pode fazer com um Iterator.
Mtodos: - boolean hasMoreElements(); - Object nextElement(); Veja abaixo um exemplo de cdigo para percorrer uma Enumeration:
Hashtable tabela = new Hashtable(); ... Enumeration elementos = tabela.elements(); while ( elementos.hasMoreElements() ) { Produto p = (Produto)elementos.nextElement(); ... } Cdigo 6-38 Enumeration
6-29
Interfaces do framework
Neste framework existem vrias interfaces que podem ser utilizadas, estas interfaces so estruturas que permitem armazenar objetos de formas especficas. Vamos ver algumas delas abaixo.
Interface Set
No conceito matemtico, um conjunto justamente um grupo de itens nicos, sem elementos duplicados. A interface Set estende a interface Collection. Set no permite duplicatas dentro da collection. Na implementao Set, null uma entrada vlida, mas permitida somente um por vez.
Interface List
Como o prprio nome j nos diz, representa uma lista que permite duplicatas. A interface List estende a interface Collection. Existem duas List implementations disponveis na Collections Framework: ArrayList e LinkedList.
A Interface Map
Um map um tipo especial de grupo sem duplicatas. Dentro da Collections API, java.util.Map define esta interface. Ele mapeia os valores chaves para os objetos armazenadao. O valores chaves so usados para procurar, ou indexar os dados armazenados. A interface Map no uma extenso da interface Collection , ele possui sua prpria hierarquia. Map no permite duplicatas dentro da collection. Na implemantao Map , null uma entrada vlida, mas s permitido uma vez. Vamos estudar aqui uma implementao desta interface: Hashtable
6-30
A classe ArrayList
Implementa a interface java.util.List e usa array para armazenamento. Um armazenamento de array geralmente mais rpido, mas possui limitaes como, no poder inserir, e apagar entradas no meio da lista. Para realizar este tipo de adio e excluso precisamos de um novo array, e isto gera portanto um overhead muito grande. Voc pode acessar qualquer elemento aleatoricamente. Esta estrutura no sincronizada, devendo ser utilizada quando o acesso a um objeto desta classe tiver uma nica thread.
package com.targettrust.exemplos; import java.util.*; /** * * * * * */ Elementos no ordenados Permite duplicados null permitido Semelhante a classe Vector Acesso aleatrio
public class ArrayListExemplo { public static void main(String[] args) { List lista = new ArrayList(); lista.add("Java J2EE"); lista.add("Microsoft Net"); lista.add("Linux"); lista.add("Oracle"); lista.add("Web Designer"); lista.add("Java J2EE"); lista.add(null); System.out.println( lista.get(0)+", "+lista.get(4) ); // [Java J2EE, Web Designer] } }
6-31
A classe Vector
Uma vez que o tamanho do array definido voc no pode mudar o tamanho do array. Mas em java isso possivel utilizando o mecanismo de refleo do Java que foi introduzido no Java 1.1, mas ele possui suas prprias limitaes. Esta classe possui os seus mtodos sincronizados desta forma deve ser utilizada quando o acesso ao objeto for concorrente. J se o acesso no tiver esta caracterstica ento deve ser utilizada a classe ArrayList que no sicronizada e , portanto, mais rpida. Para lidar com este tipo de situao em Java utilize Vector, ele cresce e reduz seu prprio tamanho automticamente. Isso permite somente objetos que no so primitivos. Para enviar primitivas, converta as primitivas um objeto e envie elas para o vector. O vector realoca e redefine o tamanho automticamente . Veja o exempo seguinte. Vector vt = new Vector(3, 10); As linha acima representam a capacidade inicial de trs, e cresce em aumento de 10 em cada realocao quando se tenta adicionar o quarto elemento. Depois de realocado a capacidade do vector se torna a capacidade inicial + a capacidade aumentada (capacity Increment).
Construtores: - Vector(int initialCapacity); - Vector(int initialCapacity, int capacitIncrement); - Vector() Mtodos: - void addElement(Object obj); - int size(); - void setSize(int n); - void trimToSize();
6-32
package com.targettrust.exemplos; import java.util.*; /** * - Elementos no ordenados * - Permite duplicados * - null permitido * - Acesso aleatrio */ public class VectorExemplo { public static void main(String[] args) { Vector lista = new Vector(); lista.add("Java J2EE"); lista.add("Microsoft Net"); lista.add("Linux"); lista.add("Oracle"); lista.add("Web Designer"); lista.add("Java J2EE"); lista.add(null); System.out.println( lista.get(0) ); System.out.println( lista ); // [Java J2EE] // [Java J2EE, Microsoft Net, Linux, Oracle, Web Designer, Java J2EE, null] } }
6-33
A classe Hashtable
Hashtable uma estrutura que possui os elementos armazenados internamente baseados em chave. Todo objeto guardado dentro desta estrutura ficar associado a uma chave para posterior recuperao do mesmo. Esta estrutura uma das mais rpidas quando o assunto pesquisa, uma vez que o acesso ao objeto armazenado direto atravs de chaves. Veja um exemplo abaixo:
package com.targettrust.exemplos; import java.util.*; /** * - Elementos no ordenados * - NO permite duplicados * - null NO permitido * - Acesso baseado em chave */ public class HashtableExemplo { public static void main(String[] args) { Hashtable lista = new Hashtable(); lista.put(new Integer(1), "Java J2EE"); lista.put(new Integer(2), "Microsoft Net"); lista.put(new Integer(3), "Linux"); lista.put(new Integer(4), "Oracle"); lista.put(new Integer(5), "Web Designer"); lista.put(new Integer(6), "Java J2EE"); System.out.println( lista.get(new Integer(1)) ); System.out.println( lista.get(new Integer(4)) ); // [Java J2EE] // [Oracle] } } Cdigo 6-41: Hashtable
6-34
A classe LinkedList
Implementa a interface java.util.List e usa linked list para armazenamento. Uma linked list permite que elementos sejam adicionados, removidos da collection em qualquer posio dentro do container. Com esta implementao voc somente pode acessar os elementos sequencialmente. Veja abaixo um exemplo de uso desta estrutura:
package com.targettrust.exemplos; import java.util.*; /** * - Elementos no ordenados * - Permite duplicados * - null permitido */ public class LinkedListExemplo { public static void main(String[] args) { List lista = new LinkedList(); lista.add("Java J2EE"); lista.add("Microsoft Net"); lista.add("Linux"); lista.add("Oracle"); lista.add("Web Designer"); lista.add("Java J2EE"); lista.add(null); System.out.println( lista ); // [Java J2EE, Microsoft Net, Linux, Oracle, Web Designer, Java J2EE, // null] } }
6-35
Generics
Os tipos genricos representam uma das maiores modificaes na linguagem java j feitas at os dias de hoje. Tipos genricos trazem a facilidade de parametrizar o tipo de classes, variveis ou mtodos. Na API do JDK 5.0 todas as collection, por exemplo, foram parametrizadas. Esta parametrizao tornou classes como, por exemplo, ArrayList capazes de armazenar elementos de um tipo E e no mais Object. A declarao de ArrayList, por exemplo, agora pode ser feita da seguinte forma:
1 ArrayList<Aluno> alunos = new ArrayList<Aluno>(); 2 3 Aluno a = new Aluno("Rafael"); 4 alunos.add( a ); 5 6 Aluno x = alunos.get( 0 ); 7 System.out.println("Nome: "+ x.getNome() ); Cdigo 6-43: Generics
Observe o cdigo acima e perceba que na linha 6 no foi preciso realizar um casting para converter o objeto retirado da coleo. O mesmo havia sido armazenado internamente como um objeto Aluno e no como sendo do tipo Object. Alm de simplificar a codificao, os tipos genricos tambm so uma grande melhoria de robustez, evitando a possibilidade de typecasts errados e, portanto a ocorrncia de ClassCastException. Isto tambm, claro, aumenta a produtividade, pois perde-se menos tempo com depurao e testes se o cdigo compila, porque vai funcionar, pelo menos no que diz respeito a tipos. Com os tipos genricos, o programador pode formalizar restries adicionais dos tipos que constri, por exemplo, determinar que determinada lista s possa conter instncias de Produto, e no objetos quaisquer. Violaes dessas regras de tipagem no so crticas para a linguagem (pois no possibilitam perda de dados nem corrupo de memria), mas so crticas para o desenvolvedor, pois podero ocultar erros de lgica. O resultado pode ser uma ClassCastException, ou ainda pior o bug pode ficar oculto por muito tempo, pois o valor opaco (Object) convertido para o tipo que deveria ter.
import static java.lang.System.*; ... ... Aluno a = new Aluno("Joo", "(51) 3325-2596" ); Map<String, Aluno> hash = new HashMap<String, Aluno>(); // Adiciona um aluno na Hash hash.put(a.getNome(), a); // Recupera o Aluno Aluno x = hash.get( a.getNome() );
6-36
Colees, Arrays, String e Wrapper Classes // Mostra dados out.printf( "Dados: %s %s", x.getNome(), x.getTelefone() Cdigo 6-44: Usando generics
);
Acima voc tem um cdigo onde criamos uma HashMap para adicionar objetos do tipo Aluno associados a chaves do tipo String. Na declarao de HashMap especificamos que a chave ser do tipo String bem como os objetos a serem armazenados sero Alunos, isto evita qualquer necessidade de casting posterior para recuperar os dados da estrutura, bem como fortalece o sistema de tipos proibindo que sejam utilizados tipos diferentes dos especificados na declarao. A linha abaixo no compilaria pois o tipo da chave esta sendo violada.
hash.put(new Integer(1), a); //ERRO ao compilar! Cdigo 6-45: Adicionando inteiro como chave
Podemos tambm cria uma classe com tipos parametrizados. A classe abaixo representa um grupo no qual podemos guardar objetos. Os objetos a serem armazenados neste grupo so sempre do tipo especificado no parmetro T da classe Grupo. Veja o cdigo da classe:
public class Grupo<T> { private ArrayList elementos; public Grupo() { elementos = new ArrayList(); } public void add(T obj) { elementos.add( obj ); } public void remove(T obj ) { elementos.remove( obj ); } } Cdigo 6-46: Criando uma classe de um determinado tipo
Observe que na linha onde tentamos adicionar um inteiro teremos problemas, pois o grupo foi criado como sendo capaz de armazenar somente Strings. O tipo do grupo pode ser trocado conforme o cdigo abaixo:
Grupo<Aluno> g = new Grupo<Aluno>();
6-37
Colees, Arrays, String e Wrapper Classes Aluno a = new Aluno("Joo", "(51) 3325-2596" ); g.add( a ); g.add( "Java J2EE" ); // ERRO! g.add( new Integer(3) ); // ERRO! Cdigo 6-48: Violando acesso ao grupo
O cdigo acima foi alterado para receber objetos aluno e armazenar dentro do grupo. Veja que a linha onde adicionamos agora uma String ou um Integer ir sinalizar erro. Neste exemplo acima os parmetros do mtodo add(...) bem como do remove(...) esto parametrizados. Teramos outra opo para no utilizar os parmetros genricos, bastaria definir o tipo dos mtodos como Object. Desta forma poderia ser criado um grupo e passado qualquer tipo de objeto para ele, mas isto permitiria que o grupo pudesse armazenar tipos diferentes de objetos. Para evitar isto voc tambm poderia tornar os tipos dos parmetros doa mtodos fixos (String, por exemplo), mas desta forma voc teria somente um grupo de strings e no poderia criar grupos de outros objetos. Observe que neste caso o objetivo justamente permitir que se possa criar um grupo de tipos variveis, mas uma vez definido um grupo como sendo de um tipo, o mesmo no poder receber elementos de outros tipos.
6-38
Autoboxing
Autoboxing diz respeito a uma converso automtica que feita entre os tipos primitivos da linguagem java (int, float, long, byte, etc...) e suas wrapper classes (Integer, Float, Long, Byte, Character, etc...). O programador no precisa mais se preocupar com estas converses ficando a cargo agora da linguagem. Este recurso interessante e simplifica a escrita de cdigos porm introduz alguns efeitos colaterais listados mais abaixo. Deve desta forma ser utilizado de forma controlada.
Integer i = 10; System.out.println( i ); Cdigo 6-49: Autoboxing
O cdigo acima atribui um valor primitive (10) a um objeto do tipo Integer. Logo em seguida o objeto integer impresso. Um exemplo: Quando trabalhamos com Collections sabemos que uma coleo pode ser adicionado somente objetos, no sendo possvel portanto adicionar um tipo primitivo a esta. Para isto o tipo primitivo deve ser encapsulado em uma wrapper class e ento o objeto desta wrapper adicionado a Collection. Veja cdigo abaixo:
ArrayList lista = new ArrayList(); // Criando os objetos Integer um = new Integer(1); Integer dois = new Integer(2); Integer tres = new Integer(3); // Adicionando os objetos a Collection lista.add ( um ); lista.add ( dois ); lista.add ( tres ); Cdigo 6-50: Adicionando dados em uma coleo
A mesma dificuldade de manipulao ocorre quando temos que retirara o valor da coleo, pois se precisarmos manipular o valor como um tipo primitivo isto exigir, alm de um casting, uma chamada a um mtodo do objeto retirado para o transformar novamente em um tipo primitivo. Todo este processo de encapsular e desencapsular conhecido como: boxing e unboxing. Isto deixa o cdigo maior e mais complicado de ser escrito.
6-39
// Mostrar os valores em formato int System.out.println( x.intValue() ); System.out.println( y.intValue() ); System.out.println( z.intValue() ); Cdigo 6-51: Mostrando dados da coleo sem autoboxing
Podemos utilizar autoboxing para resolver e simplificar a escrita deste cdigo. Veja abaixo a verso do cdigo que adiciona os trs valores dentro da collection. Observe que utilizamos para isto um tipo de collection que comporta somente Integer. Esta forma de representao de collection faz uso de Generics.
ArrayList<Integer> lista = new ArrayList<Integer>(); // Adicionando dados a Collection lista.add ( 1 ); lista.add ( 2 ); lista.add ( 3 ); // Retira os dados da collection int x = lista.get(0); int y = lista.get(1); int z = lista.get(2); // Mostra os dados da collection System.out.println( x ); System.out.println( y ); System.out.println( z ); Cdigo 6-52: Utilizando autoboxing para mostrar dados
int i = 2; int j = 2; ArrayList <Integer> lista = new ArrayList<Integer>(); lista.add(i); lista.add(j); System.out.println( (i==j) ); System.out.println( lista.get(0)==lista.get(1) );
6-40
Colees, Arrays, String e Wrapper Classes System.out.println( lista.get(0).equals( lista.get(1) ) ); Cdigo 6-53: Comparando dado s de uma coleo
A primeira comparao esta comparando tipos primitivos e como j sabemos a sada deveria ser true. J no segundo caso so comparados os valores que foram enpasulados (autoboxed), retornando tambm true. No terceiro caso so comparados os valores dos objetos criados atravs de autoboxing. Se o valor das variveis inteiras forem alteradas para um valor superior a 127, o retorno para a comparao lista.get(0)==lista.get(1) ser false! Note que estamos neste caso comparando os valores enpasulados como objetos e no os valores primitivos diretamente. Para as demais comparaes o retorno continua sendo true. Abaixo a sada para os valores alterados e superiores a 127:
true false true
6-41
6-42
Exerccios
1. Neste exerccio voc ir criar uma classe nova para representar um pacote de cursos. Um pacote de cursos contm vrios cursos. Teremos que saber quantos h neste pacote, bem como o valor total do pacote. Este valor ser a soma do preo de todos os cursos. Veja abaixo os passos para isto:
Passo 1: Crie uma classe pblica chamada PacoteCurso no pacote com.targettrust.java e defina os seguintes atributos:
private ArrayList<Curso> cursos private Date dataCriacao
6-43
Observe no atributo acima o uso de generics para definir o tipo de objetos da coleo Passo 2: Crie no mtodo construtor o ArrayList. Passo 3: Defina nesta classe uma operao que possa receber objetos da classe curso e os adiciona a coleo cursos. Quando esta coleo atingir um nmero de 10 cursos deve ser impresso um aviso. Passo 4: Crie nesta classe uma operao capaz de calcular o valor total do pacote. Para fazer este clculo voc dever percorrer a coleo e obter o preo de cada curso adicionado a ela. Use for-each para percorrer o ArrayList. Passo 5: Crie uma operao na classe PacoteCurso para que a mesma retorne uma StringBuilder contendo o nome de todos os curos que fazem parte do pacote.
2. Agora voc ir praticar o mecanismo de autoboxing do java. Vamos criar um ArrayList com nmeros inteiros e percorrer o mesmo somando estes valores.
Passo 1: Crie uma classe chamada ExemploAutoboxing no pacote com.targettrust.java e declare nesta classe o mtodo main. Passo 2: Na classe declare um atributo privado, chamado lista, esttico, do tipo ArrayList. Utilize Generics na declarao do atributo ( ArrayList<Integer> ) No mtodo main crie este objeto que representa a lista e adicione no mesmo 5 nmeros do tipo int. Passo 3: Percorra a lista com um for-each e some todos os nmeros da lista mostrando o total ao trmino do lao. Observe que no haver casting para a soma dos nmeros!
6-44
Java Fundamentals
7. Tratamento de Excees
7-1
Tratamento de Excees
Objetivos
Compreender as Vantagens do tratamento de Excees em Java; Manipular, Tratar, Propagar, Capturar e Criar Excees.
7-2
Tratamento de Excees
Introduo
Uma exceo um evento que ocorre durante a execuo de um programa que interrompe o fluxo normal das instrues. Muitos tipos de erros podem causar excees, tais como tentar acessar um elemento de um vetor fora dos limites ou tentar dividir um nmero por zero. Quando uma exceo ocorre dentro de um mtodo Java, o mtodo cria um objeto Exception e deixa que o ambiente de execuo (runtime system) se encarregue do assunto. Na terminologia Java, este processo chamado levantar uma exceo (throwing an exception). O objeto Exception criado contm informaes sobre a exceo, tais como seu tipo e o estado do programa quando o erro ocorreu. Aps o mtodo levantar uma exceo, o ambiente de execuo ento responsvel por encontrar um cdigo que manipule o erro. Para isso, o ambiente de execuo entra em ao procurando o cdigo de tratamento para o erro no conjunto de mtodos da pilha de chamada do mtodo em que o erro ocorreu. O ambiente de execuo procura de trs para frente na pilha de chamada, comeando com o mtodo onde o erro ocorreu, at encontrar um mtodo que contenha a manipulao apropriada da exceo. Uma manipulao de exceo considerada apropriada se o tipo de exceo levantada o mesmo tipo de exceo manipulada pelo manipulador (pelo cdigo de tratamento da exceo). Assim, a exceo cruza a pilha de chamadas at que uma manipulao apropriada encontrada e um dos mtodos chamados trata a exceo. Na terminologia Java, se diz que o manipulador escolhido para tratar a exceo capturou (catch the exception) a exceo. Se o ambiente de execuo procura exaustivamente em todos os mtodos da pilha de chamadas sem descobrir um manipulador de excees apropriado, o ambiente de execuo (e conseqentemente, o programa Java) termina. A utilizao de excees para manipular erros tem as seguintes vantagens sobre as tcnicas de gerenciamento de erros tradicionais: 1. Separa o cdigo para manipular erros do cdigo regular (do fluxo normal) do programa 2. Propaga erros na pilha de chamadas 3. Agrupa tipos de erros e os diferencia 4. No podem ser ignoradas 7-3
Tratamento de Excees
}
Cdigo 7-1: Exemplo de cdigo estruturado para tratamento de arquivos.
Esta funo poderia ter diversos erros potenciais, tais como erro na abertura do arquivo, erro na leitura da primeira linha, erro no fechamento do arquivo. No modo de programao tradicional para detectar os potenciais erros para esta funo, cada erro deve ser testado e atribudo para um cdigo de erro. Isto leva a uma grande quantidade de cdigo adicional para a deteco e manipulao dos possveis erros. Por exemplo, a funo anterior se tornaria uma funo tal como:
int leituraArquivo { int codigoErro = 0; abre o arquivo; if (erroAberturaArquivo) codigoErro = -1; else { le o arquivo; if (erroLeituraArquivo) codigoErro = -2; fecha o arquivo; if (erroFechamentoArquivo) codigoErro = -3; } return codigoErro; } Cdigo 7-2: Exemplo de cdigo condicional para tratamento de arquivos com retorno de valor.
Na linguagem Java, o problema de tratamento de erros realizado a partir excees. As excees permitem que o programador escreva o cdigo do fluxo principal e manipule os casos excepcionais em outro local. 7-4
Tratamento de Excees
Cdigo 7-3: Exemplo de cdigo estruturado para tratamento de arquivos utilizando Java.
Como pode ser visto, as excees no dispensam a deteco e manipulao dos erros. O que elas fornecem so meios de separar da lgica principal todos os detalhes do que fazer quando algum evento fora do normal ocorre. Com isso, o cdigo se torna mais claro e menos propenso a erros.
7-5
Tratamento de Excees
Tratamento de Excees
Alm disso, as excees que podem ser levantadas dentro de um mtodo so parte da interface de programao pblica do mtodo e devem ser especificadas na clusula throws do mtodo. Com isso, o mtodo informa aos seus chamadores sobre as excees que ele pode levantar e estes mtodos podem decidir de modo inteligente o que fazer com tais excees. O trecho a seguir demonstra como ficariam os mtodos metodo1, metodo2 e metodo3 manipulando excees. Como pode ser visto, este cdigo mais compacto que na programao tradicional.
public void metodo1() { try { chamada de metodo2; } catch (exception) { trata erro; } } public void metodo2() throws exception { chamada de metodo3; } public void metodo3() throws exception { chamada de lePrimeiraLinhaArquivo; } Cdigo 7-4: Propagao de excees utilizando a clusula throws.
7-7
Tratamento de Excees
7-8
Um exemplo de manipulador de exceo que trata somente excees geradas ao tentar abrir um arquivo com nome invlido
catch (FileNotFoundException e) { tratamento da exceo }
(FileNotFoundException) :
Cdigo 7-5: Bloco catch para tratamento de exceo especfica.
Um mtodo pode tambm capturar uma exceo baseada em seu grupo ou tipo geral. Isto feito especificando qualquer uma das superclasses de excees no comando catch. Para capturar todas as excees de E/S, independente do seu tipo, a manipulao de excees poderia especificar o argumento IOException, como no exemplo abaixo. Esta manipulao iria capturar todas as excees deste grupo. Para descobrir exatamente que tipo de exceo ocorreu, o parmetro e poderia ser
catch (IOException e) { tratamento }
usado.
Cdigo 7-6: Bloco catch para tratamento de exceo de grupo (IOException).
exceo:
Cdigo 7-7: Bloco catch para tratamento de qualquer exceo.
Manipuladores de excees que so muito genricos, como o mostrado acima, podem tornar o cdigo mais propenso a erros por capturar e tratar excees que no foram previstas e que, portanto, no sero corretamente tratadas dentro do manipulador. Deste modo, manipuladores de excees gerais no devem ser utilizados como uma regra.
7-9
Tratamento de Excees
7-10
Tratamento de Excees
Manipulando Excees
A classe Throwable a superclasse de todos os erros e excees na linguagem Java, possuindo duas subclasses: Error e Exception.
Subclasse Error
Erros so extenses da classe Error, subclasse de Throwable. Subclasses de Error, diferente das subclasses de Exception, geralmente no devem ser capturadas, e geralmente causaro o trmino do programa. Exemplos deste tipo de erro so falta de memria durante a execuo ou no estar apto a carregar uma classe.
Tratamento de Excees
manipula, a mquina virtual ir terminar o programa e imprimir o nome da exceo e um rastro da pilha.
7-12
Tratamento de Excees
Tratando Excees
Quando um mtodo utilizado pelo programa levantar uma exceo, o programador possui trs opes: Capturar a exceo e trat-la; Capturar a exceo e levantar uma exceo diferente, que ser manipulada em outro local; Deixar a exceo passar atravs do mtodo; algum manipulador deve ento captur-la em outro local.
Para identificar se um mtodo em particular de uma classe padro do Java pode levantar uma exceo, a documentao do JDK pode ser utilizada. Todas as classes padro do Java so documentadas e uma parte da documentao de cada mtodo a lista das excees que este mtodo pode levantar. Por exemplo, na classe Integer, para o mtodo parseInt (que transforma um argumento String em um nmero decimal com sinal):
public static int parseInt(String s) throws NumberFormatException
7-13
Tratamento de Excees
Manipulando Excees
O mecanismo para manipulao de excees em Java formado pelos comandos try/catch/finally. Para manipular uma exceo, o cdigo deve ser organizado nos seguintes blocos: Incluir as chamadas dos mtodos que podem levantar excees em um bloco try; Inserir um ou mais blocos catch, onde cada um ir capturar uma exceo em particular; Adicionar um bloco finally se desejado. O bloco finally executado sempre, mesmo que nenhuma exceo tenha sido levantada.
O exemplo a seguir demonstra a sintaxe para manipular trs excees (excecaoTipo1, excecaoTipo2 e excecaoTipo3) que poderiam ser levantadas por mtodo chamado.
try { ... chamada do mtodo que pode levantar exceo ... }catch (excecaoTipo1){ trata excecaoTipo1 }catch (excecaoTipo2){ trata excecaoTipo2 }catch (excecaoTipo3){ trata excecaoTipo3 }finally { ... } Cdigo 7-8: Tratamento de excees utilizando os blocos try/catch/finally.
7-14
Tratamento de Excees
O Bloco try
O comando try delimita o bloco de cdigo que contem as chamadas para os mtodos que podem levantar excees. Se uma exceo ocorre dentro de um bloco try, esta exceo capturada pelo manipulador de excees apropriado associado a este bloco try.
O Bloco catch
Um bloco try pode ser seguido por zero ou mais blocos catch, que especificam como tratar os vrios tipos de excees. Cada clusula catch declarada com um argumento, que deve ser do tipo Throwable ou uma subclasse deste. Quando uma exceo ocorre, o primeiro catch que possui o argumento do tipo apropriado ativado. Este argumento deve ser o tipo da exceo do objeto ou uma superclasse da exceo, e valido somente dentro do bloco catch. No necessrio que haja um bloco catch para todas as excees possveis. Em alguns casos, o tratamento correto permitir que a exceo seja propagada acima e possa ser capturada por outro mtodo que esteja na pilha.
O Bloco finally
O bloco finally contm o cdigo responsvel pela finalizao do mtodo (tais como fechamento dos arquivos, liberao dos recursos) antes que o controle seja transferido para outra parte do programa. O cdigo dentro deste bloco sempre executado se uma poro do bloco try executada, independente de como o cdigo no bloco try completado. Em um fluxo normal, o controle atinge o final do bloco try e passa ento ao bloco finally que executa a finalizao necessria. Se o controle deixa o bloco try pelo uso de um comando return ou break, o contedo do bloco finally executado antes do controle ser transferido para o novo destino. Se uma exceo ocorre no bloco try e h um bloco catch local para manipular esta exceo, o controle transferido para o bloco catch e posteriormente para o bloco finally. Se a exceo ocorre e no h um bloco catch para manipular a exceo, o controle transferido para o bloco finally e ento propagado para a clusula catch mais prxima que manipula esta exceo. possvel existir um bloco finally sem um ou mais blocos catch anteriores. Contudo, um bloco try deve sempre existir antes do bloco finally. 7-15
Tratamento de Excees
Observe o cdigo acima e descreva o que impresso na tela nas seguintes situaes: 1. A classe chamada utilizando: C:\java ConverteNumero 38 2. A classe chamada utilizando: C:\java ConverteNumero palavra 3. A classe chamada utilizando: C:\java ConverteNumero
Imagine agora o exemplo acima sem o bloco catch que trata a exceo ArrayIndexOutOfBoundsException. O que aconteceria se a classe fosse chamada utilizando apenas converteNumero?
7-16
Tratamento de Excees
Propagando Excees
Quando uma exceo no pode ser tratada localmente ou se deseja que ela seja tratada em outro local, ela pode ser propagada para o cdigo que chamou o mtodo. Para propagar uma exceo para o mtodo acima, a exceo deve ser indicada na declarao do mtodo chamado. Isto feito utilizando o comando
tipo metodo(parametros) throws excecaoTipo1 { ... }
throws.
Cdigo 7-10: Propagao de excees utilizando a clusula throws.
Observe o exemplo abaixo. O mtodo converteStringParaNumero no trata a exceo NumberFormatException localmente. Ao invs disso, a exceo passa automaticamente para o mtodo que chamou converteStringParaNumero. O mtodo que chamou converteStringParaNumero pode capturar a exceo NumberFormatException ou propagar a exceo para um mtodo acima. Caso ele deseje propagar a exceo, ele deve tambm conter throws NumberFormatException em sua declarao.
private void converteStringNumero(String str) throws NumberFormatException { int num; try { System.out.println("String lida: " + str); num = Integer.parseInt(str); System.out.println("Numero: " + num); }finally { System.out.println("Bloco finally mtodo converteStringNumero."); } System.out.println("Encerrando mtodo converteStringNumero"); }
Cdigo 7-11: Tratamento de excees utilizando a clusula throws para o contexto anterior.
7-17
Tratamento de Excees
Lanando Excees
O programador pode lanar excees em seu cdigo para indicar alguma condio anormal. Estas excees podem ser excees padres do sistema ou excees criadas pelo programador. Ao levantar uma exceo, o que est sendo feito na realidade a criao de um objeto e a transmisso deste para um mtodo superior. Assim, o objeto exceo deve ser criado usando o operador new. O exemplo a seguir apresenta um mtodo que lana uma exceo do tipo ArrayIndexOutOfBoundsException se verificar que o ndice no vlido.
private void testaArgumento(int indice, String vetor[]) throws ArrayIndexOutOfBoundsException { if (indice >= vetor.length) { throw new ArrayIndexOutOfBoundsException(); } } Cdigo 7-12: Antecipando uma exceo e criando a exceo correspondente.
7-18
Tratamento de Excees
Criando Excees
Para criar as suas prprias excees, o programador deve estender a classe Exception. A classe RuntimeException no deve ser estendida, pois esta classe utilizada para excees comuns que no precisam ser verificadas. O exemplo a seguir cria uma exceo chamada ExcecaoArgumentoInvalido. Esta exceo possui um nico construtor que
public class ExcecaoArgumentoInvalido extends Exception { public ExcecaoArgumentoInvalido (String message) { super(message); } }
7-19
Tratamento de Excees
7-20
Tratamento de Excees
7-21
Tratamento de Excees
Exerccios
1. Neste exerccio voc ir criar uma exceo personalizada para tratar erros de validao que podem ser ento lanados quando estiver executando a aplicao e um valor incorreto for passado, por exemplo, para o mtodo que atribui valores a um produto.
Passo 1: Crie uma classe pblica chamada ValidacaoException, esta classe deve ser criada em um arquivo fonte novo e deve extender a classe RuntimeException.
Passo 2: Defina um mtodo construtor nesta classe que possa receber uma String como parmetro e repasse esta string para a classe pai.
Passo 3: Nas operaes de modificao do atributo preco da classe Produto bem como na operao que atribui um produto a um ItemPedido faa uso desta classe para se a validao der algum erro voc lanar uma exceo com uma mensagem personalizada para quem chamou esta operao.
7-22
Java Fundamentals
8-1
Objetivos
8-2
Abstrao
Em Java voc pode definir classes que representem, na definio de um projeto, um nvel mais alto de abstrao. Ao usar estas classes o projetista ter uma viso melhor de como as subclasses devem se parecer e mesmo quais mtodos so obrigatrios em todas as subclasses.
Figura 8-1: Definindo a classe Produto como abstrata para no ser instanciada.
Classes Abstratas
Uma classe abstrata simplesmente uma classe que no pode ser instanciada. Somente suas subclasses podem ser instanciadas. Por exemplo, Produto no contm detalhes suficientes para fornecer algo til para o negcio. Um item deve ser um CD ou um DVD. Produto serve, no entanto, como uma coleo de dados e comportamentos que so comuns a todos os itens disponveis para alugar.
Mtodos Abstratos
Mtodos abstratos vo um passo alm da herana padro. Um mtodo abstrato definido dentro de uma classe abstrata deve ser implementado pelas subclasses destas. Esta tcnica permite que o projetista de classes decida exatamente quais comportamentos as subclasses devem ter. O projetista de uma classe abstrata no consegue determinar como estes comportamentos sero implementados, mas somente que eles sero implementados.
Interfaces
Interface a especificao de um conjunto de mtodos, similares a uma classe abstrata. Alm do que uma classe abstrata pode oferecer, uma interface pode efetivamente permitir herana mltipla. Uma classe pode implementar um nmero ilimitado de interfaces, mas pode estender somente uma nica superclasse. 8-3
sendo abstrata:
Figura 8-2: Definies das classes Produto, DVD e CD. Herana e Abstrao da classe Produto.
Produto declarado como uma classe abstrata porque no possui informao ou comportamento suficientes para representar um objeto autnomo. O usurio no deveria ser capaz de criar objetos Produto, porque Produto apenas uma classe parcial e intermediria. Produto existe somente para que possa ser estendida por classes mais especializadas, tais como CD ou DVD. O que acontece se voc tentar instanciar uma classe abstrata?
Produto produto = new Produto(); // Erro de compilao Cdigo 8-1: Erro de compilao na criao de uma instncia de uma classe abstrata.
Se voc tentar criar um objeto Produto em seu programa, o compilador acusar um erro. O usurio pode criar somente objetos de subclasses concretas:
CD DVD cd = new CD(); dvd = new DVD(); // Herdando Produto // Herdando Produto
O modificador abstract pode ser aplicado somente a classes e mtodos. Classes abstratas provem um modo de adiar a implementao de mtodos para 8-4
subclasses. Uma classe abstrata no pode ser instanciada, ou seja, no podemos chamar seus construtores.
8-5
Mtodos Abstratos
Ao projetar uma hierarquia de classes, h provavelmente algumas operaes que todas as classes devero ter, cada qual de sua prpria maneira. Por exemplo, em um negcio de aluguel de fitas, o vendendo deve saber se um item pode ser alugado ou no. Cada tipo de item, entretanto, determina se pode ser alugado de uma maneira especfica. Para representar este conceito em Java, o mtodo este item pode ser importado definido na classe Produto. Entretanto, no h uma implementao sensata para este mtodo em Produto, porque cada tipo de item tem suas prprias exigncias. Uma abordagem, seria deixar o mtodo vazio na classe Produto:
public abstract class Produto { public boolean isImportado() { return true; } } Cdigo 8-4: Definindo mtodos concretaos em classes abstratas.
Esta abordagem no boa o suficiente porque no fora cada uma das subclasses concretas a sobrescrever o mtodo. Suponha, por exemplo, que a classe DVD se esquea de sobrescrever o mtodo isImportado(), o que aconteceria se o usurio chamasse este mtodo a partir de uma referncia para DVD? O mtodo isImportado() definido em Produto seria chamado e retornaria true. Este no o resultado desejado. A soluo declarar o mtodo como abstrato, como mostrado logo a seguir.
8-6
Ao declarar um mtodo abstrato, voc deve fornecer somente a assinatura do mtodo, que compreende: o nome do mtodo, a lista de parmetros esperados e o tipo de retorno. Voc no fornece um corpo para o mtodo. Cada subclasse concreta dever sobrescrever este mtodo e fornecer o seu prprio corpo. Agora que o mtodo declarado abstrato, todas as subclasses devem fornecer uma implementao para ele. Subclasses abstratas podem conter mtodos que no so declarados abstratos. Estes mtodos podem ser sobrescritos pelas subclasses, mas isto no p necessariamente obrigatrio.
8-7
Interfaces
Uma interface similar a uma classe abstrata, exceto que ela no possui nenhum mtodo concreto ou variveis de instncia. apenas uma coleo de declaraes de mtodos abstratos e constantes isto , variveis declaradas como static public final. Uma interface como um contrato que a subclasse deve obedecer. Qualquer classe que implemente uma interface deve implementar todos os mtodos especificados na interface. Uma classe pode implementar muitas interfaces, mas pode estender apenas uma nica classe. Java no suporta herana mltipla, mas permite a implementao de mltiplas interfaces. Como j foi dito anteriormente, CD herda todos os atributos e comportamentos de Produto. Alm disto, deve fornecer implementao para cada um dos mtodos definidos em cada interface que implementar. Estes mtodos podem ser usados por outras classes para implementar comportamentos especficos como, por exemplo, uma rotina de ordenamento.
8-8
Exemplos de interfaces
Interfaces descrevem um aspecto de comportamento que muitas classes possuem. O nome de uma interface geralmente um comportamento como: Compra, Venda, etc. Difere, portanto, do nome de uma classe, que usualmente um substantivo, como cliente ou produto. A interface java.sql.Connection possui os mtodos a seguir: - void commit() - void rollback() - void close() - void clearWarnings() - Statement createStatement() - void setAutoCommit(boolean) - boolean isClosed()
Qualquer classe que precise trabalhar com conexo de bando de dados pode implementar a interface Connection. As classes que implementam uma interface podem ser completamente distintas e no ter uma nada a ver com as demais. A nica coisa que devem ter necessariamente em comum a necessidade de todas serem mveis.
8-9
Definindo Interfaces
Voc pode definir uma interface usando a palavra reservada interface. Todos os mtodos especificados em uma interface so implicitamente pblicos e abstratos (public e abstract). Quaisquer variveis definidas em uma interface so implicitamente pblicas, estticas e constantes (public, static e final).
public interface Connection { public void commit(); public void rollback(); public void close(); public void clearWarnings(); public Statement createStatement(); public void setAutoCommit(boolean b); public boolean isClosed(); // entre outros mtodos ... } Cdigo 8-6: A interface Conncetion do pacote java.sql.
Porque os mtodos de interface so implicitamente pblicos e abstratos prtica geralmente aceita no especificar estes modificadores de acesso. O mesmo verdade para variveis. Como so implicitamente pblicas, estticas e finais, geralmente estes modificadores no so especificados. Cada interface pode ser representada em um arquivo Java separado com o nome da interface. (neste caso poderamos criar um arquivo chamado Connection.java do pacote java.sql)
8-10
Implementando Interfaces
O exemplo abaixo mostra o exemplo da classe OracleConn que implementa a interface Conncetion. OracleConn deve implementar todos os mtodos de todas as interfaces que ele declare implementar (interfaces presentes na clusula implements). Neste caso, OracleConn deve implementar os mtodos contidos na interface Connection.
public class OracleConn implements Connection { public void commit() { //... cdigo } public void rollback() { //... cdigo } } Cdigo 8-8: A classe OracleConn deve implementar TODOS os mtodos da interface Conncetion.
Uma classe pode implementar mais de uma interface se ela desejar, bastando para tal especificar uma lista de interfaces separadas por vrgula. Considere o seguinte exemplo:
public class Aplicacao extends JFrame implements InterfaceI, InterfaceII { } Cdigo 8-9: A classe Aplicacao pode implementar mais de uma interface.
Aqui, Aplicacao implementa duas interfaces: InterfaceI e InterfaceII. Isto significa que a classe Aplicacao deve implementar todos os mtodos declarados em InterfaceI e InterfaceII. A classe Aplicacao ter o comportamento definido nas duas interfaces.
8-11
8-12
Exerccios
1. Crie uma interface para representar uma fila de impresso Passo 1: Declare uma interface em um arquivo novo com os seguintes comportamentos:
boolean imprimir() void parar() boolean remover(Documento doc) void refresh() void pausa()
Passo 2: Crie uma classe para implementar esta fila de impresso e codifique as operaes nela
2. Trabalhando com classes abstratas Passo 1: Torne a classe Produto abstrata adicionando a palavra reservada abstract na assinatura da classe. Passo 2: Tente criar um objeto desta classe agora. possvel? Passo 3: Transforme a operao que retorna o preo abstrata uma vez que a forma de calcular o preo ir depender de cada uma das subclasses.
8-13