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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Tente definir também subclasses Pág 23 .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. 5 Considere um objeto do mundo real.2.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

iampublic = 10. o código abaixo é válido: package Greek. // 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. Assim. class Beta { void accessMethod() { Alpha a = new Alpha().publicMethod().packageMethod(). ou seja.out. package Roman. class Beta { void accessMethod() { Alpha a = new Alpha(). Por exemplo: package Greek.*.println("packageMethod"). // válido a. Pacote (package) Este nível de acesso é o default. a. de tal forma que esta não possua nenhum relacionamento (superclasse/subclasse) com Alpha: import Greek. a.iampackage = 10. // válido } } Pág 71 .Rescrevendo a classe Beta. void packageMethod() { System. Este nível permite que classes do mesmo pacote acessem os membros da classe. class Alpha { int iampackage. // válido } } Observe que a classe Beta continua com acesso aos membros públicos de Alpha.

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

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

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

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

5. 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. } 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 x) { this. considere o código abaixo: class OutraClasse { public float x.FileNotFoundException IOException NullPointerException NumberFormatException OutOfMemoryException SecurityException StackOverflowException StringIndexOutOfBounds Exception Caused by an attempt to access a nonexistent file Caused by general I/O failures. } } O código acima é válido? Justique. Agora. public void UmaClasse(int a) { x = a.x = x. 2. Considere o seguinte trecho de código: class UmaClasse { private int x.5 Exercícios 1.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful