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

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

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

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

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

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

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

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

é a fundação (base) da plataforma Java e já existem implementações da JVM para diversas plataformas de hardware/software. presente em uma ferramenta de desenvolvimento ou em um browser. 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. JVM). o mesmo programa Java pode executar em Windows NT. Pode-se compilar os programas Java em qualquer plataforma que possuir um compilador Java.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. Assim. O conceito de bytecodes auxilia a tornar o lema “write once. apenas) que executa sobre outras plataformas baseadas em hardware e software (sistema operacional). é uma implementação da JVM. Todo interpretador Java.5. API) A Máquina Virtual Java. 1. Pág 11 . A plataforma Java difere da maioria das outras pelo fato de ser uma plataforma (de software.Pode-se imaginar os bytecodes como a “linguagem assembly” da Máquina Virtual Java (Java Virtual Machine. A JVM também pode ser implementada diretamente em hardware. Solaris e Macintosh sem a necessidade de recompilação (figura a seguir).

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

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

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

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

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

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

é um modelo ideal que deve servir de como meta para projetistas de sistemas orientados a objetos. Por exemplo. Os métodos envolvem e escondem o núcleo do objeto de outros componentes (objetos) da aplicação. 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). aumentar a velocidade da pedalagem e trocar de marcha. apenas saber qual método deve ser invocado. Pág 18 . um objeto pode desejar expor algumas de suas variáveis ou esconder alguns de seus métodos. quando se deseja trocar uma marcha na sua bicicleta. muitas vezes não é necessário saber como um objeto foi implementado. Analogamente. um objeto sozinho não é muito útil e aparece como um componente de uma aplicação maior que contém vários outros objetos. um objeto que modela uma bicicleta poderia ter variáveis que indicam seu o estado atual: velocidade é 20 km/h. a encapsulação é usada para esconder detalhes de implementação pouco importantes. A interação entre os objetos é que permite se obter todas as funcionalidades de uma aplicação. um núcleo de variáveis dentro de uma membrana protetora de métodos. uma bicicleta só é útil quando um outro objeto (ciclista) interage com ela. Quando um objeto A deseja que o objeto B realize um dos seus métodos (de B). Entretanto. Muitas vezes.1. Exemplos de métodos deste objeto seriam: frear. os detalhes de implementação podem ser mudados sem afetar outras partes do programa. marcha atual é a quinta. em programas. o objeto A envia uma mensagem para o objeto B. Esta representação conceitual de um objeto. esta representação não é totalmente realista. Basicamente. Objetos comunicam-se entre si por meio do envio de mensagens. Empacotar as variáveis de um objeto sobre a proteção de seus métodos é chamado de encapsulação (seção ). apenas qual alavanca deve ser movida. 2. As variáveis de um objeto fazem parte do seu núcleo (centro). Por exemplo.2 Mensagens Geralmente. 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). Por exemplo. não é preciso saber como o mecanismo de troca de marchas funciona. Assim.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. por razões de implementação ou eficiência.

o estado de cada bicicleta é independente e pode ser diferente de outras bicicletas. deve-se instanciá-la a fim de utilizar seus objetos. Pág 19 . depois de criar a classe bicicleta. pode-se tirar vantagem de que os objetos do mesmo tipo são similares e criar uma “fôrma” para estes objetos. Quando se cria uma instância de uma classe. Bicicletas possuem estado e comportamento comuns. Assim. Entretanto. Valores de variáveis de instância existem para cada instância (objeto) da classe. Resumindo.3 Classes No mundo real. Assim. 2. Esta informação acompanha a mensagem como um parâmetro. Depois de criado. uma classe é uma fôrma (protótipo) que define as variáveis e métodos comuns a todos os objetos de um certo tipo.1. cria-se um objeto daquele tipo e o sistema aloca memória para as variáveis de instância definidas para a classe. pode-se invocar os métodos de instância do objeto. 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. muitas vezes existem vários objetos do mesmo tipo. Tais fôrmas de software são chamadas de classes . utilizando a terminologia de orientação a objetos. deve-se indicar qual a marcha desejada. quando você quer trocar as marchas em uma bicicleta. Por exemplo. Desta forma. Em software orientado a objetos. pode-se dizer que um objeto bicicleta é uma instância de uma classe de objetos conhecida como bicicletas. o objeto que recebe a mensagem precisa de mais informações para saber exatamente o que fazer. é possível ter vários objetos do mesmo tipo que compartilham características.Mensagem Objeto A Objeto B Algumas vezes. Por exemplo.

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

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

• Subclasses oferecem comportamentos especializados a partir de elementos básicos comuns. onde ContaEspecial é uma subclasse de Conta. entenda-se a escolha correta de um método a ser executado para uma variável declarada como de uma classe. Devido às características de herança. 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. ContaEspecial conta_especial_do_joao. Assim: Conta conta_normal_do_joao..retirada(). contas_do_cliente[1] = conta_especial_do_joao. Suponha que exista um método do Conta (retirada()). entenda-se tempo de execução. 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. 2. Outro tipo bastante interessante de polimorfismo é conhecido como acoplamento dinâmico (dynamic binding).2. Se a subclasse oferece um método de assinatura (nome. que foi redefinido por ContaEspecial. oferecidos pela superclasse. . Com o acoplamento dinâmico. Este polimorfismo é classificado como polimorfismo de inclusão. Por meio da utilização de herança. na verdade. O primeiro tipo. Existem vários tipos de polimorfismo. // O interpretador invoca o método de ContaEspecial Pág 22 . programadores podem reusar o código da superclasse várias vezes. pode-se atribuir um objeto de uma subclasse a uma variável da classe pai (mas não o contrário!). contas_do_cliente[0] = conta_normal_do_joao. descrito no item anterior. mas que pode conter um objeto de uma subclasse desta. // O interpretador invoca o método de Conta contas_do_cliente[1].retirada(). contas_do_cliente[0]. é possível fazer com que a execução de um método dependa do tipo do objeto atribuído a variável. • Programadores podem definir classes abstratas que determinam comportamentos “genéricos”. 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. Por dinâmico.. Outros programadores completam estes detalhes por meio de subclasses especializadas. é quando uma classe redefine a implementação de um método herdado. Conta contas_do_cliente[20] . Por acoplamento. Por exemplo: Sejam duas classes Conta e ContaEspecial..3 Polimorfismo Segundo a terminologia de orientação a objetos.. um novo método.

Tente definir também subclasses Pág 23 . 5 Considere um objeto do mundo real.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. Liste as variáveis e métodos deste objeto. como um aparelho de som ou um forno.2.

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

incremento = 5. a API de manipulação de Strings torna a representação de caracteres totalmente transparente para o programador.5 Sem Variáveis Globais Variáveis globais simplesmente não fazem parte da linguagem. Em Java. separados por ponto. Pág 25 . Assim. MeuObjeto. toda variável e método deve ser declarada dentro de uma classe. que consiste do nome do pacote que contém a classe. não há como distinguir um caracter Java de 16 bits de caracteres de 8 bits convencionais.contador = 1. Também não existem funções ou procedimentos “globais”. #ifdef e nem typedef. Strings e identificadores (nomes de variáveis. chamados de Unicode (C/C++ utilizam caracteres de 8 bits.1. no formato ASCII). MinhaClasse. os arquivos-fonte em Java possuem simplesmente as declarações das suas classes e métodos. Exemplos: MinhaClasse MeuObjeto. 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.MostraIncremento(). #include. 3. métodos e classes) são compostos de caracteres de 16 bits. 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. Isto facilita a migração de programas Java para outros idiomas diferentes do inglês. MeuObjeto. Java elimina a necessidade de arquivos de cabeçalhos (headers files). 3.Incrementar().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. Além disto. o nome da classe (ou objeto) e o nome do membro (variável ou método) da classe. Em vez de cabeçalhos. não existem diretivas como #define.3.1. MinhaClasse. toda variável (método) em Java deve ser referenciado pelo seu nome qualificado. um programador Tailândes pode usar o alfabeto Thai para nomear variáveis e métodos no seu código-fonte. Por exemplo.4 Caracteres Unicode Caracteres. Assim. ele sabe exatamente onde encontrá-lo. Assim. Assim. todos os #defines e typedefs. 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).1. se você estiver utilizando apenas caracteres Latin-1.

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

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

println("Usage: Count filename"). determina seu escopo.err.length >= 1) countChars(new FileReader(args[0])). onde a declaração aparece em relação a outros elementos do código. de entrada de caracteres) e mostra o número de caracteres lidos. 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.io.*. 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. Por exemplo.").1 Variáveis e Tipos de Dados Todas as variáveis em Java possuem um tipo. } public static void main(String[] args) throws Exception { if (args./) sobre este tipo de variável. while (in. Reader in A declaração de uma variável sempre contém dois componentes: o tipo da variável e seu nome. nome e escopo. 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. stream.4.out.*. A localização de uma declaração de variável. Inteiros só podem possuir valores integrais (positivos ou negativos) e pode-se utilizar os operadores aritméticos (+. import java. System. 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. else System. ou seja. } } 4. o método countChars define duas variáveis: int count = 0. Pág 28 . Por exemplo.read() != -1) count++.-.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

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

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

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

