Introdução a Linguagem Java

Apostila desenvolvida por Alexandre de Souza Pinto (Engenheiro de Computação – Unicamp Mestre em Engenharia Eletrica – Unicamp, Consultor da Software Design Informática-Campinas, SP) e formatada por Marco Aurélio Lopes Barbosa

Pág 1

1. INTRODUÇÃO.............................................................................................................5 1.1 Um Pouco de História...................................................................................................5 1.2 Por que Java é tão Interessante?.................................................................................6 1.3 Como Java Pode Mudar Minha Vida?......................................................................8 1.4 Mas Afinal, o Que Java Pode Fazer?.........................................................................9 1.5 Arquitetura Java.........................................................................................................10 1.6 Desenvolvendo os Primeiros Programas em Java..................................................12 1.7 Exercícios:....................................................................................................................16 2. CONCEITOS DE ORIENTAÇÃO A OBJETOS.....................................................17 2.1 Conceitos Básicos........................................................................................................17 2.2 Características da Tecnologia de Objetos ..............................................................20 2.3 Exercícios......................................................................................................................23 3. DIFERENÇAS ENTRE JAVA E C/C++..................................................................24 4. CONSTRUÇÕES BÁSICAS DA LINGUAGEM JAVA.........................................28 4.1 Variáveis e Tipos de Dados........................................................................................28 4.2 Operadores ..................................................................................................................31 4.3 Expressões....................................................................................................................35 4.4 Controle de Fluxo........................................................................................................37 4.5 Arrays e Strings...........................................................................................................42 4.6 Exercícios......................................................................................................................45 5. CLASSES E OBJETOS EM JAVA.........................................................................46 5.1 Classe.............................................................................................................................46 5.2 Ciclo de Vida de um Objeto.......................................................................................48 5.3 Liberando Objetos não mais Utilizados...................................................................52 Pág 2

5.4 Criando Classes...........................................................................................................54 5.5 Exercícios......................................................................................................................76 6. OUTRAS CARACTERÍSTICAS DA LINGUAGEM JAVA...................................80 6.1 Herança.........................................................................................................................80 6.2 Ocultando variáveis....................................................................................................81 6.3 Redefinindo (overriding) métodos............................................................................82 6.4 Métodos e Classes Abstratas......................................................................................83 6.5 Classes e Métodos Finais............................................................................................85 6.6 Interfaces......................................................................................................................86 6.7 Utilizando Interfaces como Tipos de Dados............................................................91 6.8 Pacotes (Packages)......................................................................................................92 6.9 Gerenciando Arquivos Fonte e Arquivos de Classe...............................................95 6.10 Exercícios....................................................................................................................97 7. INTERFACE GRÁFICA..........................................................................................100 7.1Widgets........................................................................................................................100 7.2 Inserindo Widgets em Applets................................................................................106 7.3 Modelo de Eventos do Java (1.1).............................................................................107 7.4 Gerenciadores de Layout (Layout Managers)......................................................112 7.5 Cores e Fontes............................................................................................................113 7.6 Exercícios....................................................................................................................114 8. APPLETS.................................................................................................................115 8.1 Introdução..................................................................................................................115 8.2 Ciclo de Vida de um Applet.....................................................................................116 8.3 Métodos Utilizados para Desenho e Tratamento de Eventos.............................117 8.4 Mostrando Imagens Dentro de um Applet............................................................118 Pág 3

................................................121 9...............5 Adicionando um Applet a uma Página HTML.................................126 10..........3 Ciclo de Vida de uma Thread...........120 9.. ENTRADA E SAÍDA...........................................................127 10......127 10...................118 8....................4 Exercícios ...............................................................................................2 Leitura e Escrita de Arquivos.........119 9..................................127 10................120 9...............................................................125 9.............................................2 Utilizando o Método run de uma Thread.......1 Introdução.....................8.......4 Sincronização de Threads..........................................................................................................3 Entrada e Saída de Dados (Padrão)....................................................................................................................... THREADS....................................................................................................................................123 9....5 Exercícios.....................................................................................................................................................................................................................130 Pág 4 ....................................................129 10..........6 Exercícios................1 O que é uma Thread..................................

Gosling chegou a uma conclusão simples: era necessário criar sua própria linguagem de programação. Gosling e sua equipe perceberam rapidamente que C++ não era a linguagem mais adequada para aquele projeto. Oak também foi utilizado em um projeto de vídeo sob demanda (Video on Demand.” Antoine de Saint Exupery 1. But when you have nothing more to take away. Gosling usou o próprio C++ como modelo. luzes. Desde o seu surgimento. Introdução Nunca anteriormente nenhuma nova linguagem de programação recebeu tanta atenção e tornou-se tão popular em tão pouco tempo. onde tentou-se projetar um sistema de controle remoto para uso doméstico. Apesar dos projetos Green e VOD não tenham gerado produtos comerciais. Entretanto.1 Um Pouco de História Em 1990. aproveitando a sintaxe básica da linguagem e a sua natureza orientada a objetos e retirando aquelas características que tornavam a linguagem mais complexa. video-cassete. da Sun Microsystems. eles proporcionaram a linguagem Oak uma chance de desenvolver-se a amadurecer.) a partir de um computador portátil chamado *7 (Star Seven). Java tornou-se uma escolha atraente para o desenvolvimento de aplicações Internet/intranet. Gosling a chamou de Oak (pinheiro. em Pág 5 . telefones. como herança múltipla de classes e leaks de memória. Gosling e sua equipe. Ao terminar de projetar sua nova linguagem.“You know you've achieved perfection in design. 1. pode-se observar um belo pinheiro). Esta linguagem deveria ser simples o bastante para evitar todos aqueles problemas que estavam relacionados com o C++. Aspectos do C++. Este sistema permitiria ao usuário controlar vários dispositivos (TV. um senhor chamado James Gosling recebeu a tarefa de criar aplicações para eletrodomésticos. em inglês. a Sun descobriu que o nome Oak já estava registrado por outra companhia e decidiu trocar o nome da linguagem para Java (segundo a lenda. da janela do escritório de Gosling. Então. etc. dificultavam bastante o desenvolvimento das aplicações. Depois de algum tempo. Oak foi usado pela primeira vez em um projeto chamado Green. O fenômeno Java cativou a imaginação de programadores em todo mundo e está proporcionando o desenvolvimento de uma nova geração de aplicações distribuídas. começaram a desenvolver seu software utilizando C++. VOD) como base para um software de controle de uma TV interativa. Para desenvolver esta nova linguagem. Este nome surgiu pois. Not when you have nothing more to add. uma linguagem considerada atual devido às suas características de orientação a objetos.

foi projetada desde o início para ser orientada a objetos. multimídia. criado a cerca de 30 anos. depois da World Wide Web ter transformado a Internet em um ambiente rico em gráficos. desenvolveram um browser Web completo (chamado HotJava) para demonstrar o poder da linguagem Java. Além disto.2 Por que Java é tão Interessante? A linguagem Java foi projetada para atender às necessidades do desenvolvimento de aplicações em um ambiente distribuído (rede) e heterogêneo. Estas bibliotecas podem ser facilmente estendidas. o máximo possível. a Sun anunciou oficialmente o Java. portanto. que desenvolve o browser Netscape.0 do seu navegador. Surgiu então o conceito de applets. Java acaba se tornando uma linguagem familiar pois possui o “look and feel” do C++. possam executar em qualquer plataforma de hardware e software e possam ser estendidas dinamicamente. 1. A linguagem é acompanhada de um grande número de bibliotecas de classes já testadas e que proporcionam várias funcionalidades (E/S. Java é uma ilha da Indonésia famosa por produzir tal bebida). No segundo trimestre de 1995. Outros fornecedores de browsers. com C++. Por ser parecida.0). Pág 6 . via herança.). networking. são apresentadas algumas características da linguagem Java que a tornam tão interessante e adequada para o desenvolvimento de uma nova geração de aplicações. Em 1993. pequenos programas que podiam ser incluídos em páginas Web. a equipe Java percebeu que a linguagem que desenvolveram era perfeita para programação Web.2. adicionou suporte a Java na versão 2. 1. Um dos desafios fundamentais está relacionado com a instalação segura de aplicações que consumam o mínimo de recursos do sistema. A “nova” linguagem foi rapidamente considerada como uma poderosa ferramenta para desenvolver aplicações Internet.1 Simples. interface gráfica. A Netscape Communications. também seguiram o exemplo. cada vez mais complexos.homenagem ao gosto da equipe por café. Java. Os conceitos fundamentais de Java são absorvidos rapidamente e. não sendo necessário um extensivo treinamento por parte dos programadores. etc. os programadores conseguem ser produtivos em pouco tempo. Orientada a Objetos e Familiar Uma das características principais de Java é a simplicidade da linguagem. como a Microsoft (Internet Explorer 3. A seguir. provou-se adequado para o desenvolvimento dos sistemas atuais. de acordo com as necessidades da aplicação em particular. ao contrário de C++. O paradigma de orientação a objetos.

2. nem aritmética de apontadores. seção ). A linguagem possui características de segurança e a própria plataforma realiza verificações em tempo de execução. Para acomodar esta diversidade de plataformas. aplicações escritas em Java estão “seguras” contra códigos não autorizados que tentam criar vírus ou invadir sistemas de arquivos. 1. a natureza interpretada de Java resolve o problema de distribuição de código binário. Java também define os tamanhos de seus tipos básicos e o comportamento de seus operadores aritméticos. Java possui um segundo nível de verificações (em tempo de execução). Além de prover verificações durante a compilação. Além disto. A liberação da memória dos objetos que não são mais referenciados é feita por meio de um mecanismo chamado garbage collection (coleta de lixo). seu desempenho. Desta forma.2 Robusta e Segura Java foi projetada para criar software altamente confiável. Assim. 1. pela característica interpretada da linguagem. aspectos de segurança são de fundamental importância. Não existem tipos como apontadores.3 Arquitetura Neutra e Portável Para suportar a distribuição em ambientes heterogêneos. Obviamente. Como Java foi desenvolvida para operar em ambientes distribuídos. o compilador Java gera bytecodes. um formato intermediário neutro projetado para o transporte eficiente em múltiplos ambientes de software/hardware. Assim. Pág 7 . em geral. Esta arquitetura neutra e portável é chamada de Máquina Virtual Java (Java Virtual Machine.2. O modelo de gerência de memória é extremamente simples: objetos são criados por meio de um operador new. JVM. As próprias características do Java ajudam o programador a seguir bons hábitos de programação. por exemplo). por exemplo). aplicações que necessitam de grande poder computacional podem ter suas seções mais críticas reescritas em código nativo (compilado a partir da linguagem C.4 Alto Desempenho Desempenho é um fator que sempre deve ser levado em consideração.2. Desta forma. as aplicações devem ser capazes de executar em uma variedade de sistemas operacionais e de arquiteturas de hardware. O interpretador da linguagem possui algumas otimizações que permitem a execução mais eficiente de código Java. elimina-se um importante tipo de erro que atormentava os programadores C++. A neutralidade da arquitetura é apenas uma parte de um sistema verdadeiramente portável. é inferior ao de linguagens compiladas para linguagem de máquina (C++. não existem incompatibilidades de tipos de dados entre arquiteturas de software/hardware diferentes.1.

ligar e testar). Java pode ajudálo a: Pág 8 . através da própria rede). a linguagem oferece uma série de primitivas sofisticadas de sincronização (semáforos.5 Interpretada. poderosa. 1.2. os usuários não notam diferenças significativas entre aplicações desenvolvidas em Java e outras linguagens compiladas. obtem-se um alto grau de interatividade com o usuário da aplicação. como browsers. Além disto. 1. a fase de ligação (linking) de um programa é simples. Um fato importante é que todas as bibliotecas de sistema da linguagem Java foram desenvolvidas para serem “thread safe”. o ciclo de desenvolvimento. Esta característica proporciona a possibilidade de se atualizar transparentemente as aplicações. Aplicações de rede. Assim. incremental e leve. Por exemplo. Java suporta multithreading no nível da linguagem (suporte nativo e não por meio de bibiotecas externas). um usuário utilizando um browser pode rodar várias animações enquanto busca uma imagem e faz um “scroll” da página Web. que podem melhorar consideravelmente o desempenho das aplicações. Desenvolver aplicações em Java resulta em um software que é portável em múltiplas plataformas de hardware e software (sistemas operacionais. Multithreaded e Dinâmica O interpretador da linguagem Java pode executar os bytecodes em qualquer máquina onde exista o ambiente de execução (run-time environment) instalado. ou seja. Pela característica interpretada da linguagem. seguro e de alto desempenho. ao mesmo tempo. prototipação e testes tende a ser mais rápido do que o método tradicional (compilar. por exemplo).3 Como Java Pode Mudar Minha Vida? Consideradas individualmente. A capacidade da linguagem Java de executar várias threads dentro de um programa (processo) permite que uma aplicação seja construída de tal forma que para cada atividade seja reservada uma thread exclusiva de execução. interfaces gráficas). Novos módulos podem ser ligados sob demanda a partir de diversas fontes (inclusive. Assim. A linguagem Java é dinâmica pois as classes (código) somente são ligadas (linked) a aplicação quando necessário. que compilam os byte-codes Java para a linguagem nativa da máquina em particular. as características discutidas nos itens anteriores podem ser encontradas em uma variedade de ferramentas de desenvolvimento de software. Resumindo. Provavelmente. para aplicações fundamentalmente interativas. Atualmente. Java deve tornar seus programas melhores e exigir menos esforço de desenvolvimento do que outras linguagens. A grande novidade é a maneira como Java (e seu ambiente de execução) combinaram estas qualidades e produziram uma linguagem flexível e. pode-se dizer que. não existe a possibilidade de ocorrência de conflitos caso threads concorrentes executem funções destas bibliotecas. tipicamente precisam realizar várias tarefas “simultaneamente”.Existem soluções como compiladores Just-in-Time (JIT).

estrutura de dados. etc.4 Provavelmente. Por que? Escreve-se menos linhas de código em Java e a linguagem é mais simples que C++. Entretanto. Servlets são similares a applets pois também são extensões a um ambiente de execução. pode-se desenvolver programas Java standalone (isto é. Pág 9 . métodos. Esta API central proporciona as seguintes funcionalidades: • Fundamentais: Objetos. Java não serve apenas para escrever applets bonitinhos e divertidos para WWW. Evitar dependências de plataforma: utilizando alguns conselhos simples de programação. Utilizando a extensa biblioteca (API) Java. A característica de orientação a objetos e a extensa API (Application Program Interface) permite que um programador reutilize facilmente código desenvolvido (e testado) por outras pessoas.) sugerem que um programa escrito em Java pode ser até quatro vezes menor do que um mesmo programa desenvolvido em C++. por exemplo) a partir de um servidor central. Escrever menos código: comparações de métricas de programas (número de classes. Applet é um programa que possui determinadas características que o permitem executar em um browser (que possui suporte a Java). o Que Java Pode Fazer? 1. threads. tempo. entrada/saída. Mas Afinal. é fácil de aprender. WWW. run anywhere. Java é uma linguagem de propósito geral e uma poderosa plataforma de software. consegue-se criar aplicações 100% Java (100% Pure Java) que executam corretamente em qualquer plataforma: Write once. Em vez de executar em um browser. Desenvolver programas mais rapidamente: o tempo necessário para desenvolver uma aplicação em Java pode ser até duas vezes menor do que construir o mesmo programa em C++. os programas em Java mais conhecidos são os applets. data. os servlets executam em servidores Java (mail. números. Escrever um código melhor: a linguagem encoraja boas práticas de programação. e seu esquema de gerência de memória (garbage collection) ajuda a evitar os temidos leaks de memória. Como a API do Java suporta todos estes tipos de programas? A API do Java é dividida em pacotes (packages) de componentes de software que oferecem uma ampla gama de funcionalidades. etc. Existe uma API central (core API) que está incluída em qualquer implementação da plataforma Java. especialmente para aqueles programadores familiarizados com C ou C++. strings. por exemplo).• • • • • • Iniciar rapidamente o desenvolvimento: embora Java seja uma linguagem orientada a objetos. Distribuir software mais facilmente: pode-se facilmente atualizar aplicações (applets. que não executam em browsers) para uma ampla variedade de aplicações. Outro tipo de programa especial do Java é o servlet.

5 Arquitetura Java Na realidade. entre outras. • Java Database Connectivity (JDBC): oferece um acesso uniforme a uma grande variedade de bancos de dados relacionais. Com o compilador.1 A Linguagem de Programação Java Java é uma linguagem de programação de alto nível com as seguintes características (apresentadas nos itens anteriores): • • • • • • • • • • Simples Arquitetura neutra. servidores. controle de acesso e certificados. já a interpretação acontece cada vez que o programa é executado. Os bytecodes são independentes de arquitetura de software/hardware. processamento de fala.5. Observe que a compilação ocorre apenas uma vez. groupware.• Applets: funções utilizadas pelos applets. Java possui extensões padronizadas. gerência de chaves públicas e privadas. portável Interpretada Orientada a objetos Distribuída Alto desempenho Multithreaded Robusta Segura Dinâmica Java possui uma característica um tanto rara: um programa Java é compilado e interpretado. Java tem dois significados: é uma linguagem de programação e uma plataforma. é feita a tradução de um programa Java para um código intermediário chamado de bytecode. • Serialização: permite um esquema de persistência leve e uma comunicação via Remote Method Invocation (RMI). • Segurança: suporte. Os programas podem se adaptar automaticamente a locais específicos e apresentar a linguagem apropriada. para assinaturas eletrônicas. • Networking: URLs. Estas extensões definem API´s para manipulação de imagens 3D. and endereços IP. 1. Além da API central. animação. Com o interpretador cada instrução bytecode é analisada (parse) e executada no computador. A figura abaixo ilustra esta situação: Pág 10 . TCP and UDP sockets. • Internacionalização: auxilia o desenvolvimento de programas que possam ser localizados para usuários de todo o mundo. telefonia. em alto e baixo nível. 1.

Assim. Todo interpretador Java. O produto da compilação (bytecodes) pode então ser executado em qualquer implementação da Máquina Virtual Java. run anywhere” possível. apresentada no item anterior. Solaris e Macintosh sem a necessidade de recompilação (figura a seguir). é a fundação (base) da plataforma Java e já existem implementações da JVM para diversas plataformas de hardware/software. apenas) que executa sobre outras plataformas baseadas em hardware e software (sistema operacional). presente em uma ferramenta de desenvolvimento ou em um browser.Pode-se imaginar os bytecodes como a “linguagem assembly” da Máquina Virtual Java (Java Virtual Machine. é uma implementação da JVM. Pode-se compilar os programas Java em qualquer plataforma que possuir um compilador Java. O conceito de bytecodes auxilia a tornar o lema “write once. API) A Máquina Virtual Java. A JVM também pode ser implementada diretamente em hardware. JVM). Pág 11 . o mesmo programa Java pode executar em Windows NT. 1.2 A Plataforma Java Plataforma é o ambiente de hardware ou software onde um programa é executado. A plataforma Java possui dois componentes: • A Máquina Virtual Java (JVM) • A Interface de Programação de Aplicação (Application Programming Interface.5. A plataforma Java difere da maioria das outras pelo fato de ser uma plataforma (de software.

standalone ou applet. a API e a JVM da plataforma Java “isolam” o programa Java das diferenças das plataformas de hardware. A API Java é agrupada em bibliotecas (packages) de componentes relacionados. o JDK oferece outros utilitários (depurador. O JDK contém toda a API central (core API) e sua documentação. “compactador” de classes.2. compiladores e interpretadores otimizados.4/index. As principais ferramentas que acompanham o JDK são: • javac: compilador que pode compilar qualquer tipo de programa Java • java: interpretador utilizado para executar aplicações Java (standalone) • appletviewer: ambiente para execução de applets Java Além destas ferramentas. 1.8.) que serão apresentados ao longo do curso.sun. A figura a seguir ilustra um programa Java. que executa em uma plataforma Java.A API do Java é uma grande coleção de componentes de software. Java tende a possuir um desempenho pior do que aplicações em código nativo.com/j2se/1.6 Desenvolvendo os Primeiros Programas em Java Plataforma Java Antes de iniciar o desenvolvimento de programas em Java. a versão da API que é suportada pelos browsers atuais (IE 5. Entretanto.0 e Communicator 4. compiladores just-in-time podem aproximar o desempenho de Java ao do código nativo sem ameaçar a portabilidade da linguagem. etc. além de exemplos de applets. Note que.6) é a 1. gerador de documentação.1.2 do JDK de Java 2). A versão mais recente do JDK é a 1. é necessário possuir um ambiente de desenvolvimento Java. que oferecem muitas funcionalidades úteis como elementos de interface gráfica (GUI).2 (a Sun passou a denominar a versão 1. A ferramenta mais comumente utilizada chama-se Java Development Kit (JDK). O JDK é gratutito para download e pode ser obtido em: http://java. Programa Java API Java Máquina Virtual Java Plataforma Hardware Por ser um ambiente independente de plataforma. prontos para uso.html Pág 12 . desenvolvida pela própria Sun. Entretanto.

Word.class no mesmo diretório do arquivo fonte (HelloWorldApp. etc. execute o interpretador Java: java HelloWorldApp Observação Importante: o argumento do interpretador Java é o nome da classe a ser executada e não o nome do arquivo.println("Hello World!"). Textpad. */ class HelloWorldApp { public static void main(String[] args) { System.java).java com o seguinte código Java: /** * A classe HelloWorldApp implementa uma aplicação que * simplesmente mostra "Hello World!" na saída padrão (monitor). independentes de plataforma. O arquivo gerado contém os bytecodes Java. crie um arquivo (ASCII) chamado HelloWorldApp.). Executar a Aplicação No prompt do DOS.java Se a compilação tiver êxito. //Mostra a string } } Compilar o Código Fonte No prompt do DOS. execute o compilador Java: javac HelloWorldApp.1 Aplicação “Hello World” Nesta seção. Criar um Arquivo Fonte em Java Usando um editor de texto qualquer (notepad.1. o compilador vai criar um arquivo chamado HelloWorldApp.out. verifique se o programa foi digitado corretamente (cuidado com as letras maiúsculas/minúsculas). O nome da classe deve ser digitado da mesma maneira que foi definido no código fonte (maiúsculas/minúsculas). Pág 13 . Se a compilação falhar. são descritos os passos para a criação de uma aplicação Java “standalone”. que são interpretados pelo ambiente de execução do Java.6.

Definindo uma Classe Na linguagem Java. A aplicação “Hello World”. então. O interpretador. A linguagem Java suporta um terceiro tipo de comentário. System. na verdade. Utilizando Classes e Objetos Os outros componentes de uma aplicação Java são os objetos. por exemplo. A classe System oferece acesso a funções do sistema operacional. o esqueleto de qualquer programa Java é uma definição de classe. O método main controla o fluxo do programa. cada método (função) e variável deve existir dentro de uma classe ou objeto (uma instância de uma classe). Quando se executa uma aplicação. } A palavra-chave class começa a definição de uma classe denominada name. via interpretador Java. utiliza uma outra classe.1. usa os delimitadores /** e */.. delimitado por /* e */. métodos e comandos (statements) da linguagem Java escritos para implementar as funcionalidades desejadas. estilo C. O Método main O ponto de entrada de qualquer aplicação Java é o método main. a forma mais simples de se definir uma classe é: class name { . invoca o método main definido dentro daquela classe. As variáveis e os métodos da classe são delimitados por um par de chaves. Comentários em Java A aplicação “Hello World” tem dois blocos de comentários. Em Java. uma linha de código é explicada por meio de um comentário marcado com os caracteres //.. vamos analisar esta aplicação standalone. A aplicação “Hello World” não possui variáveis e tem um único método chamado main. A linguagem Java não suporta funções ou variáveis globais. classes. O primeiro bloco. que é parte da API que acompanha o ambiente Java. Portanto.2 Anatomia da Aplicação Uma vez executada a primeira aplicação Java. Depois. aloca recursos e executa quaisquer outros métodos que fazem parte da funcionalidade da aplicação. no início do programa. Pág 14 .6. especifica-se o nome da classe a ser executada.

crie um arquivo chamado Hello. o compilador vai criar um arquivo chamado HelloWorld. Este arquivo HTML deve conter o seguinte código: <HTML> <HEAD> <TITLE> Um Programa Simples </TITLE> </HEAD> <BODY> Aqui está o meu applet: <APPLET CODE="HelloWorld. verifique se o programa foi digitado corretamente (cuidado com as letras maiúsculas/minúsculas). Textpad.). etc. import java.6.Applet. Word. 25). O arquivo gerado contém os bytecodes Java.1. crie um arquivo (ASCII) chamado HelloWorld.awt. public class HelloWorld extends Applet { public void paint(Graphics g) { g.drawString("Hello world!".applet.html no mesmo diretório que contém a classe HelloWorld.java com o seguinte código Java: import java. execute o compilador Java: javac HelloWorld.Graphics. que são interpretados pelo ambiente de execução.class no mesmo diretório do arquivo fonte (HelloWorld. independentes de plataforma. Se a compilação falhar. são descritos os passos para a criação de um applet Java.java Se a compilação tiver êxito.java). } } Compilar o Código Fonte No prompt do DOS.class. que pode ser executado em um browser Web.3 Applet “Hello World” Nesta seção. 50. Criar um Arquivo HTML que Inclua o Applet Utilizando um editor de texto qualquer.class" WIDTH=150 HEIGHT=25> Pág 15 . Criar um Arquivo Fonte em Java Usando um editor de texto qualquer (notepad.

uma URL do tipo: file:/home/asouza/HTML/Hello. Explorar. digite no prompt do DOS: appletviewer c:\src\Hello. deve-se carregar o arquivo HTML em um ambiente que possa executar applets Java. 5. pode-se digitar. algumas das várias fontes para programadores Java. para carregar o applet. Por que os applets Java são considerados como uma aplicação neutra (em termos de plataforma)? 4.html Para utilizar o Applet Viewer. no campo Location.html 1. na Internet.</APPLET> </BODY> </HTML> Executar o Applet Para executar o applet.7 Exercícios: 2. Como você acha que a citação apresentada no início da apostila se relaciona com Java? Pág 16 . executar e observar o código-fonte de alguns exemplos disponíveis. Este ambiente pode ser um browser compatível com Java ou um programa para visualização de applets. No browser. Qual a diferença entre um applet Java e uma aplicação standalone? 3. como o Applet Viewer que acompanha o JDK.

um cachorro tem um estado (nome. Por exemplo. Pode-se olhar a sua volta e encontrar vários exemplos de objetos: cachorro. Java aproveita os melhores conceitos e funcionalidades de linguagens mais antigas (principalmente Eiffel. Portanto. com fome) e um comportamento (latindo. o conceito de “orientação a objetos” continua um pouco confuso e é propagado como a “bala de prata” que vai resolver todos os problemas do mundo do software. Assim. com exceção dos tipos de dados primitivos. tudo em Java é um objeto (até mesmo os tipos primitivos podem ser encapsulados dentro de objetos. Como outras linguagens de programação modernas. lambendo).1 2. comendo. Como uma linguagem orientada a objetos. 2. possuem também estado e comportamento. pode-se representar objetos do mundo real utilizando objetos de software. Por exemplo. raça. bicicleta. O paradigma de orientação a objetos já demonstrou que é muito mais do que uma simples “moda”. a linguagem Java é orientada a objetos.1. Na verdade. seguindo os paradigmas de desenvolvimento mais utilizados. etc.2. Analogamente. se for necessário). SmallTalk. ou seja. Objective C e C++). como C++. cadeira. cor. resultados que não seriam possíveis de se obter com técnicas procedurais. Java é um amálgama de várias técnicas desenvolvidas ao longo dos anos. o conceito de objetos é fundamental para o entendimento desta tecnologia. televisão. evoluem ao longo do tempo. objetos de software são modelados de acordo com os objetos do mundo real. Benefícios da tecnologia de objetos são observados à medida que um número cada vez maior de empresas “migram” seus produtos para este tipo de modelo. Estes objetos do mundo real compartilham duas características: possuem um estado e tem um comportamento. pode-se alcançar.1 Conceitos Básicos Objetos Como o próprio nome “orientado a objetos” indica. Infelizmente. Java vai além do C++ pois estende o modelo de objetos e remove as maiores complexidades da linguagem. Há um constante refinamento e aperfeiçoamento para atender às exigências cada vez maiores dos usuários. objetos de software podem ser usados para modelar conceitos abstratos (por exemplo. com técnicas de programação orientada a objetos. Além disto. uma visão superficial de programação orientada a objetos é afirmar que este paradigma é simplesmente uma nova maneira de organizar o código fonte. um evento de interface gráfica que representa a ação do usuário pressionando uma tecla). Conceitos de Orientação a Objetos Linguagens de programação. Pág 17 . Por exemplo. Um objeto de software armazena seu estado em variáveis e implementa seu comportamento com métodos. como os próprios idiomas humanos.

Objetos comunicam-se entre si por meio do envio de mensagens.A ilustração a seguir é uma representação comum do conceito de objeto: Detalhes de implementação (privados) API (pública) Tudo que o objeto de software conhece (estado) e pode fazer (comportamento) é expressado pela variáveis e métodos do objeto. Muitas vezes. não é preciso saber como o mecanismo de troca de marchas funciona. A interação entre os objetos é que permite se obter todas as funcionalidades de uma aplicação. uma bicicleta só é útil quando um outro objeto (ciclista) interage com ela. Por exemplo.2 Mensagens Geralmente. aumentar a velocidade da pedalagem e trocar de marcha. um núcleo de variáveis dentro de uma membrana protetora de métodos. um objeto que modela uma bicicleta poderia ter variáveis que indicam seu o estado atual: velocidade é 20 km/h. o objeto A envia uma mensagem para o objeto B. Pág 18 . As variáveis de um objeto fazem parte do seu núcleo (centro). Esta capacidade de um objeto controlar quais componentes podem acessar seus métodos e variáveis é chamada de Controle de Acesso (a ser descrita mais detalhadamente nas próximas aulas do curso). a encapsulação é usada para esconder detalhes de implementação pouco importantes. um objeto pode desejar expor algumas de suas variáveis ou esconder alguns de seus métodos. Esta representação conceitual de um objeto. Assim. por razões de implementação ou eficiência. Entretanto. os detalhes de implementação podem ser mudados sem afetar outras partes do programa. Empacotar as variáveis de um objeto sobre a proteção de seus métodos é chamado de encapsulação (seção ). apenas saber qual método deve ser invocado. apenas qual alavanca deve ser movida. quando se deseja trocar uma marcha na sua bicicleta. Basicamente. marcha atual é a quinta. em programas. Exemplos de métodos deste objeto seriam: frear. Por exemplo.1. 2. é um modelo ideal que deve servir de como meta para projetistas de sistemas orientados a objetos. Analogamente. Os métodos envolvem e escondem o núcleo do objeto de outros componentes (objetos) da aplicação. um objeto sozinho não é muito útil e aparece como um componente de uma aplicação maior que contém vários outros objetos. Quando um objeto A deseja que o objeto B realize um dos seus métodos (de B). esta representação não é totalmente realista. Estas variáveis e métodos são formalmente chamados de variáveis de instância e métodos de instância a fim de distinguí-los de variáveis e métodos de classe (descritos no item Classes). muitas vezes não é necessário saber como um objeto foi implementado. Por exemplo.

deve-se instanciá-la a fim de utilizar seus objetos. Entretanto. Valores de variáveis de instância existem para cada instância (objeto) da classe. pode-se tirar vantagem de que os objetos do mesmo tipo são similares e criar uma “fôrma” para estes objetos. é possível ter vários objetos do mesmo tipo que compartilham características. uma classe é uma fôrma (protótipo) que define as variáveis e métodos comuns a todos os objetos de um certo tipo. Por exemplo. pode-se dizer que um objeto bicicleta é uma instância de uma classe de objetos conhecida como bicicletas. Em software orientado a objetos. deve-se indicar qual a marcha desejada. Quando se cria uma instância de uma classe. 2. cria-se um objeto daquele tipo e o sistema aloca memória para as variáveis de instância definidas para a classe. Assim. o objeto que recebe a mensagem precisa de mais informações para saber exatamente o que fazer. Esta informação acompanha a mensagem como um parâmetro. Resumindo. quando você quer trocar as marchas em uma bicicleta. Assim. Bicicletas possuem estado e comportamento comuns.Mensagem Objeto A Objeto B Algumas vezes. muitas vezes existem vários objetos do mesmo tipo. Depois de criado. três componentes fazem parte de uma mensagem: • o objeto para onde a mensagem é endereçada (bicicleta) • o nome do método a realizar (mudar a marcha) • parâmetro(s) necessário(s) para realizar o método (segunda marcha) Observação: objetos não precisam estar no mesmo processo ou na mesma máquina para enviar e receber mensagens de uns para os outros. o estado de cada bicicleta é independente e pode ser diferente de outras bicicletas. Desta forma. utilizando a terminologia de orientação a objetos. Por exemplo. pode-se invocar os métodos de instância do objeto. Pág 19 . Tais fôrmas de software são chamadas de classes .1.3 Classes No mundo real. depois de criar a classe bicicleta.

não podem acessar métodos ou variáveis de instância. Métodos de classe só podem manipular variáveis de classe. ou seja. • Modularidade: Pág 20 . Resumindo. consegue-se criar variáveis de instância. dentro de um objeto. desta forma qualquer função dentro do programa pode acessar os dados. Encapsulação permite esconder. estas três características: • Encapsulação • Herança • Polimorfismo 2. • Ocultamento da informação: um objeto possui uma interface pública que outros objetos podem utilizar para comunicar-se com ele. a solução é criar variáveis globais. Na programação orientada a objetos. a idéia de encapsulação. é uma ferramenta poderosa que oferece dois benefícios principais aos programadores: o código fonte de um objeto pode ser escrito e mantido independentemente do código fonte de outros objetos. O sistema cria uma única cópia de uma variável de classe. O problema surge quando se deseja tornar uma variável disponível a outras funções. tanto sua variáveis quanto os métodos que manipulam estas variáveis. Pode-se acessar variáveis e métodos de classe sem ter a necessidade de se instanciar um objeto da classe. Assim. ou seja. classes podem também definir variáveis de classe (class variables) e métodos de classe (class methods). 2. Infelizmente. na programação estruturada também pode-se esconder os dados dentro de uma função simplesmente criando variáveis locais. o objeto pode manter informações e métodos privados que podem ser mudados a qualquer momento sem afetar os outros objetos. Além disto. apesar de simples. De que maneira este ocultamento de informação difere da abordagem estruturada? Por exemplo. que podem ser acessadas por qualquer método do objeto mas não são visíveis por outros objetos. no mínimo. Em um programa estruturado. uma linguagem de programação deve oferecer. todos os objetos daquela classe compartilham as mesmas variáveis de classe.2 Características da Tecnologia de Objetos Para ser considerada verdadeiramente orientada a objetos. é possível controlar acessos de outros componentes aos dados do objeto.2.1 Encapsulação Uma das principais diferenças entre o paradigma de programação estruturada e o modelo de orientação a objetos é a característica de encapsulação.Além das variáveis e métodos de instâncias.

se uma montain bike possui um conjunto extra de marchas. objetos são definidos em termos de classes. Subclasses podem adicionar variáveis e métodos a aqueles herdados. podemos citar: Pág 21 . a classe bicicleta é uma superclasse de mountain bikes e bicicletas de corrida. Analogamente. etc. assento. pedais. Consegue-se obter muitas informações sobre um objeto conhecendo a sua classe. Por exemplo. Como benefícios do conceito de herança. você poderia sobrecarregar o método “mudar marcha” de tal forma que seja possível escolher este novo conjunto de marchas. Subclasses também podem redefinir (override) métodos herdados e oferecer implementações especializadas para estes métodos. Na terminologia de orientação a objetos. mountain bikes e bicicletas de corrida são diferentes tipos de bicicletas. por exemplo) Entretanto. Por exemplo. ou hierarquia de classe pode ser tão “profunda” quanto necessário.2. quanto mais baixa na hierarquia for a posição de uma classe. O conceito de herança pode ser aplicado para mais de um nível. Mountain bikes e bicicletas de corrida compartilham alguns estados (velocidade. Mountain bikes e bicicletas de corrida compartilham certos comportamentos (frear. você pode não saber o que é uma penny-farthing. Por exemplo. cada subclasse herda os métodos da superclasse.2. Os métodos e variáveis são herdados através dos níveis. A árvore de herança. mas se lhe disserem que é uma bicicleta. subclasses não estão limitadas ao comportamento herdado de sua superclasse. Bicicletas Mountain Bikes Bicicletas de Corrida Cada classe herda o estado (na forma das declarações de variáveis) da superclasse. mountain bikes e bicicletas de corrida são subclasses da classe bicicleta. Além disto. Em geral.2 Herança De maneira geral. mais especializado é o seu comportamento.). você consegue imaginar o objeto (duas rodas. Sistemas orientados a objetos permitem também que classes sejam definidas em termos de outras classes. por exemplo).

parâmetro de retorno e argumentos) parecida com a do método herdado então não se trata de uma redefinição e sim de uma sobrecarga pois criou-se.. programadores podem reusar o código da superclasse várias vezes. contas_do_cliente[1] = conta_especial_do_joao. que foi redefinido por ContaEspecial. Existem vários tipos de polimorfismo. oferecidos pela superclasse. um novo método. Devido às características de herança. ContaEspecial conta_especial_do_joao. entenda-se a escolha correta de um método a ser executado para uma variável declarada como de uma classe. Por exemplo: Sejam duas classes Conta e ContaEspecial. mas que pode conter um objeto de uma subclasse desta. Por meio da utilização de herança. // O interpretador invoca o método de ContaEspecial Pág 22 . . O primeiro tipo. onde ContaEspecial é uma subclasse de Conta. 2.. contas_do_cliente[0] = conta_normal_do_joao. contas_do_cliente[0].3 Polimorfismo Segundo a terminologia de orientação a objetos. Este polimorfismo é classificado como polimorfismo de inclusão. é possível fazer com que a execução de um método dependa do tipo do objeto atribuído a variável.. Se a subclasse oferece um método de assinatura (nome. polimorfismo significa que uma mesma mensagem enviada a diferentes objetos resulta em um comportamento que é dependente da natureza do objeto que está recebendo a mensagem.retirada().. A superclasse abstrata define e pode implementar parcialmente o comportamento de uma classe mas a maioria das informações da classe fica indefinida ou não é implementada. na verdade.• Subclasses oferecem comportamentos especializados a partir de elementos básicos comuns. pode-se atribuir um objeto de uma subclasse a uma variável da classe pai (mas não o contrário!). Suponha que exista um método do Conta (retirada()).2. Outro tipo bastante interessante de polimorfismo é conhecido como acoplamento dinâmico (dynamic binding). é quando uma classe redefine a implementação de um método herdado. descrito no item anterior. Com o acoplamento dinâmico. Por acoplamento. Por dinâmico. // O interpretador invoca o método de Conta contas_do_cliente[1]. • Programadores podem definir classes abstratas que determinam comportamentos “genéricos”. entenda-se tempo de execução. Conta contas_do_cliente[20] . Assim: Conta conta_normal_do_joao.retirada(). Outros programadores completam estes detalhes por meio de subclasses especializadas.

2. 5 Considere um objeto do mundo real. Liste as variáveis e métodos deste objeto.3 1 2 3 Exercícios Quais são os dois principais componentes de um objeto? Qual a relação entre classe e objeto? Quais os benefícios do uso do conceito de mensagens para descrever a interação entre objetos? 4 Quais são as três principais características presentes no paradigma de orientação a objetos? Defina cada um destes conceitos. como um aparelho de som ou um forno. Tente definir também subclasses Pág 23 .

3. da linha de comando. toda a aplicação Java standalone deve possuir uma classe que defina o método main(). Entretanto.2 Valor de Saída do Programa Observe. Portanto. por meio da ferramenta javadoc (a ser apresentada no final do curso). 3. as analogias entre Java e C++ não são tão fortes quanto aquelas entre Java e C. não é possível retornar um valor de seu programa Java com return na função main(). que a função main() deve ser declarada com parâmetro de retorno do tipo void. existe uma série de diferenças importantes entre as linguagens como o mecanismo de tratamento de exceções.1.exit() com o valor desejado. Pág 24 . o que torna relativamente simples que programadores C aprendam a linguagem.1. 3.3. Este último tipo serve para produzir documentação on-line. A seguir são abordadas algumas das principais diferenças entre as linguagens. na seção . Este método tem a seguinte assinatura: public static void main(String args[]) O argumento da função é um vetor de strings.1 Argumentos de Linha de Comando Como visto no exemplo da seção . Ao contrário de C. convencionalmente chamado de args ou argv.length (assim como para qualquer vetor em Java). Apesar de Java utilizar muitas das terminologias do C++. se existirem. O tamanho do vetor argv é dado por argv. Diferenças entre Java e C/C++ Java é bastante parecido com C. Se for necessário retornar algum valor.3 Comentários Java suporta os mesmo delimitadores de comentário do C/C++ (/* */ e //) além de um terceiro tipo (/** */). deve-se usar o método System.Os elementos deste vetor são os argumentos. programadores C++ devem tomar cuidado para não ter uma falsa sensação de familiaridade com Java só porque as linguagens compartilham uma série de palavras-chaves.1. Assim. o primeiro elemento do array não é o nome da classe e sim o primeiro argumento da linha de comando.

Assim. MinhaClasse.3. Strings e identificadores (nomes de variáveis. Isto facilita a migração de programas Java para outros idiomas diferentes do inglês.1. MeuObjeto. a API de manipulação de Strings torna a representação de caracteres totalmente transparente para o programador. O formato Unicode é compatível com o ASCII pois os 256 primeiros caracteres Unicode são idênticos aos caracteres do padrão ISO8859-1 (Latin-1).MostraIncremento(). MeuObjeto. #ifdef e nem typedef.Incrementar(). que consiste do nome do pacote que contém a classe. Além disto.5 Sem Variáveis Globais Variáveis globais simplesmente não fazem parte da linguagem. chamados de Unicode (C/C++ utilizam caracteres de 8 bits. ele sabe exatamente onde encontrá-lo. Pág 25 . Em Java. Assim. separados por ponto. #include. Um dos problemas principais de C/C++ é a quantidade de contexto necessária para se entender o código de outros programadores: deve-se ler todos os cabeçalhos relacionados. MinhaClasse. Java elimina a necessidade de arquivos de cabeçalhos (headers files).contador = 1. Exemplos: MinhaClasse MeuObjeto. Assim. se você estiver utilizando apenas caracteres Latin-1. o nome da classe (ou objeto) e o nome do membro (variável ou método) da classe.1. toda variável e método deve ser declarada dentro de uma classe. não há como distinguir um caracter Java de 16 bits de caracteres de 8 bits convencionais.4 Caracteres Unicode Caracteres. Por exemplo. um programador Tailândes pode usar o alfabeto Thai para nomear variáveis e métodos no seu código-fonte. os arquivos-fonte em Java possuem simplesmente as declarações das suas classes e métodos. todos os #defines e typedefs.6 Sem Pré-processador // Variável de instância // Método de instância // Variável de classe // Método de classe Java não inclui nenhum tipo de pré-processador. Em vez de cabeçalhos. não existem diretivas como #define. 3. no formato ASCII). métodos e classes) são compostos de caracteres de 16 bits. Também não existem funções ou procedimentos “globais”.1. toda variável (método) em Java deve ser referenciado pelo seu nome qualificado. Assim. Java define um mapeamento entre os nomes dos pacotes/classes e os diretórios onde estão de tal forma que quando o compilador Java precisa ler um determinado arquivo de classe.incremento = 5. 3.

na forma de diretivas #ifdef ou #if. Não há a necessidade de estruturas ou uniões quando se possui classes. 3.7 Sem tipo struct ou union Java não possui estruturas ou uniões como tipos de dados. Com Java. Nestes casos. obtém-se o mesmo efeito simplesmente declarando uma classe com as variáveis de instância apropriadas. programadores podem ler.1. Para substituir o efeito do typedef basta declarar classes. a linguagem Java torna-se bastante livre de contexto. Pode-se obter algo similar declarando uma classe que possua apenas constantes.8 Sem tipos enumerados Java não possui tipos enum. Teoricamente. pode-se utilizar o mesmo nomes em diferentes classes pois os nomes são qualificados pela classe que os contêm. } Utilizar classes que contêm constantes proporciona uma vantagem em relação aos tipos enumerados de C/C++. ou seja. Exemplo: class Direcao { public static final int Norte = 1. obtém-se os efeitos de #define utilizando constantes. Java não possui nenhum mecanismo de compilação condicional. Ou seja. Na prática. você não pode utilizar estes nomes em nenhum outro enum.Em Java. public static final int Oeste = 4. 3. public static final int Leste = 3. a compilação condicional também é utilizada para fins de depuração. entender e modificar código de maneira mais fácil e rápida. public static final int Sul = 2. não existem partes do código específicas para uma determinada plataforma. a saída é utilizar constantes em Java para obter os mesmos resultados da compilação condicional (bons compiladores conseguem realizar compilação condicional implicitamente. afinal de contas uma classe efetivamente define um novo tipo. Em C/C++. Removendo todos estes recursos. compilação condicional não é necessária em Java pois a linguagem é independente de plataforma e.1. nomes definidos via enums devem ser únicos: se você possui um tipo enumerado chamado HotColors contendo os nomes Vermelho e Amarelo. Pág 26 . portanto. a compilação não será realizada em um trecho de código se o compilador conseguir provar que este trecho nunca será executado).

o uso de apontadores é essencial apenas para programação de baixo nível (device drivers. <<). • Não é possível calcular o tamanho em bytes de qualquer tipo primitivo ou objeto. ++. esta restrição não parecerá tão importante. Para um programador C. acostumado com o modelo de programação Java.1. Mas. Uma interface não é uma definição de uma classe. 3. Interfaces só podem declarar métodos e constantes. leva a programas mais difíceis de entender e modificar. foi descartada de Java. Eliminando-os.9 Sem herança múltipla Herança múltipla.10 Sem goto Java não possui um comando goto. Existem duas razões para estas restrições: • Apontadores são famosos por ser uma fonte quase inesgotável de bugs.auxilia a simplificação do código-fonte. • Apontadores e aritmética de ponteiros podem ser utilizadas para “contornar” os mecanismos de segurança do Java. -. Removendo os apontadores. Esta decisão de projeto da linguagem. Variáveis não podem ser definidas em interfaces.1. é uma definição de um conjunto de métodos que uma ou mais classes irão implementar.12 Sem apontadores Java não possui apontadores e não permite manipular endereços de memória de nenhuma forma: • Não é possível converter referência de objetos ou vetores em inteiros ou vice-versa. uma vez. em geral. • Não é possível realizar aritmética de ponteiros. Pág 27 . por exemplo). 3. e todos os problemas que pode causar.1. As vantagens da herança múltipla são proporcionadas por interfaces (que serão discutidas mais profundamente em uma aula próxima). simplifica-se a linguagem e elimina-se vários potenciais bugs. 3.3. Na verdade. temos um ambiente mais seguro e robusto. A experiência mostra que o uso de goto. a falta de apontadores pode ser uma restrição infeliz do Java. Na verdade.11 Sem sobrecarga de operadores Em Java não é possível sobrecarregar os operadores aritméticos padrões (+.1.

Construções Básicas da Linguagem Java A classe Count apresentada a seguir possui um método chamado countChars que lê e conta os caracteres de um Reader (um objeto que implementa um fluxo.out. onde a declaração aparece em relação a outros elementos do código.*. stream. O tipo de dados de uma variável determina quais valores a variável pode conter e as operações que podem ser realizadas sobre ela.err. a declaração int count define que a variável count é um inteiro (int). public class Count { public static void countChars(Reader in) throws IOException { int count = 0. o método countChars define duas variáveis: int count = 0.4."). Por exemplo. } } 4. Pág 28 . Reader in A declaração de uma variável sempre contém dois componentes: o tipo da variável e seu nome.-./) sobre este tipo de variável. import java.println("Usage: Count filename"). nome e escopo. Inteiros só podem possuir valores integrais (positivos ou negativos) e pode-se utilizar os operadores aritméticos (+.io. while (in. Mesmo um método pequeno como este utiliza muitas das construções básicas de Java e classes que pertencem a API central da linguagem.length >= 1) countChars(new FileReader(args[0])). } public static void main(String[] args) throws Exception { if (args.1 Variáveis e Tipos de Dados Todas as variáveis em Java possuem um tipo. else System. de entrada de caracteres) e mostra o número de caracteres lidos.*.read() != -1) count++. determina seu escopo. ou seja. Por exemplo. A localização de uma declaração de variável. System.println("Counted " + count + " chars.

Existem duas grandes categorias de tipos de dados na linguagem Java: primitivo e referência. A tabela a seguir apresenta todos os tipos primitivos suportados por Java. Tipo
byte short int long float double char boolean

Tamanho/Formato 8-bit complemento de 2 16-bit complemento de 2 32-bit complemento de 2 64-bit complemento de 2 32-bit IEEE 754 64-bit IEEE 754 16-bit Unicode true ou false

Descrição Byte-length integer Short integer Integer Long integer Single-precision floating point Double-precision floating point A single character A boolean value (true or false)

Uma variável de um tipo primitivo contém um único valor de tamanho/formato apropriados. O valor da variável count em countChars pode assumir desde 0 (valor inicial) até o número que representa o número de caracteres lidos. Vetores (arrays), classes e interfaces são tipos de referência. O valor de uma variável deste tipo, em contraste com os tipos primitivos, é uma referência para o valor ou conjunto de valores representados pela variável. A referência é como o endereço de um amigo: o endereço não é o seu amigo, mas é uma forma de se alcançá-lo. O método countChars usa uma variável do tipo de referência, in¸ que é um objeto Reader. Assim, pode-se utilizar o nome do objeto para acessar suas variáveis ou chamar algum de seus métodos. Observação Importante: Em Java, tipos primitivos sempre são passados por valor; já vetores e objetos são passados por referência. Exemplo: int a,b; a = 1; b = a; a = 2; // a = 2 e b = 1 pois int é um tipo primitivo (passagem por valor) Button p, q; p = new Button(); q = p; // q refere-se ao mesmo objeto que p (passagen por referência) p.setLabel(“Ok”); // Uma mudança no objeto via p String s = q.getLabel(); // s contém “Ok” Convenção: Nomes de variáveis começam com uma letra minúscula e nomes de classes com uma letra maiúscula. Se o nome da variável consiste de mais de uma palavra, as palavras são agrupadas e cada palavra depois da primeira começa com uma letra maiúscula (exemplo: numeroClientes). O escopo de uma variável corresponde ao bloco de código onde a variável é acessível e determina quando a variável é criada e destruída. A localização da declaração da variável

Pág 29

dentro do programa estabelece o seu escopo. De acordo com o seu escopo, uma variável pode ser das seguintes categorias:
• • • •

Variável membro Variável local Parâmetro de método Parâmetro de tratamento de exceção

Uma variável membro está associada a um objeto ou a uma classe. Pode ser declarada em qualquer lugar dentro de uma classe, desde que fora de um método. Uma variável membro está acessível para todo código dentro da classe. A classe Count não declara nenhuma variável membro. Variáveis locais são declaradas em qualquer ponto dentro de um método ou de um bloco de código dentro de um método. No método countChars, count é uma variável local. O escopo de count vai da declaração da variável até o fim do método countChars. Parâmetros de métodos são argumentos formais de métodos e construtores que são utilizados para passar valores para os métodos. Em countChars, in é um parâmetro do método. O escopo de um parâmetro é todo o método que o declara. Parâmetros de tratamento de exceção são similares aos parâmetros de método mas são argumentos de um tratador (handler) de exceções em vez de um método ou construtor. O método countChars não possui tratadores de exceção e, portanto, não possui parâmetros desta categoria. Variáveis locais e variáveis membros podem ser inicializadas na sua própria declaração. Por exemplo, o método countChars fornece um valor inicial de zero para a variável count: int count = 0;

Pág 30

Parâmetros de método de tratadores de exceção não podem ser inicializados desta forma. O valor do parâmetro é determinado pelo objeto que invoca o método. Pode-se declarar qualquer variável como final, incluindo parâmetros. O valor de uma variável final não pode ser alterado depois de inicializado. Para declarar uma variável deste categoria, basta usar a palavra chave final antes do tipo: final int aFinalVar = 0; Pode-se adiar, se necessário, a inicialização da variável. Porém depois de inicializada a primeira vez, novas modificações não são permitidas. Exemplo: final int blankfinal; ... blankfinal = 0; 4.2 Operadores

Operadores realizam alguma função em um, dois ou três operandos. Por exemplo, ++ é um operador unário, = é um operador binário. Java possui um único operador ternário ? : (equivalente a um if-else). Além de realizar uma função, um operador também retorna um valor. O valor e seu tipo dependem do operador e dos tipos de operandos. Por exemplo, operadores aritméticos retornam números. O tipo de dado retornado vai depender do tipo de operandos: se dois inteiros são somados, o resultado é um inteiro. Os operadores de Java podem ser divididos nestas categorias: aritméticos, relacionais e condicionais, bitwise e lógicos e de atribuição. Tais categorias são descritas a seguir. 4.2.1 Operadores Aritméticos

Java suporta vários operadores aritméticos para número inteiros e de ponto flutuante. A tabela a seguir lista os operadores aritméticos binários da linguagem: Operador
+ * / %

Uso
op1 + op2 op1 - op2 op1 * op2 op1 / op2 op1 % op2

Descrição Soma op1 e op2 Subtrai op2 de op1 Multiplica op1 por op2 Divide op1 por op2 Calcula o resto da divisão de op1 por op2

Observação: A linguagem Java estende a definição do operador + para incluir concatenação de strings. Por exemplo, o método countChars utiliza o + para concatentar “Counted”, o valor de count e “ chars”: Pág 31

Esta operação automaticamente converte o valor de count para o tipo String.têm versões pré-fixa e pós-fixa. o operador ++ aparece depois de seu operando (versão pósfixa). Ambas as versões incrementam o operando de 1.. retorna o valor depois do decremento 4. Observe que."). no exemplo..possuem versões unárias que realizam as seguintes operações: Operador + - Uso +op -op Descrição Promove op to int se é um byte. Analogamente. Entretanto. o método countChars() utiliza o operador != para determinar se o valor retornado por in. A tabela abaixo apresenta os operadores relacionais de Java: Pág 32 . Por exemplo. -. o laço abaixo irá executar uma vez a menos se mudarmos count++ para ++count. ++ também possui uma versão pré-fixa onde o operador aparece antes do operando. retorna o valor antes do incremento Incrementa op de 1. Por exemplo. A tabela abaixo resume a função destes operadores: Operador ++ ++ --- Uso op++ ++op op---op Descrição Incrementa op de 1. Os operadores + e . count = 0. ++ que incrementa seu operando de 1 e – que decrementa seu operando de 1.System. op++ retorna o valor do operando antes incrementá-lo e ++op retorna o valor do operando depois de incrementá-lo.2.2 Operadores Relacionais e Condicionais Um operador relacional compara dois valores e determina o relacionamento entre eles.println("Counted " + count + " chars. or char Negates aritmeticamente op Existem também dois outros operadores aritméticos unários. } while (count++ < 6). short. do { .out. O método countChars usa ++ para incrementar a variável count cada vez que é lido um caracter da entrada: count++. retorna o valor antes do decremento Decrementa op de 1.read não é igual a 1. retorna o valor depois do incremento Decrementa op de 1.

Operador
> >= < <= == !=

Uso
op1 > op2 op1 >= op2 op1 < op2 op1 <= op2 op1 == op2 op1 != op2

Retorna True se op1 é maior que op2 op1 é maior ou igual a op2 op1 é menor que op2 op1 é menor ou igual a op2 op1 e op2 são iguais op1 e op2 não são iguais

Em geral, operadores relacionais são utilizados com operadores condicionais para construir expressões mais complexas. Um destes operadores é &&, que realiza a operação E (booleana). Por exemplo: 0 < index && index < NUM_ENTRIES Em algumas situações, o segundo operando de um operador condicional nem chega a ser calculado. Considere a expressão: ((count > NUM_ENTRIES) && (in.read() != -1)) Se count é menor do que NUM_ENTRIES, o operando a esquerda de && retorna false. Neste caso, o valor de retorno de && pode ser determinado sem calcular o valor do operando a direita. Assim, o interpretador não irá executar o método in.read da expressão. O operador & é similar ao && se os seus operandos são do tipo boolean. Entretanto, & sempre calcula ambos os seus operandos. Analogamente, | é similar a | | se ambos os operandos são booleanos. Java suporta cinco operadores condicionais binários: Operador
&& || ! & |

Uso
op1 && op2 op1 || op2 ! op op1 & op2 op1 | op2

Retorna true se
op1 e op2 são ambos true, calcula condicionalmente op2 op1 ou op2 é true, calcula condicionalmente op2 op é false op1 e op2 são ambos true, sempre calcula op1 e op2 op1 ou op2 é true, sempre calcula op1 e op2

Além disto, Java possui um outro operador condicional, o operador : ?. É um operador ternário que, basicamente, funciona como uma “abreviatura” da expressão if-else: expression ? op1 : op2 O operador ?: avalia expression e retorna op1 se expression é verdadeira e op2 se é falsa. 4.2.3 Operadores Bitwise

Um operador bitwise permite realizar manipulação de bits. A tabela abaixo apresenta os operadores deste tipo: Pág 33

Operador
>> << >>> & | ^ ~

Uso
op1 >> op2 op1 << op2 op1 >>> op2 op1 & op2 op1 | op2 op1 ^ op2 ~op2

Operação shift dos bits de op1 p/ direita por uma distância dada por op2 shift dos bits de op1 p/ esquerda por uma distância dada por
op2
shift dos bits de op1 p/ direita por uma distância dada por op2 (unsigned)

bitwise and bitwise or bitwise xor bitwise complemento

Por exemplo, a expressão a seguir desloca (shift) os bits do inteiro 13 para a direita (uma posição): 13 >> 1; A representação binária do número 13 é 1101. Assim, o resultado da operação de shift é 110 ou 6 em decimal. Um shift a direita de 1 é equivalente, mas bem mais eficiente do que dividir o operando da esquerda por 2. Analogamente, um shift a esquerda equivale a uma multiplicação por 2. O operador and bitwise executa a função and, de forma paralela, em cada par de bits da cada operando. Suponha a seguinte operação: 12 & 13 O resultado é igual a 12. A representação binária de 12 é 1100 e a de 13 é 1101. Assim: 1101 & 1100 -----1100 O operador | realiza a função ou inclusivo e ^ realiza a função ou exclusivo. O operador complemento ~ inverte o valor de cada bit do operando: se o bit do operando é 1 o resultado é 0 e se o bit do operando é 0, o resultado é 1. 4.2.4 Operadores de Atribuição

O operador = é utilizado para se atribuir um valor a outro. O método countChars utiliza = para inicializar count: int count = 0; Java proporciona vários operadores “short cuts” que permitem realizar operações aritméticas, lógicas e bitwise juntamente com a atribuição. Por exemplo: Pág 34

i += 2; é equivalente a: i = i + 2; 4.3 Expressões

Expressões é que realizam o trabalho de um programa Java. Entre outras coisas, expressões são utilizadas para calcular e atribuir valores para variáveis e ajudar a controlar o fluxo de execução de um programa. Assim, o trabalho de uma expressão é duplo: realizar o cálculo indicado pelos elementos da expressão e retornar algum valor que é o resultado desta computação. Então, podemos definir um expressão da seguinte forma: série de variáveis, operadores e chamadas de métodos que retorna um único valor. Como discutido no item anterior, operadores retornam um valor. Portanto, o uso de um operador é uma expressão. Por exemplo: count++ é uma expressão que retorna o valor de count antes que a operação de incremento ocorra. O tipo de dado retornado por uma expressão depende dos elementos utilizados nesta expressão. A expressão count++ retorna um inteiro pois ++ retorna o mesmo valor que seu operando (count é um inteiro). O método counntChars() contém, além da expressão count++, algumas outras expressões, como esta: in.read() != -1 Tal expressão é interessante pois consiste, na verdade, de duas expressões. A primeira é uma chamada de método: in.read() Uma chamada de método é uma expressão que retorna o valor do método. Portanto, o tipo de dado desta expressão é o mesmo tipo de dado do parâmetro de retorno do método. O método in.read() tem como parâmetro de retorno um inteiro, assim a expressão in.read retorna um inteiro. A segunda expressão utiliza o operador !=. Na expressão em questão, os operandos de != são in.read() e -1. Note que in.read() é um operando válido para esta expressão pois retorna um inteiro. Assim, in.read() != -1 compara dois inteiros, o valor retornado por in.read() e -1. O valor retornado por != é true ou false dependendo do resultado da comparação. Pág 35

Considere esta expressão composta: x*y*z Neste exemplo em particular. Portanto. poderia se escrever (x + y) / 100. que Java permite a construção de expressões compostas de várias partes (expressões) menores desde que os tipos de dados requeridos por uma parte da expressão sejam compatíveis com os tipos de dados das outras partes. também. (params) expr++ expr-++expr --expr +expr -expr ~ ! new (type)expr * / % Pág 36 . Por exemplo. deve-se ser explícito e indicar com parênteses quais operadores devem ser avaliados primeiro. isto não vale para todas as expressões. postfix operators unary operators creation or cast multiplicative [] . Operadores com precedência maior são avaliados antes de operadores com uma precedência relativa menor. Os operadores nesta tabela estão listados em ordem de precedência: quanto mais alta a posição na tabela.Pode-se observar. a expressão a seguir fornece resultados diferentes dependendo de que operação é realizada primeiro: x + y / 100 Você pode determinar. a partir destes dois exemplos. sempre que possível. na expressão composta x + y / 100. Se não for determinado explicitamente a ordem desejada para o cálculo das operações. que a ordem de como a expressão é avaliada também é importante. Operadores com precedência maior são calculados primeiro. x + y / 100 é equivalente a x + (y / 100) Para tornar o código fácil de ler e manter. maior a sua precedência. Operadores que estão em uma mesma linha da tabela possuem igual precedência. Assim. a ordem com que a expressão é avaliada não é importante pois os resultados das multiplicações são independentes de ordem. o operador de divisão tem uma precedência maior do que o de adição. explicitamente. o compilador vai calcular primeiro a expressão y / 100. A tabela a seguir mostra a precedência dos operadores Java. Por exemplo. para tornar a expressão anterior nãoambígua. Por exemplo. para o compilador Java como deve ser avaliada uma expressão utilizando parênteses. o compilador toma esta decisão baseado na precedência atribuída aos operadores e outros elementos utilizados em uma expressão. Note. Entretanto.

pode ser um bloco de código Java delimitado por chaves { }.read() != -1) { count++. } Convenção: a chave { deve ficar no final da mesma linha que o while e a chave } deve começar uma nova linha.out.println("Read a character. Por exemplo: while (in. enquanto a expressão for verdadeira. De maneira geral. Um statement. algumas regras devem determinar qual deve ser avaliado primeiro. Os operadores de atribuição são avaliados da direita para a esquerda. Em Java. o while realiza alguma ação enquanto uma certa condição continua verdadeira. Count = " + count). while é chamado de um comando de controle de fluxo. System. na verdade. A linguagem Java suporta vários tipos de controle de fluxo. execute statement. incluindo: Pág 37 .4 Controle de Fluxo O método countChars utiliza um while para realizar um laço que lê e conta todos os caracteres da entrada : while (in. alinhada com o while.read() != -1) count++. ou seja. 4.additive shift relational equality bitwise AND bitwise exclusive OR bitwise inclusive OR logical AND logical OR conditional assignment + << >> >>> < > <= >= instanceof == != & ^ | && || ? : = += -= *= /= %= &= ^= |= <<= >>= >>>= Quando operadores de igual precedência aparecem em uma mesma expressão . determina a ordem de execução do código. A sintaxe geral do while é: while (expression) statement Ou seja. todos os operadores binários (exceto o operador de atribuição) são avaliados da esquerda para a direita.

// código para realizar a ação OK . } else { . } else { grade = 'F'. return 4. } else if (testscore >= 60) { grade = 'D'.. label: . } Pág 38 ..out. switch-case for.. a forma mais simples do if pode ser escrita como: if (expression) statement else é utilizado quando um diferente conjunto de operações deve ser executado quando a expressão é falsa: if (response == OK) { . if (testscore >= 90) { grade = 'A'. A outra forma do else é o else if que executa um bloco de código baseado em outra expressão. } else if (testscore >= 80) { grade = 'B'.println("DEBUG: x = " + x). throw break. continue. do-while try-catch-finally.. // código para realizar a operação Cancel } . Esta é a versão mais simples do if: o código é executado caso a condição dada seja verdadeira. Generalizando. } else if (testscore >= 70) { grade = 'C'.. while.1 If-else if (DEBUG) System. char grade. Exemplo: int testscore...Comando tomada de decisão laço exceção miscelâneos Palavra-chave if-else.1..

println("October"). sem um break Pág 39 .out. case 2: System. case 8: System..println("November"). apenas um bloco de código é executado (o primeiro onde a condição é verdadeira) e o fluxo de controle sai do if sem avaliar as demais condições. principalmente. break. case 7: System. break.out.out.. break. if (month == 1) { System. case 3: System.2 Switch O switch é utilizado para realizar uma execução condicional baseada em uma expressão.out. case 10: System.println("January"). Exemplo: int month. break.println("February"). break.out. case 4: System. } else if (month == 2) { System.out. Obviamente. Deve-se fazer esta escolha baseado. 4. case 9: System. break.println("August"). case 11: System. break.1.println("December"). Ou seja. case 6: System.println("May"). case 5: System. break.out.println("January").out. poderíamos implementar tal funcionalidade com if: int month.out.println("April").out.Um if pode ter um número qualquer de else if.out. switch (month) { case 1: System. Decidir quando utilizar if ou switch depende do “feeling” do programador.println("March"). O break faz com que o fluxo de controle saia do switch e continue na primeira expressão após do switch. . break.out. mas apenas um else.println("June").out. Note que. O break é necessário pois os case estão em “cascata”. break. Um ponto interessante do switch é o break colocado depois de cada case. case 12: System.println("February"). neste caso.println("July"). o valor do mês e executa o bloco de código apropriado.println("September"). break. break. } O switch avalia sua expressão. na facilidade de leitura do código. apesar de alguns valores de testscore satisfazerem mais de uma expressão.out.

break.println("August"). case 2: if ( ((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0) ) numDays = 29. Exemplo: int month. case 5: System. case 11: System.out. break. break. o fluxo de controle irá passar sequencialmente pelos próximos case.println("March"). Exemplo: int month. case 4: System.out.println("February"). case 4: case 6: case 9: case 11: numDays = 30.println("October"). Entretanto. existem algumas situações onde deseja-se proceder sequencialmente pelos case.out. case 10: System.println("July"). } Finalmente.out. case 9: System.out. break. break.println("January").println("May"). break. case 3: System. case 6: System.out.explícito. break.println("June"). switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31. break.out. switch (month) { case 1: System. Pág 40 .println("November").out. break.out.println("April"). case 8: System. pode-se usar default no final do switch para tratar todos os valores que não foram explicitamente tratados por um dos case.println("September").out. break. break. break. case 2: System. else numDays = 28.out. break. break. case 7: System. int numDays.

i++) { . é similar ao while exceto que a expressão é avaliada apenas no final da iteração do laço: do { statements } while (booleanExpression). break.println("December"). Java possui duas outras comandos de laço: for e do-while. break.length. i < length. critério de terminação e instrução de incremento).1 Laços Além do while. } 4. mas pode ser útil em determinadas situações. // faz alguma coisa com o elemento de a . pelo menos uma vez..1.case 12: System. Esta expressão é avaliada no início de cada nova iteração do laço. o laço termina.1 Tratadores de Exceção Pág 41 . o do-while. terminação é uma expressão que determina quando encerrar o laço. Por exemplo.out.1. o do-while é o tipo de laço menos utilizado.. } A forma geral do for é dada por: for (inicialização. as restrições do laço (instrução de inicialização. O for é utilizado quando se sabe.println("Hey.. that's not a valid month!"). a priori. Em geral. incremento é uma expressão que é chamada a cada iteração do laço. default: System. quando os comando do laço devem ser executados. int length = a.out.. sempre. Qualquer (ou todos) componente do for pode ser vazio. O outro laço suportado pelo Java. Exemplo: // a é um vetor de algum tipo . incremento) statements inicialização é uma expressão que inicia o laço – é executada uma vez no começo do laço. for (i = 0. int i. Quando a expressão é avaliada como false. terminação.. 4.. Finalmente.

Observação 2: continue somente pode ser chamado dentro de um laço. o controle retorna para o “fundo” do laço. Quando um método é declarado como void. isto significa que o controle retorna ao “topo” do laço. ou seja que permitem a mudança do fluxo de controle para labels pré-definidos. Assim. portanto.5. simplesmente coloque um valor (ou expressão que calcula o valor) depois do return: return ++count. Return. O conceito de exceção será abordado mais profundamente nas próximas aulas do curso.1 break. Em laços do tipo for e while. 4. O método que chamou a função que levantou a exceção pode usar try. a função pode levantar (throw) uma exceção para indicar a ocorrência de um erro (e seu tipo) para quem invocou a função. 4. a condição de terminação é reavaliada neste ponto e o laço continua ou não dependendo dos resultados do teste. Pode-se também tratar dados compostos de múltiplos caracteres via objeto String. catch e finally para capturar e tratar estas exceções. Em laços do-while.5 Arrays e Strings Como outras linguagens de programação. Java permite agrupar e gerenciar múltiplos valores por meio de um objeto array (vetor). Tais versões funcionam como uma alternativa ao famigerado goto e.Quando um erro ocorre em um método Java. 4.1 Array Pág 42 . deve se utilizar a versão de return sem valor. Existem duas formas de return: uma retorna um valor e a outra não. O return é utilizado para sair do método atual e retornar para o ponto imediatamente subsequente a chamada do método. Para retornar um valor. Observação 1: continue e break possuem versões “labeled”. O continue faz com que o fluxo de controle vá para a condição de terminação do laço.1. O valor retornado deve ser compatível com o tipo do parâmetro de retorno declarado pelo método. devem ser evitadas. continue e return (comandos de branching) break faz com que o fluxo de controle “salte” para o bloco de código (statement) imediatamente subsequente ao bloco de código atual.

para declarar um vetor de inteiros. Esta declaração não aloca nenhuma memória para armazenar os elementos do vetor.length que retorna o tamanho atual do vetor. o compilador irá exibir um erro e se recusará a compilar o seu programa. em particular o uso do vetor args: public static void main(String[] args) throws Exception { if (args. Vamos analisar novamente o método main.err.O método countChars não utiliza um vetor. ao criar um vetor. usa-se o operador new mais o tipo de dado dos elementos do vetor mais o número de elementos (delimitado por [ ] ): elementType[] arrayName = new elementType[arraySize].length >= 1) countChars(new FileReader(args[0])). A declaração de um vetor. deve-se utilizar int[] arrayOfInts. A parte int[] da declaração indica que arrayOfInts é um vetor de inteiros. else System. System. tem dois componentes: o tipo e o nome. j ++) { arrayOfInts[j] = j.println("[j] = " + arrayOfInts[j]). pode-se atribuir e recuperar os valores dos elementos: for (int j = 0. os índices de um vetor começam em 0 e vão até o tamanho do vetor menos 1.length. Por exemplo. O tipo do vetor inclui os tipos dos dados que compõem o vetor. } Observação Importante: Em Java. Se o seu programa tentar acessar qualquer elemento deste vetor antes de se alocar memória para ele. } Pág 43 . Esta seção mostra como criar e utilizar vetores em Java. j < arrayOfInts.out. length é uma propriedade oferecida por todos os vetores em Java. mas o método main declara um vetor como parâmetro de entrada. Para alocar memória aos elementos de um vetor. Para isto. Em geral. como qualquer outra variável. utiliza-se o operador new (o operador new será apresentado com maior profundidade nas próximas aulas). deve-se instanciar o objeto. A expressão a seguir aloca memória suficiente para que arrayOfInts armazene 10 elementos do tipo inteiro: int[] arrayOfInts = new int[10]. Após alocar memória ao vetor. Observe no exemplo acima que o laço for possui a expressão arrayOfInts.println("Usage: Count filename").

Vetores podem armazenar qualquer tipo de dado de Java. em tempo de execução. " chars. Os colchetes vazios indicam que o tamanho do vetor é desconhecido em tempo de compilação pois o vetor é passado. Existe uma classe diferente. O método main verifica a existência de pelo menos um elemento em args e. Neste ponto. i ++) { arrayOfStrings[i] = new String("Hello " + i). eles não podem ser modificados. O método main utiliza String na declaração do vetor args: String[] args Este código declara explicitamente um vetor que contém objetos String. utiliza o primeiro elemento do vetor (nome) para abrir um arquivo.. um para cada literal. ou seja. } Também é possível realizar a inicialização de um vetor durante sua própria declaração. “Jose”. main não precisa se preocupar em alocar memória para args. 4. ou seja." Neste caso. String arrayOfStrings[] = {“Joao”. o código a seguir declara um vetor que pode conter objetos String: String[] arrayOfStrings = new String[10]. mas ainda não foi alocada memória para as strings propriamente ditas. Assim. em caso afirmativo. “ Maria”}.. chamada Pág 44 . portanto. cada elemento contém uma referência para um objeto String.O ambiente de execução Java aloca o espaço para o vetor args e. incluindo tipos referência como objetos e outros vetores. o programa implicitamente aloca dois objetos String. deve-se alocar os objetos String separadamente: for (int i = 0.2 String Uma sequência de caracteres é chamada de string e é implementada em Java pela classe String.length. Observação Importante: objetos String são imutáveis. Por exemplo.lang. uma vez criados.5. Os elementos neste vetor são de tipos de referência. no pacote java. i < arrayOfStrings. com os argumentos da linha de comando. O método countChars também utiliza dois objetos na forma de strings literais: "Counted " . memória suficiente foi alocada para conter as referências.

de forma tabular." Duas destas strings são literais: Counted e chars. Java permite que se concatene strings utilizando o operador +. 12.StringBuffer que pode ser usada para criar e manipular caracteres sob demanda (“on the fly”). Escreva um laço for que inicialize uma matriz 10x15 com valores de 0 a 149. 11. x<12. Quantas vezes o laço abaixo irá executar? Qual o valor de x quando o laço terminar? for (int x=3. Escreva um laço (while. x+=2) ++count. O código a seguir concatena 3 strings para produuzir sua saída: "Counted " + count + " chars.. do { . 6.6 1 Exercícios Faça um programa que realize um “eco” (apresente na tela) de seus argumentos da linha de comando. na verdade é um inteiro que é convertido para string e então concatenado às demais. como descobrir as suas dimensões? (dica: uma matriz em Java pode ser vista como um vetor de vetores) 10. 2 Qual a principal diferença entre os tipos primitivos e os tipos de referência em Java? 3 O que é escopo de uma variável? Como é possível determiná-lo? 4 Quantas vezes o código abaixo será executado? Qual será o valor do contador quando o laço terminar? int count = 10. Pág 45 . 4. } while (count++ <= 15).. for. O método countChars usa esta funcionalidade para imprimir sua saída. Como você criaria uma matriz bidimensional de 20 x 10 elementos utilizando Java? 9. do-while) que resulte em um laço infinito. Escreva um laço for que inicialize um vetor de 50 inteiros com os valores 50 a 99. 7. os valores da matriz do exercício anterior. Escreva um código que mostre. 8. Escreva um laço while que execute 20 vezes. Dada uma matriz bidimensional. 5. a do meio. A terceira string. Converta este laço para um do-while.

cujo tipo é SimplePoint. O código a seguir define uma outra classe. A classe SimplePoint possui duas variáveis membro do tipo inteiro. Além disto. as variáveis recebem o valor 0 (expressões de atribuição para os dois membros da classe). origin. public SimplePoint origin = new SimplePoint(). Além disto. que representa um retângulo: public class SimpleRectangle { public int width = 0. public int y = 0. Para criar um objeto da classe SimplePoint. public class SimplePoint { public int x = 0. memória é alocada para o objeto e seus membros x e y. chamada SimplePoint. } Além de duas variáveis membros do tipo inteiro. SimpleRectangle. Classes e Objetos em Java Esta seção aborda como a linguagem Java implementa os conceitos de orientação a objetos (seção 2). x e y. Quando um novo objeto é criado. 5. Pág 46 . que representa um ponto em um espaço bidimensional.5. SimpleRectangle possui uma terceira variável. deve-se instanciar a classe. public int height = 0. A palavra-chave public que antecede a declaração de x e y indica que qualquer outra classe pode acessar livremente estas duas variáveis. width e height.1 Classe O código a seguir define uma classe. } Este segmento de código declara uma classe (na verdade. um novo tipo de dado). apresenta exemplos práticos do uso destes conceitos em Java. O nome de uma classe pode ser utilizado da mesma forma que o nome de um tipo primitivo para declarar variáveis.

0): public class Point { public int x = 0. a criação de um objeto do tipo SimpleRectangle aloca memória para as suas variáveis. chamada Point que contém um construtor que pode ser utilizado para inicializar um novo objeto da classe Point para um valor diferente de (0. this. Assim. } } Agora. tem-se uma nova versão de SimplePoint. ao criar um ponto.y = y. origin simplesmente referencia um objeto SimplePoint que está em outro lugar. int y) { this.Como no exemplo anterior. As classes SimplePoint e SimpleRectangle são implementações simplificadas. Neste caso. Poderia-se criar um mecanismo para inicializar suas variáveis com valores diferentes de 0. 78) Os valores 44 e 78 são passados para o construtor da classe e atribuídos então as variáveis x e y do objeto: Pág 47 . // a constructor! public Point(int x.1). public int y = 0. Por outro lado. a seguir. Tanto width quanto height são inteiros e estão inteiramente contidos dentro de SimpleRectangle. pode-se definir valores iniciais: new Point(44.x = x. a variável origin cria um objeto SimplePoint utilizando: new SimplePoint(). como ilustrado a seguir: Esta figura mostra a diferença entre tipos primitivos e tipos de referência (seção 4.

apresentando o ciclo de vida de um objeto (criação. public int height = 0. w. int h) { origin = p. } public Rectangle(Point p. Uma vez que um objeto terminou seu trabalho.finalize(). // four constructors public Rectangle() { origin = new Point(0. um programa Java cria muitos objetos de várias classes. 0). cria-se um objeto por meio de uma instanciação de classe. um método para calcular a área do retângulo e um método finalize que “limpa” a variável de referência do objeto: public class Rectangle { public int width = 0. } // a method for computing the area of the rectangle public int area() { return width * height. uso e destruição). origin. height = h. chamada Rectangle. h).A seguir. } // a method for moving the rectangle public void move(int x.1 Criando Objetos Em Java.2 Ciclo de Vida de um Objeto Tipicamente. super. tem-se uma nova versão de SimpleRectangle.x = x. Por exemplo. que possui quatro construtores. 5. 5.2. Estes objetos interagem entre si via envio/recebimento de mensagens. width = w.y = y. } protected void finalize() throws Throwable { origin = null. int w. 0). } public Rectangle(int w. um método para mover o retângulo. public Point origin. Esta expressão realiza. } public Rectangle(Point p) { origin = p. três ações: Pág 48 . int y) { origin. int h) { this(new Point(0. Estas interações é que irão proporcionar as funcionalidades de uma aplicação. } } As seções a seguir descrevem com detalhes o código acima. ele é destruído e seus recursos são “reciclados” para que outros objetos possam utilizá-los. na verdade. o código a seguir cria um objeto do tipo Rectangle a partir da classe Rectangle: Rectangle rect = new Rectangle().

200). Observe.1). 0). Os construtores de uma classe sempre possuem o mesmo nome da classe e não possuem parâmetro de retorno. podem aparecer da seguinte forma: Rectangle rect. deve-se utilizar o operador new. Assim. o valor da variável é uma referência para o valor representado pela variável. Inicializando um Objeto Como visto no código da classe Rectangle. • Inicialização: Rectangle() é uma chamada para o construtor de Rectangle.• Declaração: Rectangle rect é uma declaração de variável que informa ao compilador que o nome rect será utilizado para referir-se a um objeto da classe Rectangle. alocando a memória necessária. Declarando um Objeto A declaração de um objeto não é uma parte necessária para a criação de um objeto. Como outras declarações de variáveis. O operador new exige um único argumento: uma chamada a um construtor. classes podem oferecer um ou mais construtores para inicializar um objeto. 200). • Instanciação: new é o operador Java que cria um novo objeto. ou seja. apenas uma variável que pode referenciar um objeto Rectangle. Cada classe em Java oferece um conjunto de construtores para inicializar seus objetos. Aqui. o operador new cria o objeto e o construtor o inicializa. Por exemplo: new Rectangle(100. Depois desta expressão. as declarações dos construtores de Rectangle: Pág 49 . aloca espaço para o objeto. que incializa o objeto. 200) é o argumento de new. Assim. possui largura igual a 100 e altura igual a 200. embora muitas vezes apareça na mesma linha. O operador new retorna uma referência para uma variável: Rectangle rect = new Rectangle(100. rect refere-se para um objeto Rectangle cuja origem está em (0. Instanciando um Objeto O operador new cria um objeto. a declaração Rectangle rect não cria um novo objeto. classes e interfaces (a serem discutidas em uma próxima aula) podem ser usadas como tipos de dados. Lembre-se que classes e interfaces são tipos de referência (seção 4. Rectangle(100. ou seja. Para criar um novo objeto. Em Java. Declarações apenas notificam o compilador que vai se utilizar o nome rect para referenciar uma variável cujo tipo é Rectangle.

largura e altura. Um construtor que não possui argumentos é chamado de construtor default. Por exemplo. a programação orientada a objetos desencoraja a manipulação direta das variáveis de um objeto. Note que não se consegue colocar um objeto Point e um Retângulo em um estado inconsistente modificando as suas variáveis (e se fosse um triângulo?). int w. que não faz nada. Tais modificações devem ser realizadas por meio de métodos. algumas vezes faz sentido utilizar diretamente as variáveis de um objeto. o compilador é capaz de determinar qual construtor deve ser invocado. Desta forma. é razoável. 5. estes devem possuir um número diferente de argumentos e/ou argumentos de tipos distintos. Um objeto “ideal” oferece métodos pelos quais se consegue inspecionar ou modificar o seu estado. uma classe pode proteger suas variáveis contra manipulação direta por outros objetos se estas manipulações podem ameaçar a consistência do objeto.2. int h) public Rectangle(Point p. Executando (invocando) seus métodos Como já foi discutido.public Rectangle(Point p) public Rectangle(int w. corre-se o risco de colocar o objeto em um estado inconsistente. ou nenhum valor. Estes métodos garantem que um objeto nunca entrará em um estado inconsistente. é Pág 50 . Se uma classe possui vários construtores. Se uma classe (como SimplePoint e SimpleRectangle. então. assumir que não há problemas em se inspecionar/modificar tais variáveis. origem. Assim. em situações práticas. int h) public Rectangle() Cada um destes construtores permite se definir valores iniciais para diferentes aspectos do retângulo: a origem. Manipulando ou inspecionando as suas variáveis 2. a linguagem Java automaticamente oferece um construtor sem argumentos. Assim. Portanto. é correto afirmar que todas as classes possuem pelo menos um construtor. suponha que o objeto Rectangle representa um objeto retangular em um programa de desenho e que o usuário moveu este objeto para um outro local. Se um objeto oferece acesso a suas variáveis.2 Utilizando Objetos Pode-se utilizar um objeto de duas maneiras: 1. a largura e a altura. As classes Point e Rectangle permitem livre acesso a suas variáveis. vistas no começo da seção) não definir explicitamente um construtor. Entretanto. Java proporciona um mecanismo de controle onde as classes podem restringir ou permitir o acesso a suas variáveis e métodos (tal mecanismo será descrito com mais detalhe em uma aula posterior).

deve refernciar um objeto. 37). com um ponto (.move(15. height e width (ou simplesmente executar o método area()): area = rect. Observação: depois de executada a expressão acima. atribuindo para a origem um novo ponto. devemos escrever: rect. Executando o método move Referenciando as Variáveis de um Objeto Suponha que você tenha criado um retângulo chamado rect. Por isto. A classe retângulo oferece duas maneiras equivalentes de realizar isto: 1.height * rect. Assim. Por exemplo: height = new Rectangle(). este objeto está sujeito à “coleta de lixo” (descrita em um dos itens a seguir). acrescenta-se o nome da variável à referência do objeto. Pode-se utilizar também qualquer expressão que retorne uma referência para um objeto. Manipulando diretamente a variável origin do objeto 2. Pág 51 .width. De maneira geral. rect. utilizando o método move(). no caso. como descrito na seção .) no meio: objectReference.origin. Para calcular a área de rect.necessário atualizar o ponto de origem do objeto. é possível utilizar o operador = para atribuir um valor a rect. possui o valor default dado pelo construtor). Para mover rect para uma nova localização.origin = new Point(15. deve-se escrever: rect.variable A primeira parte do nome da variável. objectReference. para se referir a uma variável de um objeto. Esta expressão move o retângulo.origin é a variável que contém o ponto de origem de rect. 37). Executando (invocando) os Métodos de um Objeto Para mover rect para uma nova localização. Esta expressão cria um novo objeto retângulo e imediatamente acessa a sua variável height (que. o programa não possui nenhuma referência (variável) para o objeto recém-criado.height. poderíamos usar as outras duas variáveis do objeto. Pode-se utilizar este tipo de variável da mesma maneira que os tipos de variáveis vistos anteriormente.

x e origin.origin = new Point(15. 15 e 37.area() A expressão new Rectangle(100. 50). Java permite que se crie quantos objetos forem necessários (obviamente.Esta expressão invoca o método move() de rect() com dois parâmetros (inteiros). Como mostrado. Se o método não possuir argumentos. pode-se invocar o método area() para calcular a área deste objeto recém-criado. Para aqueles métodos que retornam algum valor. e o programador não precisa se Pág 52 . utiliza-se parênteses vazios: objectReference. Assim. O método move o objeto rect pois atribui novos valores às variáveis origin. destrua-os quando não precisar mais deles. como area().) no meio. define-se os argumentos para o método dentro de parênteses. Além disto. pode-se utilizar a invocação do método em expressões.methodName(). Esta expressão é equivalente àquela descrita no item anterior: rect. 5. Observação: Lembre-se que invocar o método de um objeto equivale a enviar uma mensagem para aquele objeto. você obterá uma resposta distinta se enviar a mesma mensagem para um outro objeto (bob): int areaOfRectangle = bob.area(). Neste caso. o objeto é um retângulo chamado rect. o número de objetos é limitado pelos recursos disponíveis no sistema). Por exemplo.methodName(argumentList). usá-lo para tomar decisões (if-else) ou controlar um laço: int areaOfRectangle = new Rectangle(100. podemos usar: new Rectangle(100. Provavelmente. Como descrito no item anterior. objectReference deve ser uma referência para um objeto (variável ou uma expressão que retorna uma referência de um objeto). explicitamente. A notação utilizada para invocar o método de um objeto é similar a aquela usada para referenciar as suas variáveis: acrescenta-se o nome do método à referência do objeto. 37). Esta técnica de gerência de memória é entediante e bastante suscetível a erros (memory leaks). 50). pode-se atribuir o valor de retorno a uma variável.3 Liberando Objetos não mais Utilizados A maioria das linguagens orientadas a objetos exige que o programador mantenha um controle sobre todos os objetos criados e que. 50) retorna um objeto retângulo. com um ponto (. ou objectReference.y.area().

atribuindo null a variável que o referenciava (origin): protected void finalize() throws Throwable { origin = null.3. Note que o Pág 53 . a sua execução. o coletor roda sincronamente quando o sistema fica sem memória disponível ou quando um programa Java requisita. Referências são armazenadas em variáveis e são descartadas quando estas variáveis saem de escopo (pode-se também remover uma referência de um objeto atribuindo à variável o valor null). explicitamente.3. objetos não marcados (ou seja.1 Coletor de Lixo (Garbage Coletor) A plataforma Java possui um coletor de lixo que periodicamente libera a memória utilizada pelos objetos que não são mais necessários. o coletor dá ao objeto uma oportunidade de se “limpar” por meio da chamado do método finalize do objeto. Durante a finalização. O coletor de lixo é uma thread que executa com baixa prioridade de forma síncrona ou assíncrona. Por exemplo. Este processo é denominado de coleta de lixo (garbage collection).preocupar em destruí-los. Assim que uma outra thread torna-se ativa. Este processo é chamado de finalização. o método finalize da classe Rectangle libera o objeto Point.2 Finalização Antes que um objeto seja “coletado”. não mais referenciados) são considerados como lixo e então são “coletados” (liberando a memória alocada para aqueles objetos). um objeto pode desejar liberar outros recursos do sistema como arquivos e sockets ou eliminar referências para outros objetos de tal forma que estes tornem-se também candidatos à coleta de lixo. O coletor de Java é do tipo mark-sweep: ele inspeciona as áreas de memória dinâmica em busca de objetos e marca aqueles que estão sendo referenciados. o coletor de lixo termina a sua execução. 5. O coletor de lixo executa assincronamente. Depois que todos os caminhos para os objetos são investigados. Por exemplo. Um objeto está sujeito a coleta de lixo quando não existem mais referências para ele. O ambiente de execução Java (JVM) remove os objetos quando percebe que eles não são mais utilizados. quando o sistema está ocioso. } O método finalize é um membro da classe Object. 5.finalize(). super. em sistema como o Windows 95/NT. A classe Object fica no topo da hierarquia de classes de Java e é “pai” de todo mundo. dependendo da situação e do sistema onde Java está rodando. Uma classe deve redefinir o método finalize para realizar as finalizações necessárias para os objetos daquele tipo.

Stack impõe as restrições de uma estrutura LIFO ao objeto Vector. A figura a seguir lista a classe e identifica a estrutura do código.finalize para dar a oportunidade a classe pai de realizar uma “limpeza” final (a utilização do método finalize será discutida com maior detalhe em uma próxima aula). Vector. 5. Esta implementação de uma pilha utiliza um outro objeto. pode-se apenas remover (adicionar) elementos do (ao) topo da pilha. Para isto. Pág 54 . ou seja. para armazenar os seus elementos. A classe Stack usa então um objeto da classe Vector para armazenar seus elementos. será apresentado um pequeno exemplo que implementa uma pilha (last-in-first-out. Entretanto. vamos analisar cada uma das estruturas da figura acima. A classe Vector é um vetor de objetos que tem uma característica muito interessante: é capaz de alocar dinamicamente espaço para novos objetos à medida que seja necessário.método finalize de Rectangle executa o método super.4 Criando Classes Esta seção mostra como escrever classes a partir das quais objetos são criados. A seguir. LIFO).

A lista a seguir apresenta algumas explicações básicas sobre cada um destes componentes da declaração de uma classe. utiliza-se a palavra-chave implements seguida de uma lista. dos nomes das interfaces. O conceito de herança em Java será abordado com mais detalhes em uma próxima aula.4.1 Declaração da Classe O lado esquerdo da figura a seguir mostra os componentes que podem fazer parte da declaração de uma classe. •abstract: serve para declarar que a classe não pode ser instanciada (criada). delimitada por vírgulas. Os componentes indispensáveis em uma declaração de classe são: a palavra-chave class e o nome da classe. o conceito de interfaces em Java será apresentado com maior profundidade em uma próxima aula. Em uma próxima aula. •final: serve para declarar que a classe não pode ser “derivada” (ou seja. serão apresentadas razões para utilizar classes do tipo “finais”. Utilizando a palavra-chave public. em Java. uma classe pode ser utilizada apenas por classes que fazem parte do mesmo package (package é um conceito equivalente a uma bibliotecas de objetos. Também. A discussão mais detalhada de tais elementos será feita ao longo do curso. o programador indica que tal classe pode ser utilizada por qualquer outra. independente do pacote a que ela pertença. •class NameofClass: a palavra-chave class indica ao compilador que o código a seguir é uma declaração de uma classe cujo nome é NameofClass. posteriormente. •extends Super: o elemento extends identifica que a classe Super é a superclasse da classe declarada. serão apresentadas situações onde é vantajoso se utilizar uma classe deste tipo.5. ou packages). na ordem que podem (ou devem) aparecer na declaração. O lado direito do diagrama descreve o propósito do componente. •implements Interfaces: para declarar que uma classe implementa uma ou mais interfaces. •public: por default. Pág 55 . Novamente. O texto em itálico identifica o nome de uma classe (ou interface). Todos os demais elementos são opcionais. pode-se agrupar classes em pacotes. ter subclasses).

4. vemos que a declaração da classe é bastante simples e indica que tal classe é pública e que seu nome é Stack. um construtor que atribui um tamanho inicial para a pilha: public Stack(int initialSize) { items = new Vector(initialSize). não-pública. } Como já visto. Rigorosamente falando.4. No exemplo da classe pilha. da classe Vector). declarações das variáveis que guardam o estado da classe e de seus objetos. quando necessário. Baseando-se no número e no tipo de argumentos passados para o construtor é que o compilador consegue determinar qual construtor utilizar. Stack poderia definir. Também são definidos um construtor. Java suporta a sobrecarga de construtores de tal forma que uma classe pode possuir vários construtores (obviamente. Construtores sempre possuem o mesmo nome da classe. e quatro métodos: push. a classe Stack define um único construtor: public Stack() { items = new Vector(10). 5. pop.3 Construtores da Classe Todas as classes Java possuem construtores que são utilizados para inicializar um novo objeto daquele tipo. Observação: variáveis e métodos são chamados de membros da classe. de mesmo nome). por exemplo. A classe Stack define. o default. 5. um método finalize que realiza a “limpeza” dos objetos. os construtores não são classificados nem como métodos ou variáveis.2 Corpo da Classe O corpo da classe segue a declaração e é delimitado por chaves: { e }. e finalize. Lembre-se que finalize é um método especial que proporciona a “limpeza” dos objetos da classe Stack. métodos que implementam o comportamento da classe e de seus objetos e. } Note que os construtores de uma mesma classe devem possuir uma lista de argumentos diferentes. No exemplo. no código Pág 56 . não-abstrata que não implementa nenhuma interface. uma variável membro que armazena os itens da pilha (items. o compilador Java assume algumas “declarações” default: uma subclasse de Object nãofinal.Observação: se o programador não declarar explicitamente os componentes opcionais. Por exemplo. isEmpty. em seu corpo. O corpo de uma classe contém todo o código que proporciona o ciclo de vida dos objetos instanciados a partir da classe: construtores para incializar novos objetos.

framesPerSecond = fps. o ambiente de execução do Java (JVM) automaticamente irá proporcionar um construtor default. Pág 57 . . ou seja.images = new Image[numImages].. Entretanto. i <= numImages. o número de imagens (numImages) e depois carrega as imagens. é uma função “vazia”). int num) { super("AnimationThread"). Note que se nenhum construtor for definido explicitamente para a classe. AnimationThread(int fps. int numImages. no código abaixo. o compilador sabe que deve usar o construtor que tem como argumento um único valor (do tipo inteiro): new Stack(10). for (int i = 0. } } . o compilador escolhe o construtor default: new Stack(). i++) { . como a velocidade de exibição das imagens (framesPerSecond).abaixo. class AnimationThread extends Thread { int framesPerSecond.. derivada da classe Thread. Image[] images. this. O construtor da classe a seguir.numImages = num... } Observe que o corpo de um construtor é como o corpo de um método. contém declarações de variáveis locais. laços e outras expressões. // Load all the images.. Este construtor “automático” oferecido pelo sistema não faz nada (ou seja. this.. uma linha no construtor de AnimationThread apresenta um código que não será visto em métodos comuns: super("AnimationThread"). Analogamente. this. atribui alguns valores default.

protected. ou seja. é interessante (e até necessário.4. A classe em questão pode possuir métodos de classe (públicos). A declaração de uma variável pode possuir os seguintes componentes: •accessLevel: permite controlar quais outras classes têm acesso à variável membro. e estes métodos podem construir um objeto da classe e retornar a sua referência. Thread. package. A variável declarada tem nome items e é do tipo Vector. •static: define que a variável é uma variável de classe em vez de uma variável de instância. Pode-se definir quatro níveis de acesso: public. Pág 58 . Além disso. •protected: apenas subclasses da classe em questão podem criar instâncias dela. especificam quais objetos podem criar instâncias da classe: •private: nenhuma outra classe pode instanciar a classe. o construtor da superclasse deve ser a primeira expressão dentro do construtor da subclasse. •public: qualquer classe pode instanciar a classe declarada. Na maioria das vezes. apenas o código dentro da classe Stack pode acessá-la. •package: apenas classes que fazem parte do mesmo pacote podem construir um objeto da classe em questão. a palavra-chave private identifica a variável itens como uma variável privada.4. por exemplo) pois aparece no corpo da classe mas fora de qualquer método ou construtor. e private.7).Esta expressão invoca o construtor da superclasse de AnimationThread. static também pode ser utilizado na declaração de métodos (seção 5. chamados de fábricas. 5. Observação: Se presente. Estes níveis são detalhados na seção 5.6. que devem ser associados aos construtores. Esta declaração refere-se a uma variável membro e não a um outro tipo de variável (local. Ou seja. Este construtor da classe Thread tem como parâmetro uma String que define o nome da thread. em certos casos) invocar o construtor da superclasse para aproveitar o código de inicialização e/ou para que a classe funcione corretamente.4 Variáveis A classe Stack utiliza a seguinte linha de código para definir sua única variável membro: private Vector items. Os componentes listados abaixo.4.

uma variável membro e um método podem possuir o mesmo nome. objetos ou interfaces). ou boolean. passado como argumento da função.023x1023. Por convenção. } } 5. Este método insere um objeto. A seguinte declaração define uma constante chamada AVOGADRO. por exemplo) ou tipos de referência (vetores. •type: pode-se utilizar.5 Métodos A figura abaixo mostra o código do método push da classe Stack. no topo da pilha e retorna o próprio objeto. tipos primitivos (int. cujo valor é 6. Além disto.4.•final: indica que o valor da variável não pode ser alterado. •name: o nome da variável pode ser qualquer identificador Java válido (por convenção. começando com uma letra minúscula). // um método que utiliza o mesmo nome de uma variável membro public Vector items() { . final double AVOGADRO = 6.023e23. Pág 59 . para definir uma variável membro. Ocorrerá um erro em tempo de compilação caso seu programa tente alterar o valor de alguma variável final. o nome de valores constantes é composto de letras maiúsculas.. float. •volatile: é utilizada para evitar que o compilador realize algumas otimizações na variável. mas uma subclasse pode utilizar o mesmo nome de uma variável declarada pela superclasse. o código abaixo está correto: public class Stack { private Vector items. Não se pode declarar mais de uma variável membro com o mesmo nome dentro de uma classe.. •transient: esta palavra chave é utilizada no caso de serialização de objetos para identificar aquelas variáveis que não precisam ser serializadas (serialização vai ser abordada no fim do curso). Por exemplo.

package.4. nome e argumentos. tipo de retorno.Como uma classe. Pág 60 .7). Os únicos componentes indispensáveis em qualquer declaração são: o nome do método. •synchronized: threads concorrentes muitas vezes invocam métodos que acessam os mesmos dados. abordaremos a necessidade de se escrever métodos abstratos e como estes métodos afetam as subclasses. O corpo do método é onde a “a ação ocorre”. A declaração de um método define todos os seus atributos como: nível de acesso. A figura abaixo mostra todos os elementos que podem estar presentes na declaração: •accesLevel: como as variáveis. Estes métodos podem ser declarados como syncronized para garantir que as threads acessem as informações compartilhadas de forma segura. e private. pode-se controlar quais classes podem acessar um método.6 descreve cada um destes níveis de acesso. um método possui duas partes principais: declaração e corpo. e um par de parênteses ( ). evitando inconsistências. •abstract: um método abstrato não possui implementação e deve ser membro de uma classe abstrata. Na próxima aula. utilizando um dos quatro níveis de acesso: public.4. a maioria deles pode ser declarada implicitamente. abordaremos a necessidade de se escrever métodos finais e como estes métodos afetam as subclasses •native: métodos implementados em linguagens diferentes de Java são chamados métodos nativos e são declarados utilizando a palavra-chave native. Um dos tópicos das próximas aulas está relacionado com a utilização de métodos nativos. Ele contém todas as instruções Java que implementam a função. •final: um método final não pode ser redefinido por subclasses. Declaração do Método Uma declaração de método possui vários componentes. A seção 5. Na próxima aula. •static: define que o método é um método de classe em vez de um método de instância (seção 5. protected. seu tipo de retorno.

Stack declara o método pop que retorna uma referência para o tipo Object: public synchronized Object pop() { int len = items. utiliza-se o operador return. por sua vez. a declaração deve indicar o tipo desta exceção. Se o método não retorna nenhum valor.size() == 0) return true. Todo método que não foi declarado como void deve conter pelo menos um return.1). Object obj = null.Number que.removeElementAt(len . •methodName: o nome do método pode ser qualquer identificador Java válido.lang. para retornar um valor. Por exemplo. Métodos também podem retornar tipos de referência. Retornando um Valor de um Método Dentro do corpo do método.elementAt(len . Suponha que. exista uma hierarquia de classes onde ImaginaryNumber é uma subclasse de java. que retorna um boolean: public boolean isEmpty() { if (items.1). else return false. obj = items.•returnType: em Java. a classe do objeto retornado deve ser uma subclasse (ou a própria classe) do tipo de retorno declarado. } Um erro de compilação ocorrerá caso tente-se escrever um método onde o valor de retorno não é compatível com o tipo definido na declaração da função. items. if (len == 0) throw new EmptyStackException(). Por exemplo. é uma subclasse de Object: Pág 61 . •( paramlist ): é por meio dos parâmetros de um método que passamos as informações para a função. return obj.size(). a classe Stack declara o método isEmpty. é necessário que um método declare o tipo de dado do valor a ser retornado. deve-se usar a palavra-chave void como tipo de retorno. •[ throws exceptions ]: caso o método possa “levantar” alguma exceção (seção ). } Quando um método retorna um objeto.

Agora. podemos utilizar o mesmo nome para todos estes métodos desde que possuam parâmetros de tipos diferentes. drawInteger(). class DataRenderer { void draw(String s) { . double futureValue.. um Object não é necessariamente um número (pode ser uma String. } void draw(float f) { .. o método a seguir calcula os pagamentos mensais de um empréstimo. partial1. } Este método pode retornar um ImaginaryNumber mas não um Object. etc. Nome do Método Java suporta sobrecarga de métodos de tal forma que vários métodos podem compartilhar o mesmo nome... I = rate / 100... denominator. Pág 62 . int numPeriods) { double I. Por exemplo. baseado no valor do empréstimo: double computePayment(double loanAmt.. números. Em outras linguagens isto poderia ser feito definindo nomes diferentes para cada método drawString(). por ser uma subclasse Number. Em Java. } } Na verdade. é necessário escrever um método que saiba imprimir cada tipo de dado.. são declarados também o número e o tipo dos argumentos necessários. entretanto. } void draw(int i) { . “é” um número. . Passando Informação para um Método Quando se declara um método. Isto porque ImaginaryNumber. answer. Assim.. métodos sobrecarregados são diferenciados pelo número e tipo dos seus argumentos..0. double rate. suponha que um método tenha como tipo de retorno um Number: public Number returnANumber() { . Por exemplo.) em uma área de desenho. por exemplo). suponha que você esteja escrevendo uma classe que imprime vários tipos de dados (strings.

denominator = (1 . int y. deve-se referenciála utilizando a palavra-chave this (este objeto): class Circle { int x. onde cada declaração é um par nome/tipo. Como foi dito.) e tipos de referências (objetos e vetores). Argumentos que ocultam variáveis-membros são muitas vezes utilizados em construtores para inicializar uma classe.x = x. A seguir. o valor futuro (se a dívida for inteiramente paga -> valor futuro igual a 0) e o número de períodos. no corpo do método. Portanto.. radius. dizemos que o argumento ocultou (hide) a variável-membro. y. public Circle(int x. os nomes dos argumentos ocultam as variáveis-membro. Importante também salientar que o argumento de um método pode ter o mesmo nome que uma das variáveis-membro da classe do objeto. números reais. public Circle(int x.partial1 = Math.0 . y e radius. } Este método possui quatro argumentos: o valor do empréstimo. int y.numPeriods)). Observe que o construtor da classe aceita 3 argumentos que têm os mesmos nomes das variáveis-membros.. } } A classe Circle tem 3 variáveis-membro: x.pow((1 + I). (0. Pág 63 . Por exemplo: class Circle { int x. Isto inclui tipos primitivos (inteiros. Em Java.. y ou radius dentro do corpo do construtor refere-se aos seus argumentos e não às variáveismembro do objeto. a utilização de x. int radius) { this. não se pode passar métodos como argumentos de outros métodos. answer = ((-1 * loanAmt) / denominator) . int radius) { . invocar alguma das funções deste objeto.partial1) / I. por exemplo). Neste caso. return answer. radius. } Observação: Diferente de outras linguagens (C. O que se pode fazer é passar um objeto para um método e. y. em Java. etc. temos um exemplo de um construtor que aceita um vetor de objetos (da classe Point) como argumento: Polygon polygonFrom(Point[] listOfPoints) { .((futureValue * partial1) / denominator). pode-se passar como argumento para um método qualquer tipo de dado válido.. Para acessar uma variável-membro do construtor. O conjunto de argumentos de qualquer método é uma lista de declarações de variáveis. a taxa de juros. separadas por vírgulas.

radius = radius. void getRGBColor(int red. os argumentos entram no escopo (ou seja são alocados) e são inicializados com os valores passados para o método: class Pen { int redValue. significa que o método não pode alterar a referência armazenada pela variável. A intenção do código... green.this.out. Qualquer alteração realizada nestas cópias locais não se reflete nas variáveis originais (r. b).. ao executar getRGBColor. os argumentos são passados por valor. Então podemos visualizar a chamada a getRGBColor como: getRGBColor(-1. pen. Quando o fluxo de controle entra no método getRGBColor.. green = " + g + ". o método abaixo não funciona como esperado: class Pen { Pág 64 . } } Observação: Os nomes dos argumentos de um método não podem ser iguais ao nome de alguma variável local dentro do corpo do método. Quando o argumento é do tipo de referência. this. era receber os valores de volta (vermelho. os valores das variáveis (1) é que são passados para o método e não as suas referências. b = -1. Considere o seguinte exemplo. Assim. g e b). . g e b para utilizar dentro do método..getRGBColor(r. int r = -1. -1). e b possuem valor –1. que tenta recuperar a cor atual de um objeto (pen): . passagem por valor significa que o método não pode alterar o valor da variável passada como argumento. System. o método recebe o valor (uma cópia) da variável passada como argumento. No momento que o método getRGBColor é executado. o método possui a sua própria cópia dos valores de r. Observação Importante: Passagem por Valor Em Java. Ou seja. greenValue. g e b. blue = " + b).. Entretanto. } } Ou seja. blueValue.println("red = " + r + ". g = -1. int blue) { // red. and blue have been created // and their values are -1 . int green. g. verde e azul) nas variáveis r. as variáveis r. Quando o argumento é do tipo primitivo. -1.y = y. g.

porém o seu valor é. as atribuições realizadas a estes argumentos dentro do método não tem nenhum efeito. . blue = blueValue. Ou seja. b).getRGBColor(r.out. objetos e vetores também são passados por valor. System.. Aproveitando este fato. } Agora. int green. .println("red = " + r + ". na verdade. green. como argumentos. int blue) { red = redValue. A saída para esta situação é utilizar. Entretanto. green e blue) não existem mais.int redValue. class Pen { Pág 65 . g e b ainda continuam iguais a –1. muitas vezes. uma referência para um objeto. Observe que.. green = " + g + ". Primeiramente. } } Quando o fluxo de controle voltar para a expressão println. a própria função getRGBColor citada acima). vanos rescrever getRGBColor para que o método aceite um objeto RGBColor como argumento.. g. // this method does not work as intended void getRGBColor(int red. greenValue. int r = -1. Então. A passagem por valor garante ao programador uma certa segurança: os métodos não podem modificar variáveis que estão fora de seu escopo. blue.. os tipos de referência. Portanto. blue = " + b). podemos rescrever getRGBColor para que faça aquilo que é esperado.. como um método pode retornar mais de um valor ou modificar variáveis fora de seu escopo? (observação: se for necessário retornar somente um valor podemos utilizar return). b = -1. vamos criar um novo tipo de objeto RGBColor que guarda os valores de vermelho. r. blueValue. verde e azul: class RGBColor { public int red.. g = -1. o argumento do método vai estar referenciando o mesmo objeto que a variável original. no código a seguir os argumentos de getRGBColor (red. . é desejável que um método seja capaz de modificar um ou mais argumentos (por exemplo. Note que o método agora atribui os valores das cores para as variáveis membros do objeto RGBColor. green = greenValue. pen.

greenValue. } } Desta forma.saturation = saturation. saturation.green = greenValue. poderíamos escrever: . blueValue. green = " + penColor. RGBColor penColor = new RGBColor(). pen. pode-se utilizar a palavra-chave this para referir-se explicitamente a membros do objeto atual.blue). int brightness) { this.green + ".red + ". System. this..brightness = brightness.out. .println("red = " + penColor. this. Pág 66 . aColor. aColor. As modificações feitas no objeto RGBColor dentro do método getRGBColor afetam o objeto original pois a variável original (penColor) e o argumento do método (aColor) referem-se ao mesmo objeto.. brightness. O objeto atual é aquele que teve o seu método invocado. int saturation. Exemplo 1: class HSBColor { int hue.getRGBColor(penColor).. void getRGBColor(RGBColor aColor) { aColor. é utilizada com a intenção de tornar o código mais claro. blue = " + penColor. void aMethod() { aVariable = true.hue = hue. Observação: no corpo de um método.int redValue.red = redValue.. } Pode-se também utilizar this para chamar um dos métodos do objeto atual. isto só é necessário caso exista alguma ambigüidade relacionada com o nome do método. Novamente. Exemplo 2: class ASillyClass { boolean aVariable. em geral. HSBColor (int hue.blue = blueValue. Também pode-se utilizar a palavra-chave super para referir-se a membros da superclasse que o objeto atual redefiniu ou sobrecarregou.

protegido (protected). A tabela a seguir apresenta os níveis de acesso permitidos: nível de acesso private protected public package classe X X X X X* X subclasse pacote (package) X X X mundo X Pág 67 . } } Primeiramente. super.6 Controle de Acesso a Membros da Classe Como visto na seção 2. void aMethod() { aVariable = false. que possuem diferentes valores: false true 5. Então o método aMethod imprime as duas versões de aVariable.} } class ASillierClass extends ASillyClass { boolean aVariable.aVariable). Tal característica é denominada de encapsulação. System. aMethod() atribui a variável aVariable (que oculta a variável declarada na superclasse) o valor false. um dos benefícios do paradigma de orientação a objetos é a possibilidade de se “proteger” variáveis e métodos do acesso por parte de outros objetos. público (public) e o nível default.aMethod(). pacote (package). Depois. Este controle é definido na própria declaração da variável (ou método).println(aVariable).aMethod(). System. Em Java. pode-se utilizar especificadores de acesso (access especifiers) para proteger tanto variáveis quanto os métodos de uma classe.4.println(super. aMethod() invoca o método da superclasse: super.out.out. A linguagem Java suporta quatro níveis de acesso distintos: privado (private). Isto faz com que a versão oculta de aVariable (aquela que foi declarada na superclasse ASillyClass) receba o valor true.

privateMethod(). Um membro privado é acessível apenas pela própria classe que o definiu.A primeira coluna indica se a própria classe possui acesso ao membro (variável ou método). private void privateMethod() { System. Por exemplo: class Beta { void accessMethod() { Alpha a = new Alpha(). a. a classe sempre possui acesso aos seus próprios membros. a ser descrita ainda nesta seção. possuem acesso ao membros. Vamos abordar com maior detalhe cada um destes níveis: Privado (Private) Este é o nível de acesso mais restritivo. que estão no mesmo pacote da classe em questão. deve-se declarar como privadas aquelas variáveis/métodos que só devem ser utilizados pela classe Para declarar um membro privado. A segunda coluna indica se as subclasses (independente do pacote a qual pertencem) possuem acesso a variável/método. a. // ilegal } } A classe Beta não pode acessar a variável iamprivate ou executar o método privateMethod de um objeto da classe Alpha e o compilador Java geraria uma mensagem de erro do tipo: Beta. *: Este nível de acesso possui uma pequena particularidade. Ou seja. A classe a seguir contém uma variável e um método privados.println("privateMethod"). utiliza-se a palavra-chave private em sua declaração. } } Apenas objetos da classe Alpha podem inspecionar ou modificar a variável iamprivate e podem executar o método privateMethod. A quarta coluna indica se todas as classes possuem acesso as variáveis/métodos. A terceira coluna indica se classes.iamprivate = 10.iamprivate = 10. class Alpha { private int iamprivate. // ilegal ^ Pág 68 . Como pode se observar.java:9: Variable iamprivate in class Alpha not accessible from class Beta. // ilegal a.out.

Primeiramente. Um objeto possui acesso a membros privados de outros objetos do mesmo tipo. vamos analisar como o protected afeta classes que estão no mesmo pacote. Assim.println("protectedMethod"). protected void protectedMethod() { System. Isto é ilustrado no exemplo a seguir: class Alpha { private int iamprivate. suas subclasses e todas as classes no mesmo pacote (package) acessem seus membros. } } Isto é perfeitamente válido.Beta. a classe Gamma pode acessar os membros protegidos de Alpha: package Greek.privateMethod(). else return false. Isto ocorre pois as restrições de acesso se aplicam às classes (todas as instância de uma classe) e não aos objetos (uma instância da classe). } } Suponha que a classe Gamma também foi declarada como membro do pacote Greek (e não é uma subclasse de Alpha). // ilegal 2 errors Observação importante: programadores novatos geralmente perguntam se um objeto Alpha pode acessar membros privados de outro objeto Alpha. utiliza-se a palavra-chave protected. class Alpha { protected int iamprotected.iamprivate) return true. Protegido (protected) Este nível de acesso permite que a classe.out. boolean isEqualTo(Alpha anotherAlpha) { if (this.iamprivate == anotherAlpha. Considere esta versão de Alpha que é declarada dentro de um pacote chamado Greek e possui uma variável e um método protegidos: package Greek.java:12: No method matching privateMethod() found in class Alpha. Para declarar um membro protegido. Pág 69 . a.

protectedMethod(). class Delta extends Alpha { void accessMethod(Alpha a. a. Considere a classe Delta que é uma subclasse de Alpha mas pertence a um outro pacote.out.class Gamma { void accessMethod() { Alpha a = new Alpha(). em qualquer pacote. // válido } } Agora. Público (public) O nível de acesso mais simples é o público. Latin. Para declarar um membro público. package Latin.protectedMethod().*. Qualquer classe. Delta d) { a. // válido a. // ilegal d. Observe o seguinte exemplo: import Greek.iamprotected = 10. // válido } } Agora. mas apenas em objetos do tipo Delta ou suas subclasses. vamos investigar como protected afeta as subclasses de Alpha.println("publicMethod"). utiliza-se a palavra-chave public: package Greek. public class Alpha { public int iampublic. A classe Delta pode acessar iamprotected e protectedMethod. se a subclasse pertencer ao mesmo pacote da classe com o membro protegido. possui acesso aos membros públicos de uma classe. // ilegal d. A classe Delta não pode acessar os membros protegidos de objetos do tipo Alpha.iamprotected = 10. então a subclasse possui acesso ao membro. // válido a. } } Pág 70 . public void publicMethod() { System.iamprotected = 10.protectedMethod().

// válido } } Pág 71 .Rescrevendo a classe Beta. // válido } } Observe que a classe Beta continua com acesso aos membros públicos de Alpha. class Beta { void accessMethod() { Alpha a = new Alpha(). Pacote (package) Este nível de acesso é o default.*. a.publicMethod().packageMethod(). // válido a. o código abaixo é válido: package Greek. } } Todas as classes declaradas no mesmo pacote de Alpha possuem acesso a iampackage e packageMethod. Este nível permite que classes do mesmo pacote acessem os membros da classe. class Beta { void accessMethod() { Alpha a = new Alpha().iampublic = 10. class Alpha { int iampackage. quando não se atribui explicitamente um nível de acesso para uma variável/método de uma classe. Por exemplo: package Greek. a. package Roman.iampackage = 10. de tal forma que esta não possua nenhum relacionamento (superclasse/subclasse) com Alpha: import Greek. ou seja.println("packageMethod"). void packageMethod() { System. // válido a. Assim.out.

O ambiente de execução aloca memória para variáveis de classe apenas uma única vez. Além disto. // válido myClass.5.mystaticvariable = 1. } } Pág 72 . Por default.. } public void setX(int newX) { x = newX.7 Membros de Instância X Membros de Classe Quando se declara uma variável como aFloat em myClass: class MyClass { float aFloat. Observação Importante: métodos de instância podem acessar variáveis de instância e de classe.4. } tem-se uma variável de instância..mystaticvariable = 1. o ambiente de execução cria uma cópia de cada variável de instância da classe para o novo objeto. x e setX: class AnIntegerNamedX { int x. Em contrapartida. métodos de classe somente podem acessar as variáveis de classe declaradas. . Toda vez que se cria uma instância de uma classe. a classe abaixo declara uma variável de instância (um inteiro chamado x) e dois métodos de instância. Existem também variáveis de classe (que são declaradas utilizando a palavra-chave static). Todas as instâncias (objetos) compartilham a mesma cópia das variáveis de classe. um membro declarado em uma classe é uma variável/método de instância. independentemente do número de instâncias criadas para aquela classe. O sistema aloca a memória na primeira vez que encontra uma referência no código a aquela classe. Pode-se acessar uma variável de classe por meio de um objeto ou da própria classe. public int x() { return x. // válido O mesmo raciocínio é válido para os métodos: classes podem possuir métodos de instância e de classe. myObject. Exemplo: myClass myObject. Por exemplo. para executar um método de classe não é necessário criar um objeto da classe.

atribui valores a x e mostra o resultado. anotherX.println("anotherX.Observação: os métodos de instância atuam sobre as variáveis de instância do objeto atual. Considere o seguinte exemplo: AnIntegerNamedX myX = new AnIntegerNamedX(). o mesmo trecho de código. a variável x declarada abaixo é uma variável de classe: class AnIntegerNamedX { static int x.x = 2 anotherX. a saída deste trecho de código é: myX.x = 2 Para especificar que uma variável membro é uma variável de classe. utiliza-se também a palavra-chave static: class AnIntegerNamedX { private int x. Analogamente.setX(1).x = 2 A saída é diferente pois agora x é uma variável de classe e só existe uma cópia da variável. System. AnIntegerNamedX anotherX = new AnIntegerNamedX().x()).x = 1 anotherX.println("myX. que é compartilhada por todos os objetos da classe AnIntegerNamedX. myX. Note que o código acima está manipulando duas cópias diferentes de x: uma que pertence ao objeto myX e outra que pertence ao objeto anotherX. que cria dois objetos da classe AnIntegerNamedX.x = 2. terá a seguinte saída: myX. System. Por exemplo. } Pág 73 .out. } public void setX(int newX) { x = newX. } } Neste caso. mostrado anteriormente. utiliza-se a palavrachave static.x = " + anotherX. Assim. para especificar que um método é um método de classe.x()).out. public int x() { return x.x = " + myX. static public int x() { return x.

println("AnIntegerNamedX.setX(1). Após criar uma exceção. devemos tornar x uma variável de classe: class AnIntegerNamedX { static private int x.8 Tratamento de Exceções Exceção é um tipo especial de objeto que é criado quando algo sai errado em um programa.x()). System.java:4: Can't make a static reference to nonstatic variable x in class AnIntegerNamedX. podemos acessar membros de classe por meio do nome da própria classe: AnIntegerNamedX. ocorrerão erros de compilação: AnIntegerNamedX. } static public void setX(int newX) { x = newX. 5.4. static public int x() { return x. ^ AnIntegerNamedX.java:7: Can't make a static reference to nonstatic variable x in class AnIntegerNamedX. Pode-se acessar a variável x a partir da classe AnIntegerNamedX (isto não pode ser feito com variáveis de instância).static public void setX(int newX) { x = newX. Para solucionar este problema. } } Quando se tenta compilar o código acima. deve-se escrever um código de tratamento de exceção: Pág 74 .out. } } Como já foi dito. Para isto. return x. x). o ambiente de execução envia este objeto ao seu programa. Note que não é mais necessário criar os objetos myX e anotherX.x = " + AnIntegerNamedX. ^ 2 errors Isto ocorre pois métodos de classe não podem acessar variáveis de instância (no caso. É responsabilidade do seu programa capturar (catch) esta exceção. numa ação denominada “levantar uma exceção” (throwing an exception). x = newX.

A linguagem Java define várias exceções (objetos) que podem ser geradas pelos métodos das classes de sua API. o restante do código é ignorado e o fluxo de controle do programa “salta” para o bloco catch. o código do bloco catch é ignorado. } Para capturar uma exceção. Pode-se “passar para a frente” a exceção. se nenhuma exceção for gerada. Tal exceção não será tratada por GetURL e sim enviada para o método que invocou GetURL.println(“Exceção !!!”). } catch (Excecao e) { System. Todo o código que pode levantar uma exceção é colocado em um bloco try.outroMetodo(). Por outro lado. por sua vez. a. utiliza-se as cláusulas try e catch. da exceção por meio deste argumento. O parâmetro de catch é o tipo de exceção a ser capturada (tal como o argumento de um método).metodoQuePodeGerarUmaExcecao(). Estas exceções devem ser sempre tratadas pelo código do seu programa.out. Para um mesmo bloco try podem existir mais de um bloco catch (cada um capturando um determinado tipo de exceção). caso contrário ocorrerá um erro de compilação. Pode-se acessar os métodos. se existirem. A documentação on-line da API da linguagem Java indica quais métodos podem levantar exceções e quais são os tipos destas exceções. Observação: não é necessário realizar o tratamento de exceção no mesmo método onde ela foi levantada. Caso ocorra uma exceção em algum ponto do bloco. utilizando-se a palavra-chave throws: protected void GetURL() throws MalformedURLException No exemplo acima.try { a. pode realizar o tratamento de exceção (via try e catch) ou “repassá-la” utilizando throws. dentro do método GetURL pode ser levantada uma exceção (MalformedURLException). Este método. A tabela abaixo lista alguma das exceções mais comuns em Java: Exceção ArithmeticException ArrayIndexOutOfBounds Exception ArrayStoreException Descrição Caused by math errors such as division by zero Caused by bad array indexes Caused when a program tries to store the wrong type of data in an array Pág 75 .

2. considere o código abaixo: class OutraClasse { public float x. } public void UmaClasse(int x) { this.5 Exercícios 1.x = x.FileNotFoundException IOException NullPointerException NumberFormatException OutOfMemoryException SecurityException StackOverflowException StringIndexOutOfBounds Exception Caused by an attempt to access a nonexistent file Caused by general I/O failures. } O código acima é válido? É possível criar classes sem construtores? Como Java trata esta questão? Pág 76 . } } O código acima é válido? Justique. Considere o seguinte trecho de código: class UmaClasse { private int x. public void UmaClasse(int a) { x = a. 5. Agora. such as inability to read from a file Caused by referencing a null object Caused when a conversion between strings and numbers fails Caused when there's not enough memory to allocate a new object Caused when an applet tries to perform an action not allowed by the browser's security setting Caused when the system runs out of stack space Caused when a program attempts to access a nonexistent characterposition in a string Observação: pode-se tratar todos os tipos de exceção utilizando um único bloco catch utilizando catch (Exception e) pois Exception é a superclasse de todos os objetos de exceção.

Qual a função da instrução super(). Justifique esta afirmativa com exemplos..3. super.3. // um método que utiliza o mesmo nome de uma variável membro public int x() { .println(“Fim de A”). Como visto na seção 5. 5. Como você faria para liberar a memória alocada para os objetos referenciados pelo vetor de X? Dica: pensar em uma maneira de “forçar” a coleta de lixo.finalize()? Justifique. } } Quando um objeto da classe B for liberado. qual será a saída do programa? E se tirarmos a linha super.4). este objeto X é utilizado para outros fins dentro do seu programa (ou seja. Como se declara constantes em Java? Dê um exemplo. Faça um programa que instancie e utilize um objeto da classe Stack (seção 5. o compilador não tem como saber que os objetos referenciados pelo vetor de X não são mais utilizados). } } Pág 77 . 10. Apesar do ambiente Java realizar a liberação automática da memória alocada aos objetos. Insira e retire alguns objetos desta pilha. } } class B extends A { protected void finalize throws Throwable { System. Seria interessante permitir que outros objetos acessem diretamente suas variáveis (vértices do triângulo)? Por que? Como você implementaria. o ambiente de execução Java (JVM) remove os objetos quando percebe que eles não são mais utilizados. 7. colocada no início do construtor de uma classe? 9.println(“Fim de B”). Este processo é denominado de coleta de lixo (garbage collection). Suponha que você deva criar uma classe que represente um triângulo. Considere o código abaixo: class A { protected void finalize throws Throwable{ System. Note que você pode inserir qualquer tipo de objeto nesta pilha (inclusive colocar objetos de tipos diferentes na mesma pilha). em Java.out. O código abaixo é válido? public class OutraClasse { private int x. tal classe? 4.out.. 6. Porém. em certas situações é importante a existência do método finalize.finalize(). Por que? 8. Suponha que no seu programa exista um objeto X que possui um vetor (variável membro) com milhares de referências a objetos que você sabe que não serão mais utilizados.

} 12.modificaX(1). MaisUmaClasse objeto1 = new MaisUmaClasse().atribui(1.x = x. Qual será a saída do trecho de código abaixo? Justifique class Ponto { int x.} } Qual será a saída do seguinte trecho de código? Justifique. } public B metodo2() { return objetoA. O código abaixo é válido? Justifique. A objetoA = new A().. Suponha que a classe B seja uma subclasse de A. Pág 78 . System. 14. 13. } } .11.x = x.. int y) { System. . p.println(“x = “ + this. y.println(“x = “ + this. public A metodo1() { return objetoB.x + “ x = “ + x). MaisUmaClasse objeto2 = new MaisUmaClasse(). public Ponto() { x=0.. Ponto p = new Ponto(). } public static void modificaY (int y) { this.x + “ x = “ + x). y=0. B objetoB = new B().out. this. objeto1.. Considere a seguinte classe: class MaisUmaClasse { int x. ..y = y. Qual a finalidade das palavras-chave this e super? Dê exemplos.out.this. static int y. public void modificaX(int x) { this.} public void atribui(int x. .2)..y = y.

Pág 79 . 19. Como se “repassa” uma exceção. Dê um exemplo. Escreva o código que realize o tratamento desta exceção e imprima a sua descrição (dica: utilize o método getMessage() da superclasse Exception).out. public static MaisUmaClasse A () { return a.modificaY(2). System.y). nome. Crie uma classe em Java (cachorro. por exemplo). Quantas exceções podem ser associadas a um único bloco try? 18.} } 16.out. objeto2. Quando você utiliza no seu programa um método que pode levantar uma exceção.y). sugestão: utilizar um vetor). 15. Escreva um programa que levante. cor. imprimirFilhos(). 20.modificaX(2). Implemente também métodos que manipulem as variáveis privadas (novoFilho(). idade) e privados (filhos.objeto2. esta exceção? 17.). etc. objeto1.println (“Objeto2: x =” + objeto2. algum tipo de exceção (divisão por zero.modificaY(1). propositadamente. System.x + “ y = “ + objeto2. por exemplo) com atributos públicos (raça.x + “ y = “ + objeto1. Por que o código abaixo é inválido? class MaisUmaClasse { private int a. é obrigatório tratar.println (“Objeto1: x =” + objeto1. no seu código.

A figura abaixo mostra o topo da hierarquia de classes da linguagem: A classe Object define e implementa um comportamento que toda a classe de Java precisa. Outras Características da Linguagem Java A seção anterior. Uma subclasse pode utilizar os membros herdados da maneira como foram definidos pelas superclasses. ocultar algumas variáveis ou redefinir os métodos herdados. Esta seção apresenta alguns conceitos mais avançados que ajudarão a organizar e projetar melhor o seu código. subclasses nos níveis mais baixos da hierarquia possuem um comportamento mais especializados. perto do topo da hierarquia.1 Herança Como foi apresentado na seção anterior. implementam um comportamento genérico. Uma subclasse herda estado e comportamento das suas classes ancestrais. Mesmo que na declaração da classe a palavra-chave extends seja omitida. Definição de subclasse: classe que estende outra classe. a palavra-chave extends declara que uma classe é subclasse de uma outra.lang). definida no pacote java. descreveu as características da linguagem que todo programador Java necessita saber para utilizar objetos e escrever classes. Suas subclasses mais imediatas. É a mais geral das classes. em Java. Quais membros são herdados pela subclasse? Pág 80 . a classe possui uma superclasse (classe Object. Classes e Objetos em Java. não há suporte para herança múltipla). pode-se especificar apenas uma superclasse para cada classe (ou seja. podemos dizer que. O termo superclasse refere-se ao ancestral direto da classe e também a todas as outras que são superclasses das classes ancestrais.6. toda classe possui uma superclasse. Desta forma. 6. Em Java.

a menos que a subclasse explicitamente oculte a variável ou redefina o método. privado ou protegido). a partir da classe Subbie. Subclasses herdam aqueles membros da superclasse declarados sem especificadores de acesso (público. Ocultando variáveis • 6.aNumber A palavra-chave super permite que um método faça referência a variáveis ocultas ou a métodos redefinidos da superclasse. } class Subbie extends Super { Float aNumber. Subclasses não herdam os membros privados (private) da superclasse.Regra: Uma subclasse herda todos os membros de sua superclasse que são acessíveis à subclasse. No caso de métodos. porém pode ser uma fonte de muitos erros. A lista a seguir cita os membros que são herdados por uma subclasse: • • • Subclasses herdam os membros da superclasse declarados como públicos (public) ou protegidos (protected). desta forma: super. Pág 81 . No caso de variáveis. Esta característica da linguagem Java traz grande flexibilidade. Considere o seguinte exemplo: class Super { Number aNumber. definido na superclasse. } A variável aNumber na classe Subbie oculta a variável aNumber definida na classe Super.2 Como foi dito. Portanto. variáveis membro definidas na subclasse ocultam variáveis de mesmo nome declaradas na superclasse. Mas é possível acessar a variável aNumber. dizemos que a subclasse redefine o método herdado. Note que construtores não são herdados pelas subclasses. deve-se ser cuidadoso no momento de escolher os nomes das variáveis da subclasse de tal forma a ocultar apenas aquelas variáveis desejadas. desde que estejam no mesmo pacote que a superclasse. As subclasses não herdam os membros da superclasse caso a subclasse declare um membro com o mesmo nome. dizemos que a subclasse oculta a variável da superclasse. Uma outra característica interessante da linguagem é que uma classe pode acessar um membro oculto.

o nome do método e os tipos dos parâmetros devem ser iguais aos do método que está sendo redefinido. O especificador de acesso do método redefinido pode permitir acesso menos restritivo que o método da superclasse.append("[").append(". } return result. senão todas as classes. A saída do método toString seria a representação textual do objeto. todas as classes descendem da classe Object. A maioria. Por exemplo. Pág 82 . } } Observe que o tipo de retorno. Por exemplo.6. for (int i = 0. // code for Stack's methods and constructor not shown // overrides Object's toString method public String toString() { StringBuffer result = new StringBuffer(). i++) { result. que retorna um objeto String contendo o nome da classe do objeto e o seu código hash."). if (i == n-1) result.3 Redefinindo (overriding) métodos A possibilidade de uma subclasse redefinir um método da sua superclasse permite que uma classe herde de uma outra cujo comportamento é “próximo” ao desejado e então complemente ou modifique o comportamento da superclasse. um método protected definido na superclasse pode ser redefinido como público na subclasse mas não pode ser redefinido como privado. i < n.elementAt[i]. result.append("]"). Para a classe Stack.toString(). mas não pode definir um acesso mais restritivo. desejarão redefinir este método e imprimir algo mais relevante. uma listagem dos itens da pilha seria algo interessante a se fazer: public class Stack { private Vector items. else result.append(items. Vamos reconsiderar o exemplo da classe Stack e redefinir o métod toString.toString()). Object possui um método chamado toString.

pode-se modelar um conceito abstrato. o compilador irá exibir uma mensagem de erro similiar a esta: FinalTest. void iamfinal() { ^ 1 error Uma subclasse também não pode redefinir métodos declarados como static na superclasse.lang representa o conceito abstrato de um Pág 83 . O que existe são instâncias de cenouras. a classe Number do pacote java. Por exemplo. serão discutidos os conceitos de métodos e classes abstratas. Alguém já viu uma instância (objeto) do tipo comida? Não. na programação orientada a objetos. super. } 6.java:7: Final methods can't be overridden. bananas. Por exemplo.4 Métodos e Classes Abstratas Algumas vezes. 6.3. Considere. Em outras palavras. por exemplo. é preciso executar o método da superclasse utilizando a palavra-chave super. necessita-se apenas adicionar maior funcionalidade ao método herdado. a implementação do método finalize da classe Stack executa o método finalize definido na superclasse (Object): protected void finalize() throws Throwable { items = null.3 Métodos que uma subclasse deve redefinir Uma subclasse deve redefinir métodos que são declarados como abstract na superclasse. 6. Comida representa o conceito abstrato e não é capaz de criar uma instância própria.3. Para fazer isto. etc.1 Executando o método que foi redefinido Algumas vezes. Analogamente. maçãs. comida no mundo real. como tal não deve ser instanciada. Method void iamfinal() is final in class ClassWithFinalMethod. uma subclasse não pode redefinir um método de classe.finalize(). Na próxima seção. não se deseja redefinir completamente um método.2 Métodos que uma subclasse não pode redefinir Uma subclasse não pode redefinir métodos que estão declarados como final na superclasse. ou a subclasse também deve ser abstrata. Ao tentar redefinir um método final. Simplesmente. uma classe representa um conceito abstrato e. chocolates.3.6.

retângulos. utiliza-se a palavra-chave abstract antes da palavra-chave class: abstract class Number { . } Se você tentar instanciar uma classe abstrata. GraphicObject também declara métodos abstratos como desenhar (draw). Para declarar uma classe como abstrata.) compartilham alguns estados (posição. linhas.. GraphicObject. Ou seja. ^ 1 error Uma classe abstrata pode conter métodos abstratos. curvas Bezier. new AbstractTest(). métodos que não possuem implementação definida.número.) devem saber como desenhar a si mesmos – eles compartilham o comportamento (desenhar) mas diferem em como este comportamento é implementado. Pode-se tirar vantagem destas similaridades e declarar estas classes como subclasses de uma classe única: GraphicObject. Por isto. Em uma aplicação de desenho. desenhar). Uma classe abstrata é uma classe que só pode ser utilizada como superclasse. suponha que você deseja criar uma classe com um método abstrato dentro dela. a classe GraphicObject possuiria uma implementação como: Pág 84 . Classes. redimensionar. Primeiramente. ou seja. círculos. que representam um conceito abstrato e não podem ser instanciadas. etc. It can't be instantiated. por exemplo: Entretanto. o compilador irá mostrar um erro parecido com este: AbstractTest. como Number. cor) e comportamento (mover. as classes (círculo. Esta é uma situação perfeita para a criação de uma superclasse abstrata. tais como a variável posição e o método mover (moveTo).java:6: class AbstractTest is an abstract class. Esta classe Number é a superclasse de classes como Integer e Float. não faz sentido definir uma implementação “default” para a superclasse. etc. que precisam ser implementados por todas as subclasses. Cada subclasse vai implementar o método draw de maneira diferente. deve-se declarar uma classe abstrata. os objetos gráficos são bastante diferentes: desenhar um círculo é bem diferente de desenhar um retângulo. são chamadas de classes abstratas.. que possui variáveis membros e métodos que são compartilhados (inteiramente) por todas as subclasses. Então. todos os objetos (retângulos. Por exemplo.

5 Classes e Métodos Finais Pode-se declarar uma classe como final. A subclasse parece e age como a classe original mas faz coisas bastante diferentes (e devastadoras). int newY) { .. ou seja.. deve ser declarada como uma classe abstrata. indesejável ou imprevisível. } } class Rectangle extends GraphicObject { void draw() { . podendo causar danos ou acessando informação privada. Além disto. como Circle e Rectangle.abstract class GraphicObject { int x.. 6. deve definir uma implementação para o método draw: class Circle extends GraphicObject { void draw() { . } abstract void draw().. Esta classe é tão vital para a operação do compilador e do interpretador que o ambiente Java deve garantir que quaisquer métodos ou objetos que usem uma String acessem a classe definida pelo ambiente e não um outro tipo de String. } Cada subclasse não abstrata de GraphicObject.. o compilador exibirá uma mensagem de erro. } } Observação: Uma classe abstrata não precisa. ou não definir uma implementação para um método abstrato que foi herdado. você pode declarar sua classe como final. possuir um método abstrato.. Para prevenir este tipo de ataque. qualquer classe que possuir um método abstrato.. a classe String de Java é uma classe final por esta razão. inconsistente. Porém. void moveTo(int newX. Ao tentar compilar uma subclasse de uma classe final. Por exemplo.. o verificador Pág 85 . Isto garante que as Strings näo possuem nenhum comportamento estranho. necessariamente. . y. a classe não pode ser derivada (possuir subclasses). Existem pelo menos duas razões para desejar que uma classe possua tal característica: • Segurança: Um mecanismo que hackers utilizam para atacar sistemas é criar uma subclasse de uma classe e substituir a classe original pela subclasse.

suponha que você deseja declarar sua classe (perfeita) ChessAlgorithm como final. verificando se a classe que está sendo executada não é uma subclasse de uma classe final.. como este: Chess.. BoardLocation newLocation) { . Para isto.. } Quaisquer tentativas de criar uma subclasse de ChessAlgorithm irão resultar em um erro de compilação.. o que se deseja é.• bytecode do interpretador também garante que nenhum tipo de ataque deste tipo está sendo feito. Pode-se pensar que uma dada classe é “perfeita” ou. proteger apenas alguns dos métodos da classe de serem redefinidos por uma subclasse. final void nextMove(ChessPiece pieceMoved. em vez de tornar a sua classe ChessAlgorithm final. Para especificar que uma classe é final. Boas práticas de projeto: por razões do projeto orientado a objetos. Pode-se querer que um método seja final porque sua implementação não pode ser alterada ou porque tal método é crítico para manter o estado do objeto consistente .. pode-se desejar criar uma classe final... conceitualmente. você poderia querer tornar apenas o método nextMove final: class ChessAlgorithm { .6 Interfaces Pág 86 .java:6: Can't subclass final classes: class ChessAlgorithm class BetterChessAlgorithm extends ChessAlgorithm { ^ 1 error As vezes. que não deve possuir subclasses. } 6. utiliza-se a palavra-chave final antes da palavrachave class na declaração da classe.. } . Por exemplo. na verdade. a declaração será: final class ChessAlgorithm { . utiliza-se a palavra-chave final nas declarações de método para indicar para o compilador que tais métodos não podem ser redefinidos por subclasses. Por exemplo.

uma interface é um dispositivo ou sistema que entidades utilizam para interagir entre si. } else { sleepers[index] = theSleeper. Uma interface Java define um conjunto de métodos mas não define uma implementação para eles.Em inglês (ou português).start(). Uma classe que implementa a interface deve implementar todos os métodos definidos na interface. O exemplo é bem simples mas mostra como criar e utilizar uma interface e também dá algumas “dicas“ sobre quando utilizar interfaces ou classes abstratas. então ele registra o objeto “dorminhoco” (sleeper). Implementar o método WakeUp (acordar). Definição: Uma interface é uma coleção de definições de métodos (sem implementação). o português é uma interface entre duas pessoas. que é implementado da seguinte forma: public synchronized boolean letMeSleepFor(Sleeper theSleeper. if (index == NOROOM) { return false. A classe AlarmClock (despertador) é uma “provedora de serviços” – ela avisa objetos que um determinado período de tempo passou. return true. De acordo com esta definição. um objeto que queira usar o despertador deve implementar o método wakeUp de tal forma que o AlarmClock possa avisar o objeto “dorminhoco” que o tempo já passou. uma interface Java é um mecanismo que objetos utilizam para interagir. Depois do período de tempo determinado. Analogamente. } } Se o AlarmClock tiver espaço. Para satisfazer o primeiro requisito. new AlarmThread(index). long time) { int index = findNextSlot(). Pedir para que o despertador o “acorde”. inicia uma nova thread AlarmThread e retorna true. um objeto deve fazer duas coisas: 1. o AlarmClock vai executar o método wakeUp do objeto dorminhoco. um objeto executa o método letMeSleepFor do AlarmClock. um controle remoto é uma interface entre você e a televisão. 2. Pág 87 . Mas como isto é feito? Isto é feito por meio do tipo de dado do objeto dorminhoco que está sendo registrado. sleepFor[index] = time. Considere o seguinte exemplo que apresenta duas classes que utilizam uma interface para interagir. Uma interface também pode incluir declarações de constantes. Assim. Para utilizar os “serviços” do AlarmClock.

letMeSleepFor(this.Note que o primeiro argumento de letMeSleepFor é o objeto que quer ser acordado. Por exemplo. abstratos. O tipo de dado deste argumento é Sleeper. clock. GUIClock não pode ser subcclasse de Sleeper e Applet. ONE_MINUTE). As duas soluções não são equivalentes. Classes que implementam esta interface “herdam” as constantes e devem implementar o método wakeUp. Por exemplo. public void wakeUp() { repaint(). public long ONE_SECOND = 1000.. portanto. ou seja. GUIClock. que é um applet que mostra o tempo atual e utiliza um objeto AlarmClock para acordá-lo a cada minuto para que ele possa atualizar o display. A seguinte classe Sleeper não faria a mesma coisa que a interface Sleeper? abstract class Sleeper { public abstract void wakeUp(). possa ser passado como parâmetro do método letMeSleepFor) implementa esta interface. Entretanto. Qualquer objeto que seja um Sleeper (e que. } Não. // in milliseconds // in milliseconds Pág 88 . class GUIClock extends Applet implements Sleeper { .. } } Depois que vimos a utilização de uma interface. Se Sleeper é uma classe abstrata. Mas Java não possui herança múltipla. } A interface Sleeper define o método wakeUp mas não o implementa. que é o nome da interface: public interface Sleeper { public void wakeUp(). considere a seguinte classe. a classe GUIClock é uma subclasse de Applet – caso contrário não seria possível executá-lo em um browser. surgem algumas questões importantes : Por que não utilizar uma classe abstrata? Observe que uma interface é simplesmente uma lista de métodos não implementados. muitos objetos que desejam utilizar AlarmClock já possuem uma superclasse. então todos os objetos que desejarem utilizar AlarmClock devem ser instâncias de uma subclasse de Sleeper. ou seja. public long ONE_MINUTE = 60000. A interface também define duas constantes úteis (ONE_SECOND e ONE_MINUTE). Isto significa que o objeto implementa todos os métodos definidos pela interface.

1 Definindo uma Interface A figura a seguir mostra que uma definição de interface possui dois componentes: a declaração e o corpo da interface: Declaração da Interface A declaração da interface Sleeper utiliza os dois elementos obrigatórios da linguagem: a palavra-chave interface e o nome da interface. qual a utilidade de interfaces? Você pode usar uma interface para definir um comportamento que pode ser implementado por qualquer classe.6. Classes que implementam a mesma interface podem ou não estar relacionadas em uma hierarquia de classes. 6. além do modificador de acesso (public): Pág 89 . Apesar de interfaces resolverem muitos problemas parecidos. A hierarquia de interfaces é independente da hierarquia de classes. sem ser obrigado a criar artificialmente uma relação de herança entre elas.Então as interfaces proporcionam herança múltipla? Muitas vezes interfaces são apresentadas como uma alternativa para herança múltipla de classes. uma interface pode possuir múltiplas “superinterfaces”. Declaração de métodos que uma ou mais classes esperam implementar. Uma classe não poder herdar implementações de métodos de uma interface. Interfaces são úteis nos seguintes casos: • • Captura de similaridades entre classes não relacionadas. interfaces e herança múltipla são soluções bem distintas: • • • Uma classe só herda constantes de uma interface. Isto não ocorre no caso de herança múltipla. independente da sua hierarquia de classes. Importante: Java permite herança de multiplas interfaces. Afinal. Ou seja.

Entretanto. públicos e abstratos. O corpo da interface também pode possuir declarações de constantes. estáticas (static) e finais (final). Por exemplo: public interface Sleeper { public void wakeUp().public interface Sleeper { . implicitamente. implicitamente. Uma interface pode ser derivada de outras interfaces. como ocorre com as classes. uma interface pode ser derivada de mais de uma interface. Todas as constantes declaradas são.. Uma declaração completa de interface é mostrada na figura abaixo: Caso a interface seja declarada como public.ONE_SECOND Classes que implementam uma interface podem acessar estas constantes como se fossem variáveis herdadas: public class GUIClock extends Applet implements Sleeper { Pág 90 . } Todos os métodos declarados na interface são. Se nâo for especificado que a interface é pública. Para utilizar as constantes definidas na interface. ela pode ser utilizada por qualquer classe. Corpo da Interface O corpo da interface contém a declaração de todos os métodos da interface. apenas as classes que estão definidas no mesmo pacote podem acessá-la. deve-se referenciar o nome da interface. públicas. } Uma interface pode ter outro componente: uma lista de “superinterfaces”. A lista de “superinterfaces” é uma lista delimitada por vírgulas. public long ONE_MINUTE = 60000.. public long ONE_SECOND = 1000. Por exemplo: Sleeper.

define-se um novo tipo de dado (referência).letMeSleepFor(this. public void wakeUp() { // update the display } } Lembre-se que quando uma classe implementa uma interface.. Portanto.7 Utilizando Interfaces como Tipos de Dados Quando se define uma nova interface..6. 6. Pág 91 . todas as classes que implementam a interface antiga terão problemas pois elas não implementam mais a interface. ela deve implementar todos os métodos declarados na interface (e em suas superinterfaces.. private boolean letMeSleepFor(Sleeper theSleeper. A assinatura do método (o nome e o número e o tipo dos parâmetros) do método da classe deve ser idêntico ao da assinatura do método definido na interface. a classe deve ser declarada como abstrata.. deve-se antecipar ao máximo todos os usos da sua interface e especificá-la completamente desde o início.2 Implementando uma Interface O exemplo da classe GUIClock já demonstrou como implementar uma interface (Sleeper): public class GUIClock extends Applet implements Sleeper { . Por exemplo: private Sleeper[] sleepers = new Sleeper[MAX_CAPACITY]. Programadores que utilizam a interface certamente vâo reclamar bastante... se for o caso). } } 6. Você pode utilizar nomes de interface como um tipo comum de variável. essencialmente. public void wakeUp() { repaint().. int time) { . } Observação: Interfaces não podem crescer. Ou. ONE_MINUTE). Note que toda vez que você realizar uma modificação em uma interface. clock.

. Pacotes também podem conter interfaces. } Deve-se incluir a palavra-chave package no início de todo arquivo que define uma classe ou interface que pertence ao pacote.1 Criando um Pacote Para criar um pacote. Por exemplo.6.8 Pacotes (Packages) Para tornar as classes mais fáceis de se encontrar e utilizar. public class Rectangle extends Graphic implements Draggable { . simplesmente coloca-se a classe ou interface dentro dele. As classes e interfaces que fazem parte do kit de desenvolvimento Java (JDK) são membros de vários pacotes: classes dos applets estão no pacote java.. 6..applet. pode-se agrupar classes relacionadas em pacotes (packages). Podemos citar as seguintes vantagens da utilização de pacotes: • Fica mais fácil para outros programadores determinar quais classes e interfaces estão relacionadas.java: package graphics.. o código a seguir coloca a classe Circle (que está no arquivo Circle.java) no pacote graphics: package graphics. coloca-se a palavra-chave package no início do arquivo onde a classe ou interface é definida.io e as classes de elementos de interface gráfica estão no pacote java. variáveis e métodos) públicos são acessíveis fora do pacote onde foram definidos. para evitar conflitos de nomes e para controlar o acesso. Assim.awt. • Os nomes das classes de um pacote não irão conflitar com nomes de classes de outros pacotes. public class Circle extends Graphic implements Draggable { . Para isto. • Pode-se permitir que classes dentro de um mesmo pacote tenham acesso irrestrito entre si. seguindo o exemplo acima.8. deve-se incluir package no arquivo Rectangle. e restringir o acesso por parte de classes definidas fora do pacote. Pág 92 . de entrada/saída no pacote java. } Lembrete: Apenas membros (classes.

8. deve-se utilizar o nome completo (long name) que inclui o nome do pacote. sua classe ou interface será automaticamente incluída no pacote default. Como evitar esta situação? Utilizando uma convenção.2 Utilizando Membros de um Pacote Apenas membros (classes.meupacote.Rectangle myRect = new graphics. Ou seja.uemg. ocorrerão problemas. Por exemplo: com. deve-se: • • • refrir-se ao membro utilizando o seu nome completo.Rectangle(). provavelmente dois programadores utilizem o mesmo nome para duas classes diferentes. br. Referenciar um Membro do Pacote pelo Nome Quando se deseja utilizar um membro de um pacote diferente. aconselha-se que todas as classes e interfaces pertençam a pacotes “com nome”.meupacote 6. Por exemplo. Definindo um Nome para o Pacote Com programadores em todo mundo escrevendo classes e interfaces em Java. e o pacote não foi importado. este é o nome completo da classe Rectangle declarada no pacote graphics: graphics. O conceito de pacote permite que classes em pacotes diferentes possuam o mesmo nome sem causar erros de compilação. importar o membro do pacote. Importar um Membro do Pacote Pág 93 . de maneira inversa.minhaempresa. Este pacote default deve ser utilizado apenas para pequenas aplicações ou no início do desenvolvimento de aplicações mais complexas.passos. que é um pacote que não possui nome. Convenção: Empresas utilizam os seus nomes de domínio da Internet. métodos e variáveis) são acessíveis fora do pacote onde foram definidos. Mas se os pacotes forem definidos com o mesmo nome.Observação Importante: se você não utilizar a palavra-chave package.Rectangle Para criar uma instância desta classe: graphics. ou importar todo o pacote. para definir o nome dos seus pacotes. Para utilizar membros públicos fora do seu pacote.

Agora. e ambos os pacotes são importados. Importar Todo o Pacote Para importar todas as classes e interface pertencentes a um pacote. pode-se referenciar qualquer classe ou interface do pacote graphics pelo seu nome curto: Circle myCircle = new Circle(). O asterisco só pode ser utilizado para importar todas as classes de um pacote. Ele não pode ser usado para importar um subconjunto de classes do pacote.lang O pacote atual Nomes Ambíguos Caso uma classe em um pacote possua o mesmo nome que uma classe definida em outro pacote. foi definida uma classe Rectangle no pacote graphics. deve-se referenciar tais classes pelo seu nome completo. o código a seguir não importa todas as classes do pacote graphics que começam om a letra “A”: import graphics.*.A*. pode-se referenciar a classe círculo pelo seu nome curto: Circle myCircle = new Circle(). o ambiente de execução Java automaticamente importa três pacotes: • • • O pacote default (que não possui nome) O pacote java. de compilação // não funciona ! Irá gerar um erro Por conveniência. mas depois da declaração do package). Por exemplo. Rectangle myRectangle = new Rectangle(). utiliza-se o import junto com o caracter * : import graphics.Circle. Neste caso. o código abaixo torna-se ambíguo: Rectangle rect. O pacote java.awt também possui uma classe chamada Rectangle. deve-se colocar a palavra-chave import no início do arquivo (antes das definições de classes e interfaces. Se ambos pacotes forem importados. Por exemplo. Agora. para importar a classe Circle do pacote graphics: import graphics. deve-se obrigatoriamente ser mais específico e indicar exatamente qual classe Rectangle deseja-se referenciar: Pág 94 .Para importar um membro específico do pacote. No exemplo anterior.

Rectangle rect. pode estar em qualquer diretório do sistema de arquivos.java. o compilador cria um arquivo de saída para cada classe e interface definida. Este arquivo fonte deve ficar em um diretório cujo nome é igual ao do pacote que contém a classe ou interface.java (UNIX) (Windows) Ao compilar o arquivo fonte. Cada componente do nome do pacote corresponde a um subdiretório. supondo que a UEMG/Passos tenha um pacote chamado graphics que contém um arquivo chamado Rectangle. o código fonte da classe Rectangle deve estar em um arquivo chamado Rectangle. assim todos os pacotes desenvolvidos na Universidade deveriam ter seus nomes precedidos por br. 6.passos.br. Assim.uemg. O diretório graphics. embora a especificação da linguagem Java não determine isto.java br\uemg\passos\graphics\Retangle. A estratégia é a seguinte. Por exemplo. Por exemplo. a UEMG/Passos possui o domínio passos.java) e de classes (.class: Pág 95 .class). este arquivo ficaria em: package br.java caminho do arquivo Além disto. por sua vez. O código fonte de uma classe ou interface deve ser colocado em um arquivo texto cujo nome é igual ao nome da classe e cuja extensão é .java e o arquivo deve estar em um diretório chamado graphics.passos. por convenção.uemg. O diagrama a seguir mostra como isto funciona.java.9 Gerenciando Arquivos Fonte e Arquivos de Classe O ambiente de desenvolvimento JDK baseia-se em um sistema de arquivos hierárquico para gerenciar os arquivos fonte (.graphics br/uemg/passos/graphics/Retangle.Rectangle Nome da classe graphics/Rectangle. O nome (longo) do membro do pacote e o caminho (pathname) do arquivo são “paralelos” (considerando o separador de arquivos do Unix “/” e não do Windows “\”): graphics. O nome do arquivo é igual ao nome da classe ou interface e sua extensão é . cada empresa utiliza o seu domínio de Internet invertido para denominar os seus pacotes.graphics.uemg.

Analogamente.zip das classes do JDK já fazem parte automaticamente do seu class path.Como o arquivo . A partir dos diretórios listados no classpath. Cada diretório definido no class path é um local onde os diretórios dos pacotes podem aparecer.class deve estar em uma série de diretórios que reflete o nome do pacote. o compilador e o interpretador procuram o diretório atual (. por exemplo: fontes\br\uemg\passos\graphics\Retangle.java (Windows) classes\br\uemg\passos\graphics\Retangle. Definindo o Class Path Há duas maneiras para se alterar o class path: • Definir a variável de ambiente CLASSPATH (não recomendado) • Utilizar a opção -classpath quando invocar o compilador ou o interpretador. você pode fornecer o seu diretório de classes a outros programadores sem ter que revelar o código-fonte. Ou seja.zip que contém todas as classes do JDK. ele não precisa estar no mesmo diretório que o arquivo fonte. afinal de contas. um arquivo . Pág 96 . o diretório atual e os arquivo . Entretanto. pode-se definir diretórios separados para os arquivos fonte e os arquivos de classes. o class path para a estrutura de diretórios classes\br\uemg\passos\graphics\Retangle.zip) definido no class path (caminho de classes). Por default. para que se preocupar em seguir esta convenção de nomes diretórios/arquivos? Isto é necessário pois somente desta forma o compilador e o interpretador Java são capazes de encontrar todas as classes e interfaces utilizadas pela sua aplicação. Definição: O class path é uma lista de diretórios ou arquivos compactados onde o compilador/interpretador realiza a busca por classes ou interfaces. quando o interpretador encontra uma nova classe enquanto está executando a sua aplicação. ele deve ser capaz de executar os métodos desta classe.class (Windows) Desta forma.class deve incluir o diretório classes mas não os subdiretórios br ou passos. Mas.) e o arquivo . Quando o compilador encontra uma nova classe enquanto compila a sua aplicação. o compilador e o interpretador podem construir o resto do caminho do arquivo baseado no nome do pacote e da classe Por exemplo. Em outras palavras. ele deve ser capaz de encontrar o arquivo correspondente. Tanto o compilador quanto o interpretador procuram por classes em cada diretório (ou arquivo .java. por exemplo.

não realiza a busca nos demais diretórios. } class Carnivoro { int numeroDeDentes.zip (UNIX) (Windows) Observação Importante: ao definir o class path desta forma. na ordem. Considere o seguinte código class Mamifero { int idade.C:\classes.10 Exercícios 1. Quando o interpretador Java está procurando por uma classe ele procura as entradas no seu class path. por exemplo). deve-se sempre incluir o arquivo classes. A segunda opção é preferível pois define o class path apenas para a execução atual do compilador/interpretador.bat.:~/classes:/JDK/lib/classes.Não é recomendado alterar a variável de ambiente CLASSPATH pois tal mudança pode ser duradoura (se estiver no autoexec. até que a primeira classe com o nome correto seja encontrada. um dia. seu programa não funcionar pois o compilador/interpretador carregou uma classe “antiga” que estava em um diretório “esquecido” definido no class path. O exemplo abaixo mostra como utilizar a opção -classpath para definir o seu classpath: javac -classpath . Considere a seguinte classe: class MinhaClasse { Pág 97 . } Por que o código abaixo irá gerar um erro de compilação? class Aluno extends Mamifero. Portanto. então.zip do JDK em seu class path. O interpretador. você redefine completamente o class path atual. Observação: A ordem dos diretórios no class path é importante.. } 3. é fácil esquecer de que uma mudança foi feita e corre-se o risco de. Carnivoro { int matricula.zip javac -classpath . 6. Também é aconselhável incluir o diretório atual.C:\JDK\lib\classes. } 2. Assim. Qual é a superclasse de: class Pessoa { String nome.

System.out. 6. O que é uma interface? O que podemos definir em uma interface Java? 9. OutraInterface 12.} public MinhaClasse() { x=y=z=w=0. deseja que ele seja herdado por subclasses. O trecho de código abaixo está correto? Justifique. Em Java. public int z. public int getX() { return x.private int x. super.x).out. protected int y. É possível que uma classe abstrata defina a implementação de alguns métodos? É possível que uma classe não-abstrata não defina a implementação de um de seus métodos? 7.println(“ x = “ + this.x = 2. class MinhaClasse implements UmaInterface. 13. } class B extends A { public int x. } Qual a saída do programa definido na classe B (java B)? Justifique. Como você declararia este método? Dê um exemplo em Java. Quais são as diferenças entre uma classe abstrata e uma interface? 11. Dê um exemplo de uma entidade do mundo real que possa ser modelada como uma classe abstrata. porém não que ele possa ser redefinido pelas subclasses.x). Defina alguns métodos e constantes para tal interface. 8. não pode ter subclasses)? Indique duas razões para criar uma classe com esta característica. int w. O que acontece quando uma classe é declarada desta maneira? class MinhaClasse implements MinhaInterface 10. Defina uma interface chamada BomAluno. public static voi main (String args[]) { x = 1. 5. System. Suponha que você criou um método em uma classe. A declaração da classe abaixo está correta? Justifique. Considere as classes: class A { public int x.println(“ x = “ + super. como se declara uma classe que não pode ser derivada (isto é. 5. Escreva a definição desta classe em Java.} } Quais os membros (variáveis/métodos) de MinhaClasse que são herdados por uma subclasse definida no mesmo pacote? 4. Pág 98 .

interface UmaInterface { . Como o nome de um pacote em Java se relaciona com a estrutura de diretórios do sistema de arquivo. } class UmaClasse implements UmaInterface { .passos. que utilize a classe carro.maquinas que possua uma classe carro. por exemplo. que não pertença a este pacote. 17. A classe abaixo pertence a qual pacote? class A { int x. Dê exemplos.seunome. Quais os 3 pacotes que o ambiente Java importa automaticamente? 19. Crie um pacote chamado br. Dê exemplos. O que é um pacote? Qual a sua finalidade? 15. UmaInterface a = new UmaClasse(). Quais são as 3 maneiras de se utilizar uma classe ou interface que pertence a um outro pacote? Dê exemplos. 18.. Pág 99 . Como se adiciona uma classe ou interface a um pacote..uemg... 14. 21. } 16. Defina uma aplicação. O que é o class path? Como ele pode ser definido? 20. }.

1 Widgets A figura abaixo ilustra a hierarquia de classes dos componentes gráficos (widgets) do pacote AWT: Cada um destes componentes será apresentado nas subseções a seguir. o componente é apagado e então desenhado Pág 100 . Interface Gráfica Esta seção mostra como se pode criar interfaces gráficas (GUI. teclas pressionadas e mudam seu estado ou alteram algum dado interno da aplicação. Alguns métodos importantes: • public void disable(): desabilita o componente (em relação às ações do usuário) • public void enable(): habilita o componente (em relação às ações do usuário) • public Graphics getGraphics(): retorna o contexto gráfico do componte • public void paint(Graphics g): faz com que o componente seja (re)desenhado na tela (no contexto gráfico fornecido) • public void repaint(): redesenha o componente. posicionados de alguma forma em um applet ou em uma janela de uma aplicação stand-alone. Graphical User Interface) para aplicações stand-alone e applets Java. Uma interface gráfica (GUI) consiste de componentes (widgets). como cliques no mouse. 7. Todos os widgets gráficos são subclasses de Component.1.7. 7. Estes componentes respondem a eventos iniciados pelo usuário. como botões e text-fields.1 Component Um componente é um widget genérico que não pode ser instanciado (Component é uma classe abstrata). utilizando o pacote AWT (Abstract Windowing Toolkit).

setBackground(new Color(255.1.0). public class CheckboxWidget extends Applet { public void init() { Checkbox m = new Checkbox("Allow Mixed Case"). Exemplo: import java.0. TextField tf = new TextField(“0”).applet. import java. deriva-se a classe Canvas e o método paint é então redefinido de acordo com a aplicação (desenhar uma figura qualquer.*. o estado inicial (default) é falso. add(m).awt. O estado de um checkbox é verdadeiro (botão pressionado) ou falso (botão liberado). • public void paint(Graphics g): normalmente.255.*. add(b).1.• public void setForeground(Color c): define a cor do primeiro plano do componente Ex.*. • public void setBackground(Color c): define a cor de “fundo” do componente Ex.3 Canvas A classe Canvas é um componente gráfico genérico que representa uma região onde se pode desenhar coisas como retângulos..4 Checkbox A classe Checkbox representa um label com um pequeno botão.awt. public class ButtonWidget extends Applet { public void init() { Button b = new Button("OK"). 7.2 Button A classe Button representa um (botão) que possui um label que pode ser “pressionado” por meio de um clique do mouse.applet. } } Alguns métodos importantes: • public Button(String label): Cria um botão com o label dado 7.0). } } Pág 101 . círculos e strings. Por exemplo: import java.setForeground(new Color(0. import java.1. 7.*. TextField tf = new TextField(“0”). tf. por exemplo). tf.

import java.1. CheckboxGroup g. public class CheckboxGroupWidget extends Applet { public void init() { // create button controller CheckboxGroup cbg = new CheckboxGroup().addItem("Blue").*. cb1 = new Checkbox("Show lowercase only". apenas um dos objetos checkbox pode ser verdadeiro (ou seja estar “marcado”).*. Os itens desta lista são adicionados ao objeto Choice por meio do método addItem. } } Pág 102 .*. import java.1.Alguns métodos importantes: • • • • public Checkbox(String label): Cria um checkbox com o label especificado public Checkbox(String label. boolean state) : Construtor utilizado quando o checkbox é membro de um CheckBoxGroup public boolean getState() : obtém o estado do checkbox (true ou false) public void setState(boolean state) : define o estado do checkbox 7.cbg. rgb.true). } } 7. Por exemplo: import java.addItem("Green"). rgb. add(cb1). em um dado instante. add(cb2).awt.awt. rgb.cbg.false).applet. Em um checkboxgroup.applet. Objetos checkbox controlados com um ckeckboxgroup podem ser chamados de radio buttons. public class ChoiceWidget extends Applet { public void init() { Choice rgb = new Choice(). Por exemplo: import java.*.addItem("Red").5 CheckBoxGroup A classe CheckBoxGroup é utilizada para controlar o comportamento de um grupo de objetos checkbox. Checkbox cb2.6 Choice A classe Choice representa uma lista de seleção. Checkbox cb1. add(rgb). cb2 = new Checkbox("Show uppercase only".

*.awt.Alguns métodos importantes: • • • • public int getSelectedIndex(): retorna o índice (numérico) do item selecionado public String getSelectedItem() : retorna o label (string) do item selecionado public void select(int pos) : define o item selecionado (por meio do índice) public void select(String str) : define o item selecionado (por meio do label) 7.Label. import java.*.addItem(“Maçã”). l. public class ListWidget extends Applet { public void init() { List l = new List(2.addItem(“Banana”).addItem(“Pera”).RIGHT)). boolean multipleSelections):cria uma lista que mostra o número de linhas especificado. true). l. } } 7.awt. pode-se selecionar mais de um item da lista Pág 103 . l. Por exemplo: import java. Por exemplo: import java.applet.1.8 List A classe List é uma lista de seleção que permite a escolha de um ou mais itens.*.applet. Múltiplos argumentos podem ser selecionados se passarmos true como segundo argumento do construtor de List. Se multipleSelections for true.*. // right justify add(new Label("right justified label". public class LabelWidget extends Applet { public void init() { add(new Label("a label")). } } Alguns métodos importantes: • public List(int rows.1. add(l).7 Label A classe Label representa uma string de texto mostrada na tela. import java.

Existem scroll bars verticais e horizontais. public void setText(String t): Define o conteúdo (texto) do componente.11 TextArea Representa um campo de texto com várias linhas. o usuário não pode modificar o conteúdo do componente.HORIZONTAL ou Scrollbar.awt.1.1)).1.HORIZONTAL).VERTICAL) especificada. 7. ela é a superclasse dos widgets de edição de texto (TextField e TextArea). Alguns métodos importantes: • • • • public String getSelectedText():Obtém o texto selecionado. } } Alguns métodos importantes: • public Scrollbar(int orientation):Constrói um scroll bar com a orientação (Scrollbar.*. sb = new Scrollbar(Scrollbar.9 Scrollbar Esta classe representa um “barra rolante” que contém um valor inteiro.• • • • public void addItem(String item) : Adiciona um item a lista public int getSelectedIndex(): retorna o item selecionado (indíce numérico) public int[] getSelectedIndexes() : retorna os itens selecionados (vetor de índices numéricos) public void select(int index): seleciona um item (índice numérico) 7. add(sb). import java. Scrollbar sb. public class ScrollbarWidget extends Applet { public void init() { // using a GridLayout ensures Scrollbar fills applet setLayout(new GridLayout(1. Exemplo: Pág 104 . A largura e altura do campo são definidas pelo seu construtor.applet. Exemplo: import java. 7. public String getText():Obtém todo o texto do componente.*.10 TextComponent A classe TextComponent não pode ser instanciada.1. public void setEditable(boolean t): Se nâo-editável.

applet. int cols): Cria uma área de texto com o número especificado de linhas e colunas.awt. public class MinhaApp extends Frame { Pág 105 . A largura do campo é especificada pelo construtor da classe e um texto inicial também pode ser especificado.applet.awt. Em geral. import java.1. add(f1). 7.1. } } Alguns métodos importantes: • public TextArea(String text.*. int cols): Cria um campo texto com o conteúdo inicial e o tamanho (número de colunas) do campo. 3.*. Exemplo: import java. além do texto inicial.*. } } Alguns métodos importantes: • • public TextField(String text): Cria um campo texto com o conteúdo inicial especificado. add(disp).*.import java.12 TextField Um campo texto representa um widget que mostra uma linha de texto. public class TextFieldWidget extends Applet { public void init() { TextField f1 = new TextField("type something").awt.13 Frame Esta classe representa objetos que são janelas. public class TextAreaWidget extends Applet { public void init() { TextArea disp = new TextArea("A TextArea". 7. import java. int rows. são utilizados por aplicações Java standalone. public TextField(String text.*. import java.applet. Exemplo: import java.*. 30).

A fórmula básica para se inserir um widget em um applet é a seguinte: 1. setLayout(new BorderLayout()). por exemplo: Button b = new Button("Hit me"). int y. int widht. setTitle("Minha Janela"). public void show(): exibe a janela public void hide(): oculta a janela public void reshape(int x. show(). Panel p. Adicionar o componente ao applet. add("North". add(tf). int height): redimensiona a janela (largura e altura) e a posiciona nas coordenadas (x. Frame f.250. p. TextField tf = new TextField("0"). 30).250. p = new Panel(). Criar o componente (widget) com o operador new. por exemplo: add(b). } } Alguns métodos importantes: • • • • • public Frame(): cria uma nova janela public void SetTitle(String title): define o título da janela.250). 3. é importante entender o conceito de um Container.add(disp). p). reshape(250. Inserindo Widgets em Applets 7. disp = new TextArea("A TextArea".2 Todos os widgets que podem ser adicionados a um applet são subclasses da classe Component. } public MinhaApp() { TextArea disp.public static void main(String args[]) { MinhaApp app = new MinhaApp().y). Containers contêm objetos Pág 106 . Como os widgets adicionados aos applets vão aparecer na tela? Para responder esta questão. 2.

Cada uma destas sub-regiões é um container e possui o seu layout manager associado.0).1 da linguagem Java.1) é suportado pelos browsers Pág 107 . Os eventos são representados por diversas classes em Java.que irão aparecer na tela. Os diferentes tipos de layout managers serão apresentados em uma próxima seção. Em geral. Observação Importante: O modelo de eventos apresentado nesta seção refere-se a versão 1. etc. no método init: import java. teclas pressionadas. O simples fato de se adicionar um Component a um Container faz com que este componente (widget) seja desenhado na tela. Por conveniência. public class MeuApplet extends Applet { Button b. public void init() { b = new Button("Hit me"). podemos adicionar widgets ao applet. TextField tf. o applet é um tipo de container associado com uma região retangular dentro de uma janela de um browser (Applet é uma subclasse de Panel que. estes estímulos são chamados de eventos. da classe FlowLayout. Um layout manager é um objeto que posiciona e redimensiona os componentes de um container de acordo com um algoritmo. FlowLayout é o layout manager default para applets.awt. Por exemplo.event.a região do applet deve então ser subdividida. Por exemplo.awt.*. Estes containers possuem uma região associada. 7. } } Para organizar a apresentação (layout) dos widgets dentro de um container. um layout manager não será suficiente para posicionar seus applets . add(tf). todos os tipos de evento do AWT são colocados no pacote java. o layout manager.awt. utiliza-se um layout manager.AWTEvent. todos os eventos são subclasses de java. tf = new TextField("0"). Assim. Entretanto.)? Na linguagem Java. por sua vez. add(b). então.*. import java. O novo modelo de eventos (versão 1. posiciona os componentes da esquerda para a direita até que não haja mais espaço e.applet.1) Como os componentes da GUI respondem a estímulos do usuário (cliques no mouse. continua a posicionar os objetos na “linha” abaixo. Este modelo de eventos é incompatível com o modelo de eventos anterior (versão 1.3 Modelo de Eventos do Java (1. é uma subclasse de Container).

e os métodos definidos na interface Classe de Evento ActionEvent ComponentEvent Interface do Ouvinte ActionListener ComponentListener Métodos do Ouvinte actionPerformed() componentHidden() componentMoved() componentResized() componentShown() focusGained() focusLost() itemStateChanged() keyPressed() keyReleased() keyTyped() mouseClicked() mouseEntered() mouseExited() mousePressed() mouseReleased() mouseDragged() mouseMoved() textValueChanged() FocusEvent ItemEvent KeyEvent MouseEvent FocusListener ItemListener KeyListener MouseListener MouseEvent TextEvent MouseMotionListener TextListener Pág 108 . Por exemplo.).event define uma interface específica para cada classe de evento. Um objeto que gera eventos (botão. A tabela a seguir lista algumas classes de eventos definidas no pacote java. o objeto que o gerou avisa todos os objetos ouvintes. Por exemplo. enquanto o outro modelo (versão 1.x e IE 4.0) é suportado pelos browsers mais antigos (Communicator 3. Para que este modelo funcione. Quando um evento ocorre. O pacote java.x e IE 3.x e 5. cada um destes tipos de evento corresponde a execução de um método diferente nos objetos ouvintes. Uma interface de ouvinte pode definir mais de um método.x). por exemplo) mantém uma lista de ouvintes que estão interessados em ser notificados quando os eventos ocorrerem e oferece métodos que permitem que objetos se “cadastrem” nesta lista de ouvintes. uma classe de eventos como MouseEvent representa vários tipos de eventos do mouse (botão pressionado. objetos ouvintes dos eventos da classe ActionEvent deve implementar a interface ActionListener. executando um método destes ouvintes e passando para eles um objeto da classe Event.x). todos os ouvintes de um tipo de evento devem implementar uma interface correspondente.event.awt.mais recentes (Communicator 4. O modelo de eventos é baseado no conceito de event listener (ouvinte de eventos). Um ouvinte de eventos é um objeto interessado em receber eventos. botão liberado. etc. a interface do objeto ouvinte correspondente.awt.

que é uma extensão do exemplo da seção . O applet a seguir. redimensionado. basta olhar a documentação da API da classe. Neste exemplo. portanto a classe Button gera eventos da classe ActionEvent. A tabela a seguir lista alguns widgets e os eventos que eles podem gerar: Widget Button CheckBox Choice Component Eventos que pode gerar ActionEvent ItemEvent ItemEvent ComponentEvent FocusEvent KeyEvent MouseEvent List ActionEvent ItemEvent Significado do evento Usuário clicou no botão Usuário selecionou ou de-selecionou um item Usuário selecionou ou de-selecionou um item O componente foi movido. ele possui um método chamado addXListener() para adicionar um ouvinte e um método chamado removeXListener() para remover um ouvinte. pesquisando na documentação. incrementa o conteúdo do text field do applet. Assim.). quando o usuário clicar o botão. deiconificada TextComponent TextEvent TextField ActionEvent Window WindowEvent Dica: Para descobrir quais eventos um widget pode gerar. Por exemplo. este objeto fonte é algum tipo de widget (botão. mostra como o modelo de eventos do Java funciona. o objeto ouvinte deve se registrar no objeto “fonte” dos eventos. iconificada. o mouse entrou ou saiu do componente ou o usuário moveu o mouse Usuário deu um clique duplo em um item da lista Usuário selecionou ou de-selecionou um item da lista Usuário alterou o texto Usuário terminou de editar o texto Janela foi aberta. O registro do objeto ouvinte segue esta convenção: se o objeto fonte gera eventos do tipo X. o applet se registra como um ouvinet dos eventos gerados pelo botão. Pág 109 . Este método. text field. por sua vez. escondido ou mostrado O componente ganhou ou perdeu o foco Usuário pressionou ou soltou uma tecla Usuário pressionou ou soltou o botão do mouse. um evento da classe ActionEvent é gerado e o método do applet ouvinte (actionPerformed()) será executado.WindowEvent WindowListener windowActivated() windowClosed() windowClosing() windowDeactivated() windowDeiconified() windowIconified() windowOpened() Depois de implementar os métodos da interface de eventos desejada. etc. fechada. No caso do AWT. podemos observar que a classe Button possui os métodos addActionListener() e removeActionListener().

public class MeuApplet extends Applet implements ActionListener { Button b.event. tf = new TextField("0").applet. se quisermos. import java. import java. decrementar o valor do text field caso o foco saia do botão temos que registrar o applet como um FocusListener dos eventos gerados pelo botão.import java.getText()).awt. O código a seguir mostra como isto pode ser feito: import java. é um evento associado ao Component.awt.*.parseInt(tf.*. // O applet é o ouvinte dos eventos do // tipo Action Event gerados pelo botão b. add(tf). // Muda o valor do text field tf. v = v+1.*. Assim.setText(String. TextField tf.*. } public void actionPerformed(ActionEvent e) { // Converte a string dentro do text field p/ um valor // inteiro int v = Integer. add(b). public void init() { b = new Button("Hit me").awt. todos os objetos do pacote AWT herdam os eventos de Component.valueOf(v)). por exemplo.*. na verdade. Pág 110 } .*. como o botão é uma subclasse de Component.awt.addActionListener(this). Entretanto.applet. Este tipo de evento (FocusEvent). import java. import java. podemos garantir que o botão também gera tais eventos.event. } Observação: como todos os widgets são subclasses de Component. public class MeuApplet extends Applet implements ActionListener.

parseInt(tf.FocusListener { Button b. v = v-1. } public void focusGained(FocusEvent e) { // Não faz nada quando o foco do mouse volta para o botão } } Pág 111 .parseInt(tf.valueOf(v)). // Muda o valor do text field tf.addActionListener(this). add(tf).addFocusListener(this).setText(String.setText(String. } public void actionPerformed(ActionEvent e) { // Converte a string dentro do text field p/ um valor // inteiro int v = Integer. TextField tf. public void init() { b = new Button("Hit me"). // Muda o valor do text field tf. } public void focusLost(FocusEvent e) { // Converte a string dentro do text field p/ um valor // inteiro int v = Integer.getText()). b. add(b). tf = new TextField("0"). // O applet é o ouvinte dos eventos do // tipo Action Event e Focus Event gerados pelo botão b.getText()). v = v+1.valueOf(v)).

Os componentes das posições North. } } O mesmo applet terá um layout diferente dependendo da largura e altura do seu container: <applet code=FlowLayoutTest. 7.awt. consequentemente.1 FlowLayout Um gerenciador da classe FlowLayout posiciona os widgets da esquerda para a direita até que não haja mais espaço na linha. para a classe Applet. South.4. Center onde os widgets podem ser colocados. East.Applet.*. Exemplo: import java. add(new Button("B2")). A partir daí. Pág 112 . de acordo com algum algoritmo. import java.class CODEBASE="/applets/magelang/AWTTraining/Examples/" width=150 height=35> </applet> <applet code=FlowLayoutTest. public class BorderLayoutTest extends Applet { public void init() { setLayout(new BorderLayout()). West são colocados na “borda” e os componentes na posição Center ocupam o espaço no centro. os objetos são colocados em uma linha abaixo. Exemplo: import java.class CODEBASE="/applets/magelang/AWTTraining/Examples/" width=50 height=90> </applet> 7.Applet.awt.2 BorderLayout A classe BorderLayout possui as posições North.7. Esta seção aborda alguns dos gerenciadores mais utilizados na prática. add(new Button("B3")). East. Este gerenciador é o default para a classe Panel e.4 Gerenciadores de Layout (Layout Managers) Um gerenciador de layout é um objeto que posiciona e redimensiona os componentes em um container AWT. // default add(new Button("B1")). West.applet. public class FlowLayoutTest extends Applet { public void init() { setLayout(new FlowLayout()). import java. South.*.applet.4.

lab.applet. Pág 113 . add("West".Applet { public void init() { Label lab = new Label("A Red Label").blue.new Button("QUIT")).add("North".Applet. add(new Button("3")). add("Center". o “grid” linha por linha. // lower right button } } 7.4. Por exemplo. } } Pode-se também definir a cor de um container. } } 7.new TextArea("Some random text\nin a TextArea")).*. add(new Button("4")). // uppper left button add(new Button("2")). Por exemplo.5 Cores e Fontes Widgets possuem cores de primeiro e segundo plano (foreground e backgorund).*. Pode-se criar objetos Color com parâmetros RGB (Red. import java.applet. add(lab). Exemplo: import java.2)). add(new Button("5")). new Button("HELP")). o primeiro elemento adicionado em um grid de 3 linhas x 2 colunas será o primeiro elemento da primeira linha. add(new Button("1")). Deve-se preencher. new Label("A Header Maybe")).awt.public class GridLayoutTest extends Applet { public void init() { setLayout(new GridLayout(3.setForeground(Color. add(new Button("6")).3 GridLayout A classe GridLayout posiciona os componentes em linhas e colunas. add("South". Green e Blue) ou HSV ou utilizar cores pré-definidas como Color. com widgets. Para definir estas cores utiliza-se o método setForeground e setBackground. todos os componentes adicionados ao container possuirão aquela cor.red). o applet abaixo mostra um label vermelho: import java.awt. public class ColorTest extends java. Color é uma classe que encapsula informações sobre cores. O terceiro elemento a ser adicionado será o primeiro elemento da segunda linha e assim por diante. Neste caso.new TextField("Type some text here")). add("East".red e Color.

10. basta usar: String[] fontList = Toolkit. esta opção deve ser impressa na área de texto Pág 114 . cujo texto inicial é Escreva Aqui. 12).6 Exercícios 1. Para obter uma lista de fontes disponíveis. Escreva um applet que possua um checkbox e um campo texto. 16). Mude o label do checkbox toda a vez que o usuário escrever no campo texto.*. A área de texto deve possuir cinco linhas. Em um applet que possui vários botões.event)? 4. g. Font. 11.BOLD. Qual é o único argumento do construtor da classe Button? 2. Quando o usuário clicar o botão.drawString("Helvetica 16 point Bold". Escreva um applet que possua um campo texto.awt. 6.setFont(f). Exemplo: import java.applet. g. Font.Applet { public void paint(Graphics g) { Font f = new Font("Helvetica". 30).BOLD. Quando o usuário selecionar uma opção.As fontes de um widget podem ser definidas pelo método setFont.getFontList(). Escreva um applet que mostra o texto Java é legal! 5. 13.awt. 7. Escreva um applet que mostre uma área de texto.EventObject que é a superclasse de todos os eventos do pacote java. 12. Escreva um applet que possua um checkboxgroup. Escreva um applet que possua uma lista e uma área de texto. o label deve mostrar o nome do botão. Escreva um applet que possua um botão chamado Enviar Mensagem. 9. Como se pode alterar o nome mostrado em um botão (pesquisar métodos da classe Button)? 3. Escreva um applet que mostra um checkbox com o texto Aperte Aqui. Escreva um applet que contenha um botão e um label. 8.getDefaultToolkit(). Escreva um applet que possua uma lista contendo o nome de cinco filmes. 10. Escreva um applet que contenha dois labels e dois botões organizados em duas linhas. Para criar um objeto Font: Font myFont = new Font("Helvetica".util. public class FontTest extends java. A lista deve possuir 10 opções. como é possível determinar qual botão foi pressionado (dica: pesquisar a classe java. Cada linha deve possuir um label seguido de um botão. } } 7. 14. Font é uma classe que armazena informações de uma fonte.

...8.applet.. Exemplo de um Applet Simples O código a seguir refere-se a um applet chamado Simple. Esta hierarquia é muito importante pois determina a maioria das tarefas que um applet pode fazer. ").. } Pág 115 . "). Este applet mostra uma string sempre que passa por um fato importante da sua “vida” como.Applet.1 Introdução Cada applet é implementado por uma subclasse da classe Applet. public class Simple extends Applet { StringBuffer buffer. } public void destroy() { addItem("preparing for unloading.Graphics. import java.. } public void start() { addItem("starting.awt. por exemplo.")... import java. Applets Esta seção apresenta os aspectos fundamentais relacionados ao desenvolvimento de applets Java. } public void stop() { addItem("stopping. A figura a seguir mostra a hierarquia de herança da classe Applet. que acompanha o kit de desenvolvimento Java. 8. Este exemplo será utilizado nas próximas seções para ilustrar conceitos comuns à maioria dos applets Java. a primeira vez que um usuário visita a página Web onde está o applet. addItem("initializing. como será mostrado nas próximas seções. public void init() { buffer = new StringBuffer(). ").

1.drawRect(0. public void init() { .1). por exemplo quando a página Web é vistada ou quando o usuário “restaura” a janela do browser. 15). eventos importantes na “vida” do applet. } O applet Simple.. .println(newWord). } public void destroy() { . . Nem todo applet precisa redefinir cada um destes métodos. . . //Draw the current string inside the rectangle. getSize(). apresentado na Pág 116 .x) não suportam tal versão.2 Ciclo de Vida de um Applet A classe Applet oferece uma série de métodos relacionados com a execução de applets.x e IE 3. • destroy: executado para realizar a “limpeza” final do applet antes de ser descarregado. Browsers mais antigos (Netscape 3. . por exemplo quando o usuário deixa a página ou minimiza o browser.out. .toString(). . .. 0. • start: executado ao iniciar a execução do applet.drawString(buffer.append(newWord). é uma subclasse de Applet. buffer. getSize().height . Por exemplo. 8. public class Simple extends Applet { .void addItem(String newWord) { System. A classe Simple redefine quatro métodos da classe Applet de tal forma que possa responder a estes eventos importantes: • init: executado cada vez que o applet é (re)carregado. } . repaint(). } public void stop() { . } public void paint(Graphics g) { //Draw a Rectangle around the applet's display area. o applet HelloWorld. } public void start() { . Alguns applets muito simples não redefinem nenhum destes métodos. definindo métodos que o sistema chama de “marcos” (milestones).width . } } Observação: Os exemplos de applet desta apostila utilizam a API da versão 1..1 do JDK. como qualquer outro applet. g. • stop: executado ao terminar a execução do applet. A maioria dos applets redefine estes métodos de acordo com suas necessidades. 5. Estes métodos são executados à medida que estes marcos vão acontecendo.. g.

O applet Simple define sua aparência na tela redefinindo o método paint: class Simple extends Applet { . usuário pressiona uma tecla). um applet que apresenta uma animação deve pará-la quando o usuário tiver “minimizado” a página. Em geral. O método start em geral é utilizado para iniciar uma ou mais threads que realizam alguma tarefa do applet. Por exemplo. os métodos para carregar imagens em um applet simplesmente não funcionam dentro do construtor do applet. De qualquer forma. o método init é o lugar ideal para executar os métodos que carregam imagens. ele apenas mostra uma string. Métodos de desenho referem-se a funções relacionadas a apresentação do applet na tela: desenhando imagens ou mostrando uma interface gráfica (botões. Muitos applets implementam o método paint para desenhar a representação do applet na página Web. Muitos applets não redefinem o método destroy pois o método stop (que é chamado antes do destroy) faz todo o trabalho necessário para finalizar a execução do applet. . o método init deve conter o código que normalmente seria colocado em um construtor. } . A maioria dos applets que redefinem o método start também devem redefinir o método stop. Por outro lado. apresentado na seção 7. etc. utilizando o método paint. Por exemplo. Tratamento de eventos refere-se a detecção e processamento de eventos de entrada (por exemplo. O pacote AWT. O método stop deve suspender a execução das threads do applet a fim de liberar recursos quando o applet não estiver sendo visto pelo usuário. 8. Pág 117 . O motivo pelo qual applets não devem possuir construtores é que um applet não tem garantias que o ambiente de execução (browser) está pronto até que o método init seja executado.3 Métodos Utilizados para Desenho e Tratamento de Eventos Applets herdam os métodos de desenho e de tratamento de eventos da classe Component do pacote AWT (Abstract Windowing Toolkit).seção 1.).. public void paint(Graphics g) { . usuário clica no mouse.. destroy pode ser utilizado por applets que querem liberar outros recursos. • update: um método que pode ser utilizado junto com o paint para melhorar o desempenho do applet. O método init é útil para realizar inicializações que não demorem muito. é utilizado pelos applets (e aplicações stand-alone) para implementar interfaces gráficas.. check-box. .. não redefine estes métodos. } O método paint é um dos dois métodos de apresentação que um applet pode redefinir: • paint: o método de apresentação básico.

"foto. passando como parâmetros um objeto da classe Image. 8. Podemos imaginar esta classe como um “apontador” de imagens.jpg").drawImage(im. 15. public class MostraImagem extends Applet { Image im. Também é obrigatória a Pág 118 . this).Applet. os parâmetros width e height definem a largura e altura do applet. Para desenhar a imagem. respectivamente. public void init() { im = getImage(getCodeBase().4 Mostrando Imagens Dentro de um Applet Para exibir imagens dentro de um applet.5 Adicionando um Applet a uma Página HTML Para incluir um applet em uma página HTML basta utilizar a tag HTML <applet>. Os parâmetros desta função são a URL onde está localizada a imagem e o nome do arquivo da imagem. por sua vez.awt. herda os métodos da classe Component do AWT. O modelo de eventos do Java (1. 10.1) foi apresentado na seção 7. import java.class” width=120 height=120> </applet> A tag <applet> possui alguns atributos: code é o nome do arquivo que contém os bytecodes do applet (. além do tamanho e da largura da imagem. A classe Applet possui um método chamado getImage que serve para carregar imagens (nos formatos JPEG ou GIF). utilizamos a classe abstrata Image. Por exemplo: import java. Estes três parâmetros são obrigatórios. } } 8.applet.class). } public void paint(Graphics g) { g. Exemplo: <applet code=”MeuApplet. do pacote AWT.*.Applets herdam os métodos paint e update da classe Applet que. utilizamos o método drawImage da classe Graphics.

awt.event. dependendo do item escolhido.ItemListener e utilizar o método repaint(). mostre uma imagem diferente.tag </applet>. Pág 119 . Dica: o applet deve implementar a interface java. É possível executar um applet sem possuir um browser compatível com Java? 3. Qual a sua finalidade? 4. Quais são os três atributos obrigatórios da tag <applet>. opcionais. A tag <applet> possui outros atributos. Desenvolva um applet que possua uma lista de seleção (classe Choice) e que. 8. O que é o ciclo de vida de um applet? Quais métodos do applet são invocados durante seu ciclo de vida? 2. que não serão abordados nesta seção. Este arquivo HTML pode ser visualizado por meio de um browser compatível com Java ou utilizando a ferramenta do JDK chamada appletviewer.6 Exercícios 1.

Uma thread é similar aos programas sequenciais descritos acima. também apenas uma única instrução está sendo executada. dentro de uma thread. 9. Threads Threads são uma podersosa ferramenta que permite realizar mais de uma tarefa “simultaneamente” em um mesmo processo (programa em execução). Uma única thread tem um começo. Esta seção apresenta o suporte da linguagem Java para programação envolvendo várias threads. Entretando. A figura a seguir ilustra esta idéia: Um browser é um exemplo de uma aplicação com várias threads (multithreaded). A figura a seguir mostra este relacionamento: Observe que não há nada de novo no conceito de uma única thread. é um fluxo de controle dentro de um programa. A grande novidade do conceito de threads é a possibilidade de utilizar várias threads dentro de um mesmo programa (processo). uma thread não é um programa (processo).9. toca uma música ou imprime a página. também chamada de contexto de execução ou processo leve. uma thread deve existir dentro de um programa (processo). estão acostumados em escrever programas seqüenciais. Dentro de um browser é possível fazer um “scroll” da página. não pode ser executada isoladamente. durante a execução do programa. Todos os programadores. uma sequência de execução e um fim. enquanto o browser carrega uma imagem. executando ao mesmo tempo e realizando tarefas distintas. Em qualquer instante.1 O que é uma Thread Uma thread. Pág 120 . Em qualquer instante. Estes programas seqüenciais possuem um início. independente da linguagem. uma única instrução está sendo executada. Na verdade. ou seja. uma seqüência de execução e um fim.

9.2

Utilizando o Método run de uma Thread

O método run de uma thread permite que esta realize alguma tarefa. O código deste método implementa o comportamento da thread. A thread pode fazer tudo que pode ser implementado na linguagem Java: calcular um expressão matemática, ordenar alguns dados, realizar alguma animação, etc. A classe Thread implementa uma thread genérica que, por default, não faz nada. Ou seja, a implementação do método run é vazia. Existem duas maneiras de implementar o método run de uma thread, descritas nas seções a seguir. 9.2.1 Criando uma Subclasse de Thread e Redefinindo o Método run

A primeira maneira possível de desenvolver uma thread é criando uma subclasse de Thread e redefinindo o seu método (vazio) run. O exemplo a seguir faz justamente isto: public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep(1000)); } catch (InterruptedException e) {} } System.out.println("ACABOU! " + getName()); } } O primeiro método da classe SimpleThread é o construtor. O parâmetro do construtor é uma String que corresponde ao nome da thread. Este parâmetro é repassado para o construtor da classe Thread. O próximo método da classe é o run. O método run é o “coração” de qualquer thread, é neste método que se determina o que a thread vai fazer. No nosso exemplo, a thread irá executar um laço (10 vezes). A cada iteração do laço, o método vai mostrar o número da iteração e o nome da thread e vai “dormir” (método sleep) por 1 segundo. Depois que o laço terminar, o método run irá imprimir ACABOU! junto com o nome da thread. A classe a seguir, TwoThreadTest, define um método main que cria dois objetos SimpleThread: um com nome “Chocolate” e outro com o nome de “Sorvete”. public class TwoThreadsTest { public static void main (String[] args) { Pág 121

new SimpleThread("Chocolate”).start(); new SimpleThread("Sorvete").start(); } } O método main também inicia cada thread, imediatamente após a sua criação, executando o método start. Ao executar esta classe, teremos uma saída parecida com esta: 0 Chocolate 0 Sorvete 1 Chocolate 1 Sorvete 2 Chocolate 2 Sorvete 3 Chocolate 3 Sorvete 4 Chocolate 4 Sorvete 5 Chocolate 5 Sorvete 6 Chocolate 6 Sorvete 7 Chocolate 7 Sorvete 8 Chocolate 8 Sorvete 9 Chocolate 9 Sorvete ACABOU! Chocolate ACABOU! Sorvete Observe que as saídas das threads estão intercaladas, isto porque cada objeto SimpleThread está sendo executado simultaneamente. 9.2.2 Implementando a Interface Runnable

Outra forma de desenvolver threads é implementar a interface Runnable que define o método run. Adaptando o exemplo da seção anterior, temos: public class SimpleThread implements Runnable { String nome; public SimpleThread(String str) { nome = str; } Pág 122

public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + nome); try { Thread.sleep(1000); } catch (InterruptedException e) {} } System.out.println("ACABOU! " + nome); } } Observe que agora SimpleThread não é uma subclasse de Thread e, portanto, não pode mais executar o construtor e o método getName desta classe. Para executar o método sleep, que também pertence a classe Thread, devemos colocar agora o nome da classe pois tal método é estático (ou seja, é um método de classe e pode ser executado sem termos que instanciar um objeto da classe Thread). A classe TwoThreadsTest também deve sofrer uma modificação: para executar as threads devemos chamar o construtor da classe Thread, passando como parâmetro um objeto da classe SimpleThread (que implementa a interface Runnable). public class TwoThreadsTest { public static void main (String[] args) { SimpleThread t1 = new SimpleThread("Chocolate"); SimpleThread t2 = new SimpleThread("Sorvete"); new Thread(t1).start(); new Thread(t2).start(); } } Regra básica: Em geral, se a thread (classe) que você está desenvolvendo deve ser subclasse de uma outra (Applet, por exemplo) utiliza-se a técnica descrita nesta seção. Caso contrário, podemos utilizar a maneira descrita na seção anterior. 9.3 Ciclo de Vida de uma Thread

O diagrama a seguir mostra os estados em que uma thread pode estar durante o seu ciclo de vida. A figura também mostra quais métodos causam uma transição para outros estados.

Pág 123

nenhum recurso do sistema (memória.1 Criando uma Thread Para criar uma thread. O método start reserva os recursos do sistema necessários para que a thread possa ser executada e executa o método run da thread. Pág 124 . a thread fica no estado “New Thread” (ver figura acima). Assim. mesmo que o processador esteja disponível. 9. ou seja. Neste estado. Muitos computadores possuem um único processador. Enquanto a thread está neste estado. a thread está executando (running). deve-se executar o método start. processamento) foi reservado para a thread. é impossível executar mais de uma thread ao mesmo tempo. ela não é executada. 9. utiliza-se o construtor da classe.3 Tirando uma Thread do Estado Runnable Uma thread vai para o estado “not runnable” quando um destes eventos ocorre: • O método sleep é executado • A thread executa o método wait. uma thread no estado runnable pode estar. o conceito é um pouco mais complexo: a thread está em um estado “executável” (runnable). Depois da execução do método start. Na verdade. esperando a sua vez de utilizar a CPU. relacionados com as 3 situações descritas acima.9.3.3. Obviamente.3.2 Iniciando uma Thread Para iniciar uma thread que está no estado “New Thread”. como para qualquer outro objeto. que retiram a thread do estado “Not runnable”. O que ocorre é um escalonamento entre as threads para permitir o compartilhamento do processador da máquina. temos uma thread “vazia” . na verdade. existem eventos. Após executar o construtor. esperando que uma determinada condição seja satisfeita • A thread está bloqueada esperando E/S de dados.

temos uma thread que imprime os valores 0 a 49 (método imprimeValor). existem situações onde as threads podem compartilhar dados. imagine uma aplicação Java onde uma thread (produtora) escreve dados em um arquivo enquanto uma outra thread (consumidor) lê os dados do mesmo arquivo. variável. Por exemplo. A maneira mais simples.println(i + " " + getName()). Sempre que duas ou mais threads compartilham algum recurso (arquivo. é a utilização de métodos synchronized. Adaptando o exemplo da seção . apresentada nesta seção. i++) System. a thread “morre” e os recursos do sistema reservados para ela são liberados.3. As threads que desejarem executar este método. Ou seja. } public void run() { imprimeValor().9. i < 50. } public static void imprimeValor() { for (int i = 0.4 Sincronização de Threads Até agora. 9.4 Terminando com uma Thread A thread termina a sua execução quando o método run termina. Existem várias formas de sincronizar threads. public class SimpleThread extends Thread { public SimpleThread(String str) { super(str). cada thread contém todos os dados e métodos necessários para a sua execução e não precisa de recursos ou métodos externos. } } Se executarmos a classe TwoThreadsTest. Entretanto. temos visto exemplos de threads independentes. Após o fim deste método. ficarão bloqueadas até que este retorne.out. nenhuma outra thread pode executar este mesmo método. teremos uma saída parecida com esta: 0 1 2 0 1 3 .) deve-se sincronizá-las de alguma forma. etc. Este mecanismo garante que enquanto uma thread estiver executando um método synchronized. Pág 125 .

aguardando que a outra thread termine de executar o método imprimeValor. teremos a seguinte saída: 0 1 2 3 . Ainda com relação ao exemplo da seção . apenas um destes métodos do objeto pode ser executado por uma thread em um determinado instante. .. Mostre o valor da variável na tela. Entretanto. o método imprimeValor só pode ser executado por uma thread. 3.. Pág 126 . Explique o que significam métodos synchronized e qual a sua finalidade.5 Exercícios 1. 4. Desta forma.. Assim uma das threads fica bloqueada. Isto ocorre pois as threads estão executando “simultaneamente” o método imprimeValor. Crie uma terceira thread. Esta técnica de sincronização pode ser utilizada para organizar o compartilhamento de recursos entre as threads (por exemplo. devemos defini-lo com synchronized: public synchronized static void imprimeValor() { .. Ou seja. Qual é a nova saída do programa? 2. em aplicações produtor x consumidor). a variável não deve ser decrementada. se uma classe define dois ou mais métodos synchronized.. 9. 49 0 1 2 3 . agora. 49 Isto ocorre pois... Se quisermos que apenas uma thread execute este método em um dado instante. Uma deve incrementar uma variável e outra decrementar. a thread que faz o decremento deve verificar se o valor da variável é positivo. Crie um programa que possua duas threads. chamada biscoito. Observação: na verdade. o mecanismo synchronized é válido por objeto. no programa mostrado na seção . se não for. o que acontece se tiramos a instrução sleep(1000) do método run das threads? Qual será a saída do programa? Explique este novo comportamento do programa..

1 Introdução Em Java.10. Os construtores destas classes têm como parâmetro Pág 127 . Leitura abrir um stream enquanto houver mais informação ler informação fechar o stream Escrita abrir um stream enquanto houver mais informação escrever informação fechar o stream O pacote java. os algoritmos de leitura e escrita. por exemplo. para buscar informações. um programa pode enviar informações para um destino externo abrindo um stream para este destino e escrevendo a informação sequencialmente: Importante: não importa de onde a informação vem nem para onde está indo.2 Leitura e Escrita de Arquivos Para realizar a leitura e escrita de arquivos utilizamos as classes FileInputStream e FileOutputStream. Esta seção mostra alguns exemplos de como realizar esta troca de informação. em algum lugar da rede ou em outro programa. 10. são sempre os mesmos. descritos acima. Nas seções a seguir. Entrada e Saída Muitas vezes. serão apresentadas algumas destas classes. as aplicações necessitam buscar informações de uma fonte externa ou enviar dados para um destino externo. 10. também não importa qual o tipo de dado que está sendo lido ou escrito. por exemplo) e ler a informação de maneira sequencial: Analogamente.io contém uma grande coleção de classes que representam vários tipos de canais (streams). respectivamente. A informação pode estar em vários lugares: em um arquivo. um programa deve abrir um stream (canal) para a fonte de informação (um arquivo.

FileOutputStream out = new FileOutputStream(outputFile).txt"). o programa realiza um laço onde faz uma leitura do FileInputStream (método read .txt"). BufferedReader. while ((c = in. in.io. Depois. } } Inicialmente. porém utiliza outras classes: import java. public class CopyBytes { public static void main(String[] args) throws IOException { File inputFile = new File("oi.close(). um da classe FileInputStream (para a leitura de dados) e FileOutputStream (para a escrita de dados).txt"). O exemplo a seguir também realiza a cópia de um arquivo para outro.io.o construtor desta classe tem como parâmetro o nome do arquivo.read()) != -1) out. Para manipular mais facilmente texto (strings) podemos utilizar as classes FileReader. BufferedReader in = new BufferedReader(inputFile). FileInputStream e FileOutputStream são adequadas para escrever dados binários (bytes). O exemplo abaixo realiza a cópia dos dados de um arquivo para outro: import java. são criados os dois streams. Pág 128 . FileWriter e PrintWriter. File outputFile = new File("ola. public class CopyBytes { public static void main(String[] args) throws IOException { FileReader inputFile = new FileReader("oi.txt"). out. int c. as duas streams são fechadas (método close). A classe File representa um arquivo . Então. FileWriter outputFile = new FileWriter("ola.quando este método retorna -1 significa que se chegou ao fim do arquivo). FileInputStream in = new FileInputStream(inputFile).um objeto da classe File.*.close().write(c). Finalmente. Cada dado lido é escrito no FileOutputStream (método write). o programa cria dois objetos da classe File que representam os arquivos de entrada e saída do programa.*.

in. armazena-as em duas variáveis e as exibe na tela: import java. while ((s = in. devemos criar um objeto da classe BufferedReader que possui o método readLine.io. Já para ler algum valor do teclado.close().println(s). BufferedReader ent = new BufferedReader(new InputStreamReader(System.readLine().readLine()) != null) out.flush(). Pág 129 .close(). String s.print("Digite um valor: "). public class Eco { public static void main(String[] args) throws IOException { String a. a = ent. Note que é necessário executar o método flush do objeto PrintWriter para que os dados sejam efetivamente escritos no arquivo de saída. out.lang possui três variáveis stream que representam: • A entrada padrão do sistema (normalmente o teclado): in • A saída padrão do sistema (normalmente o monitor): out • A saída de erro padrão do sistema (normalmente o monitor): err A variável in é da classe InputStream e as variáveis out e err são da classe PrintStream. Para imprimir strings na saída padrão utilizamos os métodos print ou println.3 Entrada e Saída de Dados (Padrão) A classe System do pacote java. out.PrintWriter out = new PrintWriter(outputFile).x. System. 10. } } A diferença principal com relação ao exemplo anterior é que neste programa fazemos a leitura e a escrita de linhas de texto (métodos readLine e println).*.in)). O programa a seguir lê duas strings.out.

out.out.close(). 2. System.readLine(). Pág 130 . ent.print("Digite outro valor: ").4 Exercícios 1.println("Você digitou: " + a + " " + x). x = ent. Faça um programa que leia dez strings que estão em um arquivo texto e que as exiba na tela. Faça um programa que leia dez strings digitadas pelo usuário e que escreva estas strings em um arquivo.System. } } 10.

Sign up to vote on this title
UsefulNot useful