De maneira geral.read() != -1) count++.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 . Por exemplo: while (in. 4. pode ser um bloco de código Java delimitado por chaves { }.out. Um statement. A sintaxe geral do while é: while (expression) statement Ou seja. o while realiza alguma ação enquanto uma certa condição continua verdadeira. A linguagem Java suporta vários tipos de controle de fluxo. Os operadores de atribuição são avaliados da direita para a esquerda. incluindo: Pág 37 . enquanto a expressão for verdadeira. execute statement. } Convenção: a chave { deve ficar no final da mesma linha que o while e a chave } deve começar uma nova linha. todos os operadores binários (exceto o operador de atribuição) são avaliados da esquerda para a direita. Em Java. algumas regras devem determinar qual deve ser avaliado primeiro. ou seja. Count = " + count).read() != -1) { count++.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. while é chamado de um comando de controle de fluxo. determina a ordem de execução do código. System. na verdade. alinhada com o while.println("Read a character.

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

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

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

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

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

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

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

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

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

1).y = y. Assim. this. a variável origin cria um objeto SimplePoint utilizando: new SimplePoint(). ao criar um ponto. As classes SimplePoint e SimpleRectangle são implementações simplificadas. Poderia-se criar um mecanismo para inicializar suas variáveis com valores diferentes de 0. a seguir. } } Agora. como ilustrado a seguir: Esta figura mostra a diferença entre tipos primitivos e tipos de referência (seção 4. // a constructor! public Point(int x. Tanto width quanto height são inteiros e estão inteiramente contidos dentro de SimpleRectangle.Como no exemplo anterior. 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 . public int y = 0. pode-se definir valores iniciais: new Point(44.x = x. a criação de um objeto do tipo SimpleRectangle aloca memória para as suas variáveis. int y) { this. Neste caso. tem-se uma nova versão de SimplePoint. 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.0): public class Point { public int x = 0. Por outro lado. origin simplesmente referencia um objeto SimplePoint que está em outro lugar.

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

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

que não faz nada. largura e altura. Desta forma. estes devem possuir um número diferente de argumentos e/ou argumentos de tipos distintos. em situações práticas. 5. Portanto. o compilador é capaz de determinar qual construtor deve ser invocado. 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. Executando (invocando) seus métodos Como já foi discutido. Manipulando ou inspecionando as suas variáveis 2. é razoável. Assim.public Rectangle(Point p) public Rectangle(int w. int h) public Rectangle() Cada um destes construtores permite se definir valores iniciais para diferentes aspectos do retângulo: a origem. então. As classes Point e Rectangle permitem livre acesso a suas variáveis. Um objeto “ideal” oferece métodos pelos quais se consegue inspecionar ou modificar o seu estado. Um construtor que não possui argumentos é chamado de construtor default. origem. a largura e a altura. 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). assumir que não há problemas em se inspecionar/modificar tais variáveis. algumas vezes faz sentido utilizar diretamente as variáveis de um objeto. Se uma classe (como SimplePoint e SimpleRectangle. corre-se o risco de colocar o objeto em um estado inconsistente.2 Utilizando Objetos Pode-se utilizar um objeto de duas maneiras: 1. Estes métodos garantem que um objeto nunca entrará em um estado inconsistente. ou nenhum valor. é Pág 50 . 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?). Se um objeto oferece acesso a suas variáveis. int h) public Rectangle(Point p. Assim.2. Se uma classe possui vários construtores. a linguagem Java automaticamente oferece um construtor sem argumentos. a programação orientada a objetos desencoraja a manipulação direta das variáveis de um objeto. Tais modificações devem ser realizadas por meio de métodos. Entretanto. 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. int w. vistas no começo da seção) não definir explicitamente um construtor. Por exemplo. é correto afirmar que todas as classes possuem pelo menos um construtor.

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

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

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. Durante a finalização.3. o método finalize da classe Rectangle libera o objeto Point. Depois que todos os caminhos para os objetos são investigados. Por exemplo. super. Note que o Pág 53 .preocupar em destruí-los. o coletor roda sincronamente quando o sistema fica sem memória disponível ou quando um programa Java requisita. Este processo é chamado de finalização. atribuindo null a variável que o referenciava (origin): protected void finalize() throws Throwable { origin = null. Um objeto está sujeito a coleta de lixo quando não existem mais referências para ele. 5.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. O ambiente de execução Java (JVM) remove os objetos quando percebe que eles não são mais utilizados. O coletor de lixo é uma thread que executa com baixa prioridade de forma síncrona ou assíncrona. quando o sistema está ocioso. A classe Object fica no topo da hierarquia de classes de Java e é “pai” de todo mundo. Este processo é denominado de coleta de lixo (garbage collection). Por exemplo. } O método finalize é um membro da classe Object. Assim que uma outra thread torna-se ativa. não mais referenciados) são considerados como lixo e então são “coletados” (liberando a memória alocada para aqueles objetos). dependendo da situação e do sistema onde Java está rodando. O coletor de lixo executa assincronamente. Uma classe deve redefinir o método finalize para realizar as finalizações necessárias para os objetos daquele tipo.finalize().3. 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). a sua execução. em sistema como o Windows 95/NT. 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. objetos não marcados (ou seja.2 Finalização Antes que um objeto seja “coletado”. 5. explicitamente. o coletor de lixo termina a sua execução.

Para isto. Stack impõe as restrições de uma estrutura LIFO ao objeto Vector. Vector. vamos analisar cada uma das estruturas da figura acima. A seguir. ou seja. LIFO).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). Entretanto. Pág 54 . será apresentado um pequeno exemplo que implementa uma pilha (last-in-first-out.método finalize de Rectangle executa o método super. A figura a seguir lista a classe e identifica a estrutura do código. para armazenar os seus elementos. 5. pode-se apenas remover (adicionar) elementos do (ao) topo da pilha. A classe Stack usa então um objeto da classe Vector para armazenar seus elementos. Esta implementação de uma pilha utiliza um outro objeto. 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.4 Criando Classes Esta seção mostra como escrever classes a partir das quais objetos são criados.

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

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

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

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

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

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

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

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

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

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

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

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

público (public) e o nível default. pode-se utilizar especificadores de acesso (access especifiers) para proteger tanto variáveis quanto os métodos de uma classe.aMethod().out. Depois. 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. Este controle é definido na própria declaração da variável (ou método). Então o método aMethod imprime as duas versões de aVariable. aMethod() invoca o método da superclasse: super.println(super.aVariable). pacote (package). super. A linguagem Java suporta quatro níveis de acesso distintos: privado (private). 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 . protegido (protected). aMethod() atribui a variável aVariable (que oculta a variável declarada na superclasse) o valor false. Tal característica é denominada de encapsulação.aMethod(). void aMethod() { aVariable = false.} } class ASillierClass extends ASillyClass { boolean aVariable. Isto faz com que a versão oculta de aVariable (aquela que foi declarada na superclasse ASillyClass) receba o valor true. Em Java.out. System. que possuem diferentes valores: false true 5.6 Controle de Acesso a Membros da Classe Como visto na seção 2. System. } } Primeiramente.4.println(aVariable).

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

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

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

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

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

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

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

Estas exceções devem ser sempre tratadas pelo código do seu programa. o código do bloco catch é ignorado. Caso ocorra uma exceção em algum ponto do bloco. caso contrário ocorrerá um erro de compilação. Este método. se nenhuma exceção for gerada. O parâmetro de catch é o tipo de exceção a ser capturada (tal como o argumento de um método). pode realizar o tratamento de exceção (via try e catch) ou “repassá-la” utilizando throws.println(“Exceção !!!”). se existirem. Por outro lado. a. Para um mesmo bloco try podem existir mais de um bloco catch (cada um capturando um determinado tipo de exceção). o restante do código é ignorado e o fluxo de controle do programa “salta” para o bloco catch.out. Pode-se “passar para a frente” a exceção. Pode-se acessar os métodos. Todo o código que pode levantar uma exceção é colocado em um bloco try. por sua vez. da exceção por meio deste argumento. 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.metodoQuePodeGerarUmaExcecao(). utiliza-se as cláusulas try e catch. Tal exceção não será tratada por GetURL e sim enviada para o método que invocou GetURL. A linguagem Java define várias exceções (objetos) que podem ser geradas pelos métodos das classes de sua API. 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 . } catch (Excecao e) { System. } Para capturar uma exceção. Observação: não é necessário realizar o tratamento de exceção no mesmo método onde ela foi levantada. utilizando-se a palavra-chave throws: protected void GetURL() throws MalformedURLException No exemplo acima. dentro do método GetURL pode ser levantada uma exceção (MalformedURLException).try { a.outroMetodo().

x = x. } O código acima é válido? É possível criar classes sem construtores? Como Java trata esta questão? Pág 76 . public void UmaClasse(int a) { x = a. 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. Agora. } } O código acima é válido? Justique. 5. 2.5 Exercícios 1.FileNotFoundException IOException NullPointerException NumberFormatException OutOfMemoryException SecurityException StackOverflowException StringIndexOutOfBounds Exception Caused by an attempt to access a nonexistent file Caused by general I/O failures. } public void UmaClasse(int x) { this. considere o código abaixo: class OutraClasse { public float x. Considere o seguinte trecho de código: class UmaClasse { private int x.

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

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

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

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

a partir da classe Subbie. Ocultando variáveis • 6. Esta característica da linguagem Java traz grande flexibilidade.Regra: Uma subclasse herda todos os membros de sua superclasse que são acessíveis à subclasse. variáveis membro definidas na subclasse ocultam variáveis de mesmo nome declaradas na superclasse. Considere o seguinte exemplo: class Super { Number aNumber. dizemos que a subclasse oculta a variável da superclasse. Pág 81 . As subclasses não herdam os membros da superclasse caso a subclasse declare um membro com o mesmo nome. definido na superclasse. No caso de métodos. a menos que a subclasse explicitamente oculte a variável ou redefina o método.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. Portanto. Subclasses não herdam os membros privados (private) da superclasse. 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. No caso de variáveis.2 Como foi dito. Subclasses herdam aqueles membros da superclasse declarados sem especificadores de acesso (público. Mas é possível acessar a variável aNumber. porém pode ser uma fonte de muitos erros. desta forma: super. Uma outra característica interessante da linguagem é que uma classe pode acessar um membro oculto. } A variável aNumber na classe Subbie oculta a variável aNumber definida na classe Super. 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). Note que construtores não são herdados pelas subclasses. privado ou protegido). dizemos que a subclasse redefine o método herdado. desde que estejam no mesmo pacote que a superclasse. } class Subbie extends Super { Float aNumber.

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

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

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

como Circle e Rectangle..abstract class GraphicObject { int x. Por exemplo... Isto garante que as Strings näo possuem nenhum comportamento estranho. } } class Rectangle extends GraphicObject { void draw() { . ou não definir uma implementação para um método abstrato que foi herdado. deve definir uma implementação para o método draw: class Circle extends GraphicObject { void draw() { . o compilador exibirá uma mensagem de erro. int newY) { . Além disto. 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. deve ser declarada como uma classe abstrata.. void moveTo(int newX. Porém. . o verificador Pág 85 . } Cada subclasse não abstrata de GraphicObject. indesejável ou imprevisível.. necessariamente. 6. Para prevenir este tipo de ataque. qualquer classe que possuir um método abstrato.. ou seja. possuir um método abstrato. 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.. a classe String de Java é uma classe final por esta razão. A subclasse parece e age como a classe original mas faz coisas bastante diferentes (e devastadoras). você pode declarar sua classe como final.. podendo causar danos ou acessando informação privada. inconsistente.5 Classes e Métodos Finais Pode-se declarar uma classe como final. } abstract void draw(). Ao tentar compilar uma subclasse de uma classe final. y. } } Observação: Uma classe abstrata não precisa.

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

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

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

Uma classe não poder herdar implementações de métodos de uma interface. A hierarquia de interfaces é independente da hierarquia de classes. uma interface pode possuir múltiplas “superinterfaces”. Apesar de interfaces resolverem muitos problemas parecidos. interfaces e herança múltipla são soluções bem distintas: • • • Uma classe só herda constantes de uma interface. qual a utilidade de interfaces? Você pode usar uma interface para definir um comportamento que pode ser implementado por qualquer classe. Classes que implementam a mesma interface podem ou não estar relacionadas em uma hierarquia de classes. Isto não ocorre no caso de herança múltipla. Afinal. sem ser obrigado a criar artificialmente uma relação de herança entre elas. Ou seja. Interfaces são úteis nos seguintes casos: • • Captura de similaridades entre classes não relacionadas.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. independente da sua hierarquia de classes. Declaração de métodos que uma ou mais classes esperam implementar. além do modificador de acesso (public): Pág 89 .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.6. 6. Importante: Java permite herança de multiplas interfaces.

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

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

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

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

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

por sua vez.java br\uemg\passos\graphics\Retangle.java.passos.java (UNIX) (Windows) Ao compilar o arquivo fonte.uemg. por convenção. O diagrama a seguir mostra como isto funciona. Este arquivo fonte deve ficar em um diretório cujo nome é igual ao do pacote que contém a classe ou interface. 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 é . a UEMG/Passos possui o domínio passos. Por exemplo.java. cada empresa utiliza o seu domínio de Internet invertido para denominar os seus pacotes.java) e de classes (.Rectangle rect. o compilador cria um arquivo de saída para cada classe e interface definida. este arquivo ficaria em: package br. o código fonte da classe Rectangle deve estar em um arquivo chamado Rectangle.uemg. A estratégia é a seguinte. Por exemplo.br. 6. pode estar em qualquer diretório do sistema de arquivos.graphics br/uemg/passos/graphics/Retangle.java e o arquivo deve estar em um diretório chamado graphics.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 (. 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.java caminho do arquivo Além disto. assim todos os pacotes desenvolvidos na Universidade deveriam ter seus nomes precedidos por br. supondo que a UEMG/Passos tenha um pacote chamado graphics que contém um arquivo chamado Rectangle. embora a especificação da linguagem Java não determine isto. Assim. O nome do arquivo é igual ao nome da classe ou interface e sua extensão é . Cada componente do nome do pacote corresponde a um subdiretório.class).uemg.graphics. O diretório graphics.Rectangle Nome da classe graphics/Rectangle.class: Pág 95 .passos.

A partir dos diretórios listados no classpath. Entretanto. ele deve ser capaz de encontrar o arquivo correspondente.zip) definido no class path (caminho de classes).class (Windows) Desta forma.java (Windows) classes\br\uemg\passos\graphics\Retangle. por exemplo: fontes\br\uemg\passos\graphics\Retangle.Como o arquivo .zip que contém todas as classes do JDK.class deve incluir o diretório classes mas não os subdiretórios br ou passos.class deve estar em uma série de diretórios que reflete o nome do pacote. 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. Por default. um arquivo .java. Definição: O class path é uma lista de diretórios ou arquivos compactados onde o compilador/interpretador realiza a busca por classes ou interfaces. Mas. Ou seja. o compilador e o interpretador procuram o diretório atual (. Em outras palavras. por exemplo.zip das classes do JDK já fazem parte automaticamente do seu class path. o diretório atual e os arquivo . afinal de contas. ele não precisa estar no mesmo diretório que o arquivo fonte. Analogamente. 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. o class path para a estrutura de diretórios classes\br\uemg\passos\graphics\Retangle. Cada diretório definido no class path é um local onde os diretórios dos pacotes podem aparecer. o compilador e o interpretador podem construir o resto do caminho do arquivo baseado no nome do pacote e da classe Por exemplo. Quando o compilador encontra uma nova classe enquanto compila a sua aplicação.) e o arquivo . Tanto o compilador quanto o interpretador procuram por classes em cada diretório (ou arquivo . pode-se definir diretórios separados para os arquivos fonte e os arquivos de classes. quando o interpretador encontra uma nova classe enquanto está executando a sua aplicação. Pág 96 . ele deve ser capaz de executar os métodos desta classe.

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

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

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

Graphical User Interface) para aplicações stand-alone e applets Java. 7. o componente é apagado e então desenhado Pág 100 . Todos os widgets gráficos são subclasses de Component. teclas pressionadas e mudam seu estado ou alteram algum dado interno da aplicação. Interface Gráfica Esta seção mostra como se pode criar interfaces gráficas (GUI.7.1. Uma interface gráfica (GUI) consiste de componentes (widgets). como cliques no mouse.1 Component Um componente é um widget genérico que não pode ser instanciado (Component é uma classe abstrata).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. Estes componentes respondem a eventos iniciados pelo usuário. como botões e text-fields. utilizando o pacote AWT (Abstract Windowing Toolkit). posicionados de alguma forma em um applet ou em uma janela de uma aplicação stand-alone. 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. 7.

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

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

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

1. Exemplo: Pág 104 . public class ScrollbarWidget extends Applet { public void init() { // using a GridLayout ensures Scrollbar fills applet setLayout(new GridLayout(1. public String getText():Obtém todo o texto do componente. o usuário não pode modificar o conteúdo do componente. A largura e altura do campo são definidas pelo seu construtor.1)).VERTICAL) especificada. sb = new Scrollbar(Scrollbar.• • • • 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.1.11 TextArea Representa um campo de texto com várias linhas.awt. add(sb). Alguns métodos importantes: • • • • public String getSelectedText():Obtém o texto selecionado.*. 7.1.*. public void setText(String t): Define o conteúdo (texto) do componente.HORIZONTAL ou Scrollbar. import java. Existem scroll bars verticais e horizontais.applet. Exemplo: import java.10 TextComponent A classe TextComponent não pode ser instanciada. ela é a superclasse dos widgets de edição de texto (TextField e TextArea).9 Scrollbar Esta classe representa um “barra rolante” que contém um valor inteiro. 7. Scrollbar sb. } } Alguns métodos importantes: • public Scrollbar(int orientation):Constrói um scroll bar com a orientação (Scrollbar.HORIZONTAL). public void setEditable(boolean t): Se nâo-editável.

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

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

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

o objeto que o gerou avisa todos os objetos ouvintes. botão liberado. O pacote java. 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 . todos os ouvintes de um tipo de evento devem implementar uma interface correspondente.mais recentes (Communicator 4. O modelo de eventos é baseado no conceito de event listener (ouvinte de eventos). cada um destes tipos de evento corresponde a execução de um método diferente nos objetos ouvintes.x).x e IE 4.event define uma interface específica para cada classe de evento. executando um método destes ouvintes e passando para eles um objeto da classe Event. Um ouvinte de eventos é um objeto interessado em receber eventos. etc.x). Para que este modelo funcione. Uma interface de ouvinte pode definir mais de um método. enquanto o outro modelo (versão 1. A tabela a seguir lista algumas classes de eventos definidas no pacote java.0) é suportado pelos browsers mais antigos (Communicator 3. Quando um evento ocorre.awt. a interface do objeto ouvinte correspondente. objetos ouvintes dos eventos da classe ActionEvent deve implementar a interface ActionListener.).awt.x e IE 3. uma classe de eventos como MouseEvent representa vários tipos de eventos do mouse (botão pressionado. Um objeto que gera eventos (botão.event. 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. Por exemplo. Por exemplo.x e 5.

quando o usuário clicar o botão. pesquisando na documentação. 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. podemos observar que a classe Button possui os métodos addActionListener() e removeActionListener(). ele possui um método chamado addXListener() para adicionar um ouvinte e um método chamado removeXListener() para remover um ouvinte. redimensionado. incrementa o conteúdo do text field do applet.). este objeto fonte é algum tipo de widget (botão. o objeto ouvinte deve se registrar no objeto “fonte” dos eventos. etc. o applet se registra como um ouvinet dos eventos gerados pelo botão. text field. Por exemplo. que é uma extensão do exemplo da seção . 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. Neste exemplo. fechada. iconificada. deiconificada TextComponent TextEvent TextField ActionEvent Window WindowEvent Dica: Para descobrir quais eventos um widget pode gerar.WindowEvent WindowListener windowActivated() windowClosed() windowClosing() windowDeactivated() windowDeiconified() windowIconified() windowOpened() Depois de implementar os métodos da interface de eventos desejada. basta olhar a documentação da API da classe. No caso do AWT. um evento da classe ActionEvent é gerado e o método do applet ouvinte (actionPerformed()) será executado. O applet a seguir. portanto a classe Button gera eventos da classe ActionEvent. Assim. Este método. Pág 109 . O registro do objeto ouvinte segue esta convenção: se o objeto fonte gera eventos do tipo X. por sua vez. 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. mostra como o modelo de eventos do Java funciona.

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

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

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

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

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

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

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

} . public void paint(Graphics g) { . não redefine estes métodos. 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. • update: um método que pode ser utilizado junto com o paint para melhorar o desempenho do applet.. destroy pode ser utilizado por applets que querem liberar outros recursos... check-box. apresentado na seção 7. .. . os métodos para carregar imagens em um applet simplesmente não funcionam dentro do construtor do applet. Por exemplo. usuário pressiona uma tecla). Pág 117 . 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. Por outro lado. Por exemplo. Tratamento de eventos refere-se a detecção e processamento de eventos de entrada (por exemplo. 8. é utilizado pelos applets (e aplicações stand-alone) para implementar interfaces gráficas. } 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.). O applet Simple define sua aparência na tela redefinindo o método paint: class Simple extends Applet { . Muitos applets implementam o método paint para desenhar a representação do applet na página Web. usuário clica no mouse. O pacote AWT. 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.seção 1. O método start em geral é utilizado para iniciar uma ou mais threads que realizam alguma tarefa do applet. um applet que apresenta uma animação deve pará-la quando o usuário tiver “minimizado” a página. o método init é o lugar ideal para executar os métodos que carregam imagens. A maioria dos applets que redefinem o método start também devem redefinir o método stop. O método init é útil para realizar inicializações que não demorem muito. De qualquer forma. o método init deve conter o código que normalmente seria colocado em um construtor. 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. Em geral.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). utilizando o método paint. ele apenas mostra uma string. etc.

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

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

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

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

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

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

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

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

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

io. String s.in)). out. armazena-as em duas variáveis e as exibe na tela: import java. 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. public class Eco { public static void main(String[] args) throws IOException { String a. while ((s = in.readLine()) != null) out. } } 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). BufferedReader ent = new BufferedReader(new InputStreamReader(System.close().println(s).readLine(). in. Note que é necessário executar o método flush do objeto PrintWriter para que os dados sejam efetivamente escritos no arquivo de saída. Pág 129 . Já para ler algum valor do teclado. devemos criar um objeto da classe BufferedReader que possui o método readLine.out.close().*. a = ent. O programa a seguir lê duas strings.flush().3 Entrada e Saída de Dados (Padrão) A classe System do pacote java.x. 10.PrintWriter out = new PrintWriter(outputFile). Para imprimir strings na saída padrão utilizamos os métodos print ou println. System.print("Digite um valor: ").

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

Sign up to vote on this title
UsefulNot useful