Download - Projeto JEDI - Introdução à Programação - Java - Módulos 01 e 02 - 431 páginas

Transcript
Page 1: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 1Introdução à Programação de Computadores

Versão 1.01 - Jan/2008

Page 2: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

AutorFlorence Tiu Balagtas

EquipeJoyce AvestroFlorence BalagtasRommel FeriaReginald HutchersonRebecca OngJohn Paul PetinesSang ShinRaghavan SrinivasMatthew Thompson

Necessidades para os ExercíciosSistemas Operacionais SuportadosNetBeans IDE 5.5 para os seguintes sistemas operacionais: • Microsoft Windows XP Profissional SP2 ou superior• Mac OS X 10.4.5 ou superior• Red Hat Fedora Core 3 • Solaris™ 10 Operating System (SPARC® e x86/x64 Platform Edition) NetBeans Enterprise Pack, poderá ser executado nas seguintes plataformas:• Microsoft Windows 2000 Profissional SP4• Solaris™ 8 OS (SPARC e x86/x64 Platform Edition) e Solaris 9 OS (SPARC e

x86/x64 Platform Edition) • Várias outras distribuições Linux

Configuração Mínima de HardwareNota: IDE NetBeans com resolução de tela em 1024x768 pixel

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 500 MHz Intel Pentium III workstation ou equivalente

512 MB 850 MB

Linux 500 MHz Intel Pentium III workstation ou equivalente

512 MB 450 MB

Solaris OS (SPARC) UltraSPARC II 450 MHz 512 MB 450 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Série 1.8 GHz 512 MB 450 MB

Mac OS X PowerPC G4 512 MB 450 MB

Configuração Recomendada de Hardware

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 1 GB

Linux 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 850 MB

Solaris OS (SPARC) UltraSPARC IIIi 1 GHz 1 GB 850 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Series 1.8 GHz 1 GB 850 MB

Mac OS X PowerPC G5 1 GB 850 MB

Requerimentos de SoftwareNetBeans Enterprise Pack 5.5 executando sobre Java 2 Platform Standard Edition Development Kit 5.0 ou superior (JDK 5.0, versão 1.5.0_01 ou superior), contemplando a Java Runtime Environment, ferramentas de desenvolvimento para compilar, depurar, e executar aplicações escritas em linguagem Java. Sun Java System Application Server Platform Edition 9.• Para Solaris, Windows, e Linux, os arquivos da JDK podem ser obtidos para sua

plataforma em http://java.sun.com/j2se/1.5.0/download.html• Para Mac OS X, Java 2 Plataform Standard Edition (J2SE) 5.0 Release 4, pode ser

obtida diretamente da Apple's Developer Connection, no endereço: http://developer.apple.com/java (é necessário registrar o download da JDK).

Para mais informações: http://www.netbeans.org/community/releases/55/relnotes.html

Introdução à Programação I 2

Page 3: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Colaboradores que auxiliaram no processo de tradução e revisãoAlexandre MoriAlexis da Rocha SilvaAline Sabbatini da Silva AlvesAllan Wojcik da SilvaAndré Luiz MoreiraAndro Márcio Correa LouredoAntoniele de Assis LimaAntonio Jose R. Alves RamosAurélio Soares NetoBruno da Silva BonfimBruno dos Santos MirandaBruno Ferreira RodriguesCarlos Alberto Vitorino de AlmeidaCarlos Alexandre de SeneCarlos André Noronha de SousaCarlos Eduardo Veras NevesCleber Ferreira de SousaCleyton Artur Soares UraniCristiano Borges FerreiraCristiano de Siqueira PiresDerlon Vandri AliendresFabiano Eduardo de OliveiraFábio BombonatoFernando Antonio Mota TrintaFlávio Alves GomesFrancisco das ChagasFrancisco Marcio da SilvaGilson Moreno CostaGivailson de Souza NevesGustavo Henrique CastellanoHebert Julio Gonçalves de PaulaHeraldo Conceição Domingues

Hugo Leonardo Malheiros FerreiraIvan Nascimento FonsecaJacqueline Susann BarbosaJader de Carvalho BelarminoJoão Aurélio Telles da RochaJoão Paulo Cirino Silva de NovaisJoão Vianney Barrozo CostaJosé Augusto Martins NieviadonskiJosé Leonardo Borges de MeloJosé Ricardo CarneiroKleberth Bezerra G. dos SantosLafaiete de Sá GuimarãesLeandro Silva de MoraisLeonardo Leopoldo do NascimentoLeonardo Pereira dos SantosLeonardo Rangel de Melo FilardiLucas Mauricio Castro e MartinsLuciana Rocha de OliveiraLuís Carlos AndréLuís Octávio Jorge V. LimaLuiz Fernandes de Oliveira Junior Luiz Victor de Andrade LimaManoel Cotts de QueirozMarcello Sandi PinheiroMarcelo Ortolan PazzettoMarco Aurélio Martins BessaMarcos Vinicius de ToledoMaria Carolina Ferreira da SilvaMassimiliano GiroldiMauricio Azevedo GamarraMauricio da Silva MarinhoMauro Cardoso Mortoni

Mauro Regis de Sousa LimaNamor de Sá e SilvaNéres Chaves RebouçasNolyanne Peixoto Brasil VieiraPaulo Afonso CorrêaPaulo José Lemos CostaPaulo Oliveira Sampaio ReisPedro Antonio Pereira MirandaPedro Henrique Pereira de AndradeRenato Alves FélixRenato Barbosa da SilvaReyderson Magela dos ReisRicardo Ferreira RodriguesRicardo Ulrich BomfimRobson de Oliveira CunhaRodrigo Pereira MachadoRodrigo Rosa Miranda CorrêaRodrigo Vaez Ronie DotzlawRosely Moreira de JesusSeire ParejaSergio PomerancblumSilvio SzniferSuzana da Costa OliveiraTásio Vasconcelos da SilveiraThiago Magela Rodrigues DiasTiago Gimenez RibeiroVanderlei Carvalho Rodrigues PintoVanessa dos Santos AlmeidaVastí Mendes da Silva RochaWagner Eliezer Roncoletta

Auxiliadores especiaisRevisão Geral do texto para os seguintes Países:

• Brasil – Tiago Flach• Guiné Bissau – Alfredo Cá, Bunene Sisse e Buon Olossato Quebi – ONG Asas de Socorro

Coordenação do DFJUG• Daniel deOliveira – JUGLeader responsável pelos acordos de parcerias• Luci Campos - Idealizadora do DFJUG responsável pelo apoio social• Fernando Anselmo - Coordenador responsável pelo processo de tradução e revisão,

disponibilização dos materiais e inserção de novos módulos• Regina Mariani - Coordenadora responsável pela parte jurídica• Rodrigo Nunes - Coordenador responsável pela parte multimídia• Sérgio Gomes Veloso - Coordenador responsável pelo ambiente JEDITM (Moodle)

Agradecimento EspecialJohn Paul Petines – Criador da Iniciativa JEDITM

Rommel Feria – Criador da Iniciativa JEDITM

Introdução à Programação I 3

Page 4: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta seção, vamos discutir os componentes básicos de um computador, tanto em relação a hardware como a software. Também veremos uma pequena introdução sobre linguagens de programação e sobre o ciclo de vida do desenvolvimento. Por fim, mostraremos os diferentes sistemas numéricos e as conversões entre eles.

Ao final desta lição, o estudante será capaz de:

• Identificar os diferentes componentes de um computador.

• Conhecer as linguagens de programação e suas categorias.

• Entender o ciclo de vida de desenvolvimento de programas e aplicá-lo na solução de

problemas.

• Conhecer os diferentes sistemas numéricos e as conversões entre eles.

Introdução à Programação I 4

Page 5: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. IntroduçãoO computador é uma máquina que realiza uma variedade de tarefas de acordo com instruções específicas. É uma máquina de processamento de dados, que recebe dados através de um dispositivo de entrada e o processador os manipula de acordo com um programa.

O computador tem dois componentes principais. O primeiro é o Hardware que é a parte palpável (que se pode tocar) do computador. Ele é composto de partes eletrônicas e mecânicas.

O segundo componente principal é o Software que é a parte impalpável (não se pode tocar) do computador. Ele é composto de dados e dos programas de computador.

Introdução à Programação I 5

Page 6: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Componentes Básicos de um Computador

3.1. Hardware

3.1.1. Unidade Central de Processamento (CPU - Central Processing Unit)

O processador é o “cérebro” do computador. Ele possui milhões de partes elétricas muito pequenas. Ele faz as operações fundamentais dentro do sistema. Alguns exemplos de processadores são o Pentium, Athlon e SPARC.

Figura 1: Processador de um PC

3.1.2. Memória

A memória, onde se encontram os dados e as instruções que a CPU precisa para realizar suas tarefas, dividida em diversos locais de armazenamento que possuem seus respectivos endereços lógicos. A CPU acessa a memória pelo uso destes endereços.

1. Memória Principal

A memória principal, às vezes, chamada de RAM (Random Access Memory ou Memória de Acesso Randômico) está fortemente ligada ao processador. Ela é utilizada para armazenar programas e dados, com os quais o processador está trabalhando no momento e não é utilizada para armazenamento de longo prazo, por este motivo seu armazenamento é considerado volátil. Isto significa que assim que o computador é desligado, toda a informação armazenada na memória principal será perdida.

Figura 2: Pente de memória

2. A Memória Secundária

A memória secundária está ligada à memória principal. Ela é usada para armazenar programas e dados para uso de longo prazo. Exemplos de memória secundária são discos rígidos e cd-rom.

Introdução à Programação I 6

Page 7: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 3: Interior de um Disco rígido do computador

A memória secundária é considerada um tipo de armazenamento não-volátil. Isto significa que as informações nela armazenadas não serão perdidas após o computador ser desligado.

Memória Principal Memória Secundária Propriedade

Rápida Lenta Velocidade

Cara Barata Preço

Baixa Alta Capacidade

Sim Não Volátil

Tabela 1: Comparação entre a memória principal e a memória secundária

3.1.3. Dispositivos de Entrada e Saída

Os dispositivos de entrada e saída permitem que o computador interaja com o mundo exterior pela movimentação de dados para dentro e para fora do sistema.

Exemplos de dispositivos de entradas são teclados, mouses, microfones, etc. Exemplos de dispositivos de saída são monitores, impressoras, alto-falantes, etc.

3.2. SoftwareO software é um programa que o computador usa para funcionar. Ele é armazenado em algum dispositivo de hardware como um disco rígido, mas é em si mesmo intangível. Os dados que o computador usa podem ser qualquer coisa que o programa precise. Os programas agem como instruções para o processador.

Alguns tipos de programas de computador:

1. Programas de Sistemas

Programas necessários para que o hardware e o software funcionem juntos corretamente.

Exemplos:

• Sistemas Operacionais como Linux, Windows, Unix, Solaris, MacOS

2. Aplicativos

Programas que as pessoas usam para realizar determinado trabalho.

Exemplos:

• Processadores de Textos

• Jogos

• Planilhas Eletrônicas

3. Compiladores

O computador entende apenas uma linguagem: linguagem de máquina. Linguagem de máquina

Introdução à Programação I 7

Page 8: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

está na forma de zeros e uns. Já que é totalmente impraticável para as pessoas criarem programas usando zeros e uns, é preciso haver uma maneira de traduzir ou converter a linguagem que entendemos em linguagem de máquina, para isto, existem os compiladores.

Introdução à Programação I 8

Page 9: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Visão Geral sobre Linguagens de Programação

4.1. O que é uma linguagem de programação?Uma linguagem de programação é uma técnica de comunicação padronizada para se expressar instruções para um computador. Assim como os idiomas utilizados pelos seres humanos, cada linguagem tem sua própria sintaxe e gramática.

Linguagens de programação possibilitam ao programador especificar precisamente com quais dados o computador irá interagir, como estes dados serão gravados/transmitidos, e precisamente quais ações serão tomadas de acordo com as circunstâncias.

Existem diferentes tipos de linguagens de programação que podem ser usadas para a criação de programas, mas, independente da linguagem utilizada, essas instruções são traduzidas em linguagem de máquina, e podem ser entendidas por computadores.

4.2. Categorias das Linguagens de Programação1. Linguagens de Programação de Alto Nível

Uma linguagem de programação de alto nível é uma linguagem de programação que é mais amigável para o usuário, em alguns casos independente de plataforma, e que abstrai operações de baixo nível como acesso a memória. Uma instrução de programação pode ser traduzida em uma ou várias instruções de máquina por um compilador.

Exemplos são Java, C, C++, Basic, Fortran

2. Linguagens de Montagem de Baixo Nível

Linguagens de montagem são similares às linguagens de máquina, são mais simples de programar pois possuem poucos comandos e permitem ao programador substituir nomes por números. Linguagens de montagem estão disponíveis em cada família de CPU, e cada instrução de montagem é traduzida em uma instrução de máquina por um programa montador.

Nota: Os termos "alto nível" e "baixo nível" são relativos. Originalmente, linguagens de montagem eram consideradas de baixo nível e COBOL, C, etc. eram consideradas de alto nível. Muitos programadores, hoje em dia, podem se referir a estas últimas como linguagens de baixo nível.

Introdução à Programação I 9

Page 10: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. O Ciclo de Vida de Desenvolvimento de ProgramasProgramadores não sentam e simplesmente começam a escrever código de uma vez, quando estão tentando fazer um programa de computador. Ao invés disto, eles seguem um planejamento organizado ou metodologia, que quebra o processo em uma série de tarefas.

Este é o ciclo de vida quando se tenta resolver um problema no computador:

Figura 4: Ciclo de vida para a resolução de problemas

Para entendermos o funcionamento deste ciclo na solução de problemas no computador, vamos definir um problema exemplo que iremos resolver passo a passo enquanto discutimos as metodologias para resolução de problemas em detalhe.

5.1. Definir o problemaGeralmente, um programador recebe uma tarefa na forma de um problema. Antes do programa poder ser projetado para resolver um problema em particular, o problema deve, em primeiro lugar, ser bem e claramente definido em termos dos seus requisitos de entrada e saída.

Um problema claramente definido já é metade da solução. Programação de computadores requer que o problema seja primeiro definido antes de se pensar em criar a solução.

Vamos definir o problema exemplo:

“Crie um programa que irá determinar o número de vezes que um nome aparece em uma lista.”

5.2. Analisar o problemaDepois do problema ter sido definido adequadamente, o mais simples e também o mais eficiente e efetivo meio de se resolver será visualizá-lo através de uma representação clara e objetiva.

Geralmente, este passo se dá com a quebra do problema em sub-problemas menores e mais simples.

Problema Exemplo:

Determinar o número de vezes que um nome aparece em uma lista

Entrada para o programa:

Lista de nomes, nome que se deseja procurar

Saída do programa:

O número de vezes que o nome aparece em uma lista

5.3. Projetar e representar o algoritmoLogo que o problema estiver sido claramente definido, podemos nos concentrar em desenvolver a solução. Na programação de computadores, geralmente é requirido que expressemos a solução passo a passo.

Introdução à Programação I 10

Page 11: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Um Algoritmo é uma especificação clara e não ambígua dos passos necessários para se resolver o problema. Ele pode ser expresso tanto em linguagem humana (Inglês, Tagalog e Português), como através de representação gráfica como fluxograma ou através de pseudocódigo, que é um meio termo entre a linguagem humana e a linguagem de programação.

Dado o problema definido na seção anterior, como podemos expressar a solução de uma maneira simples e que possa ser entendida?

Expressando a solução através da linguagem humana:

1. Obter a lista de nomes, vamos chamá-la de NomeLista2. Obter o nome a ser procurado, vamos chamá-lo de NomeChave3. Criar um contador, vamos chamá-lo de Conta4. Pegar cada nome em NomeLista5. Se NomeChave for igual ao nome selecionado em NomeLista6. Adicionar 1 a Conta7. Repetir 4 até que todos os nomes já tiverem sido comparados8. Exibir o valor de Conta

Expressando a solução através de um fluxograma:

Figura 5: Exemplo de um fluxograma

Expressando a solução através de pseudocódigo:

Introdução à Programação I 11

Page 12: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Fazer NomeLista = Lista de Nomes Fazer NomeChave = o nome a ser procuradoFazer conta = 0 Para cada nome em NomeLista fazer Se nome é igual a NomeChave Fazer Conta = Conta + 1 Mostrar Conta

Figure 6: Exemplo de pseudocódigo

5.3.1. Símbolos do Fluxograma e o seu significado

Um fluxograma é uma ferramenta de projeto usada para representar graficamente a lógica de uma solução. Os fluxogramas, tipicamente, não mostram comandos de linguagem de programação. Ao invés disto, eles mostram o conceito em Português ou em notação matemática.

Aqui estão algumas dicas dos símbolos mais usados para a criação de fluxogramas. Pode-se utilizar quaisquer símbolos quando criar os seus fluxogramas, desde que use-os de maneira consistente.

Símbolo Nome Significado

Símbolo de Processo

Representa o processo de se executar uma operação definida ou grupo de operações que resultam em mudança de valor, forma ou localização da informação. Também funciona como símbolo padrão quando nenhum outro símbolo estiver disponível.

Símbolo de Entrada/Saída (E/S)

Representa a função de E/S que faz com que os dados fiquem disponíveis para processamento (entrada) ou para a exibição (saída) das informações processadas.

Símbolo de Linha

Representa a seqüência de informações disponíveis e operações executáveis. As linhas conectam outros símbolos, e as setas são obrigatórias somente em fluxos com orientação da direita para esquerda e de baixo para cima.

Símbolo de Anotação

Representa a adição de informação descritiva, comentários, ou notas explicativas para esclarecimentos. A linha vertical e a linha pontilhada podem ser colocadas à esquerda, como mostrado, ou à direita.

Símbolo de Decisão

Representa a decisão que determina qual das alternativas será seguida.

Símbolo Terminal

Representa o começo, o final, um ponto de interrupção ou um atraso em um programa.

Símbolo Conector

Representa qualquer entrada, ou saída, a outra parte do fluxograma. Também serve como um conector fora de página.

Introdução à Programação I 12

Page 13: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Símbolo Nome Significado

Símbolo de Processo Pré-definido

Representa um processo nomeado consistindo de uma ou mais operações ou passos de programa especificados em algum outro lugar.

Tabela 2: Símbolos do Fluxograma

5.4. Codificar e DepurarDepois de construir o algoritmo, será possível criar o código fonte. Usando o algoritmo como base, o código fonte pode ser escrito usando a linguagem de programação escolhida.

Na maioria das vezes, depois do programador ter escrito o programa, este poderá não estar funcionando 100% no início. O programador deve corrigir o programa no caso de erros (também conhecidos como Erros de Compilação) que ocorrem no programa. Este processo é chamado de depuração de erros (debug).

Existem dois tipos de erros que os programadores poderão encontrar. O primeiro é o erro em tempo de compilação e o outro é o erro em tempo de execução.

Erro em tempo de compilação ocorre se há um erro de sintaxe no código. O compilador irá detectar o erro e o programa nem mesmo compilará. Neste ponto, o programador estará inapto a criar um executável que possa ser executado pelo usuário até que o erro seja corrigido.

Esquecer um ponto-e-vírgula no final de uma instrução ou escrever um comando erroneamente, por exemplo, são erros em tempo de compilação. É algo que o compilador pode detectar como sendo um erro.

Compiladores não são perfeitos e então não podem detectar todos os erros em tempo de compilação. Isso é especialmente verdadeiro para erros de lógica como as repetições (loops) infinitos. Este tipo de erro é chamado de erro em tempo de execução.

Por exemplo, a sintaxe do código pode estar correta. Entretanto, ao seguir a lógica do código, o mesmo pedaço de instrução é executado várias e várias vezes, infinitamente. Neste caso, os compiladores não são espertos o suficiente para pegar todos estes tipos de erro em tempo de compilação, conseqüentemente, o programa compila corretamente em um arquivo executável. Entretanto, quando o usuário final roda o programa, o programa (ou mesmo o computador inteiro) congela devido a uma repetição infinita. Outros tipos de erro em tempo de execução são: um valor errado a ser computado, uma instrução errada a ser executada, etc.

Introdução à Programação I 13

Page 14: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Sistemas Numéricos e ConversõesNúmeros podem ser representados de várias maneiras. A representação depende do que é chamado de BASE. As que seguem são quatro das representações mais comuns.

6.1. DecimalNormalmente representamos os números na forma decimal. Números na forma decimal estão na base 10. Isto significa que os únicos dígitos que aparecem são 0-9. Aqui estão alguns exemplos de números escritos na forma decimal:

12610 (normalmente escrito somente como 126) 1110 (normalmente escrito somente como 11)

6.2. BinárioNúmeros na forma binária estão na base 2. Isto significa que os únicos dígitos aceitos são 0 e 1. Precisamos escrever a subscrição 2 para indicar que o número é um número binário. Aqui estão alguns exemplos de números escritos na forma binária:

11111102

10112

6.3. OctalNúmeros na forma octal estão na base 8. Isto significa que os únicos dígitos aceitos são 0-7. Precisamos escrever a subscrição 8 para indicar que o número é um número octal. Aqui estão alguns exemplos de números escritos na forma octal:

1768

138

6.4. HexadecimalNúmeros na forma hexadecimal estão na base 16. Isto significa que os únicos dígitos aceitos são 0-9 e as letras A-F (ou a-f, minúsculas ou maiúsculas não importam). Precisamos escrever a subscrição 16 para indicar que o número é um número hexadecimal. Aqui estão alguns exemplos de números escritos na forma hexadecimal:

7E16

B16

Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F

Decimal Equivalente 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Tabela 3: Números Hexadecimais e sua equivalência para números decimais

Decimal Binário Octal Hexadecimal

12610 11111102 1768 7E16

1110 10112 138 B16

Tabela 4: Sumário dos exemplos

6.5. Conversões

6.5.1. Decimal para Binário / Binário para Decimal

Para converter um número decimal em binário, deve-se dividir continuamente este número por 2 e separar o resto (que será ou 0 ou 1), considerando-o como um dígito da forma binária do número. Obter o quociente e dividir novamente por 2, repetir o processo até que o quociente atinja 0 ou 1. Ao término, agrupar todos os restos começando pelo último resto. O resultado é a forma binária do número.

Introdução à Programação I 14

Page 15: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

NOTA: O último dígito menor que o divisor (2) será o primeiro número do resultado.

Por Exemplo:12610 = ? 2

Quociente Resto126 / 2 = 63 063 / 2 = 31 131 / 2 = 15 115 / 2 = 7 17 / 2 = 3 13 / 2 = 1 11 / 2 = 1

Escreva nesta

direção

Então, escrevendo os restos de baixo para cima, obtemos o número binário 11111102.

Para converter um número binário para decimal, multiplicar o dígito binário por “2 elevado a posição deste número binário”. Adicionar todos os produtos para obter o número decimal resultante.

Por Exemplo:

11111102 = ? 10

Posição 6 5 4 3 2 1 0Dígitos Binários 1 1 1 1 1 1 0

0 x 20 = 0

1 x 21 = 2

1 x 22 = 4

1 x 23= 8

1 x 24= 16

1 x 25 = 32

1 x 26 = 64TOTAL: 126

6.5.2. Decimal Para Octal (ou Hexadecimal)/Octal (ou Hexadecimal) para Decimal

Converter números decimais para octal ou hexadecimal é basicamente o mesmo que converter decimal para binário. Entretanto, ao invés de utilizar o 2 como divisor, substituí-lo por 8 (para octal) ou 16 (para hexadecimal).

Por Exemplo (Octal):

12610 = ? 8

Quociente Resto

126 / 8 = 15 615 / 8 = 1 71 / 8 = 1

Escreva nesta

direção

Então, escrevendo os restos de baixo para cima, obtemos o número octal 1768.

Por Exemplo (Hexadecimal):

12610 = ? 16

Introdução à Programação I 15

Page 16: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Quociente Resto

126 / 16 = 7

14 (igual ao dígito hexadecimal E)

7 / 16 = 7

Escreva nesta

direção

Então, escrevendo os restos de baixo para cima, obtemos o número hexadecimal 7E16

Converter números octais ou hexadecimais é um processo semelhante a converter números de binários para decimal. Para fazer isto, substituímos o número 2 pelo 8 para octal ou pelo 16 para hexadecimal.

Por Exemplo (Octal):

1768 = ? 10

Posição 2 1 0Dígitos Octais 1 7 6

6 x 80 = 6

7 x 81 = 56

1 x 82 = 64

TOTAL: 126

Por Exemplo (Hexadecimal):7E16 = ? 10

Posição 1 0Dígitos Hexadecimais 7 E

14 x 160 = 14

7 x 161 = 112

TOTAL: 126

6.5.3. Binário para Octal / Octal para Binário

Para conveter números binários para octal, partimos o número binário em grupos de 3 dígitos (da direita para esquerda), e o preenchemos com zeros se o número de dígitos não for divisível por 3. Então, convertemos cada partição em seu correspondete dígito octal. A tabela abaixo mostra a representação binária de cada dígito octal.

Dígito Octal Representação Binária

0 000

1 001

2 010

3 011

4 100

5 101

6 110

7 111

Tabela 5: Dígitos Octais e sua representação binária correspondente

Por Exemplo:

Introdução à Programação I 16

Page 17: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

11111102 = ? 8

0 0 1 1 1 1 1 1 0

1 7 6Número octal equivalente

Converter números octais para binário é o oposto do que foi explicado acima. Simplesmente converta cada dígito octal na sua representação binária (conforme a tabela) e concatene-os. O resultado é a representação binária.

6.5.4. Binário para Hexadecimal / Hexadecimal para Binário

Para converter números binários para hexadecimal, partimos o número binário em grupos de 4 dígitos (da direita para a esquerda), e o preenchemos com zero se o número de dígitos não for divisível por 4. Então convertemos cada partição em seu dígito hexadecimal correspondente. A tabela abaixo mostra a representação binária de cada dígito hexadecimal.

Dígito Hexadecimal

Representação Binária

0 0000

1 0001

2 0010

3 0011

4 0100

5 0101

6 0110

7 0111

8 1000

9 1001

A 1010

B 1011

C 1100

D 1101

E 1110

F 1111

Tabela 6: Dígitos Hexadecimais e sua representação binária correspondente

Por Exemplo:

11111102 = ? 16

0 1 1 1 1 1 1 0

7 E

Número hexadecimal equivalente

Introdução à Programação I 17

Page 18: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Converter números hexadecimais para binário é o oposto do que foi explicado acima. Simplesmente converta cada dígito hexadecimal na sua representação binária (conforme a tabela) e concatene-os. O resultado é a representação binária.

Introdução à Programação I 18

Page 19: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Exercícios

7.1. Escrevendo AlgoritmosDado o seguinte conjunto de tarefas, crie um algoritmo para realizar cada uma das tarefas abaixo. Escreva os algoritmos usando pseudocódigo ou fluxogramas.

1. Assar pão

2. Acessar o computador

3. Obter a média de três números

7.2. Conversão de NúmerosConverta os números abaixo:

1. 198010 para binário, hexadecimal e octal

2. 10010011012 para decimal, hexadecimal e octal

3. 768 para binário, hexadecimal e decimal

4. 43F16 para binário, decimal e octal

Introdução à Programação I 19

Page 20: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 2Histórico de Java

Versão 1.0 - Jan/2007

Page 21: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição iremos discutir um pouco da história de Java e o que é a tecnologia Java. Também iremos discutir as fases de um programa Java.

Ao final desta lição, o estudante será capaz de:

• Descrever as características da tecnologia Java como a JVM - Máquina Virtual Java, Garbage Collection e segurança do código;

• Descrever as diferentes fases de um programa Java.

Introdução à Programação I 4

Page 22: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Explorando o Java

2.1. Um pouco da história

Java foi criado em 1991 por James Gosling da Sun Microsystems. Inicialmente chamada OAK (Carvalho), em homenagem à uma árvore de janela do Gosling, seu nome foi mudado para Java devido a existência de uma linguagem com o nome OAK.

Figura 1: James Gosling criador do Java

A motivação original do Java era a necessidade de uma linguagem independente de plataforma que podia ser utilizada em vários produtos eletrônicos, tais como torradeiras e refrigeradores. Um dos primeiros projetos desenvolvidos utilizando Java era um controle remoto pessoal chamado *7 (Star Seven).

Figura 2: Star Seven

Ao mesmo tempo, a World Wide Web e a Internet foram ganhando popularidade. Gosling achava que a linguagem Java poderia ser usada para programação da Internet.

2.2. O que é a tecnologia Java?

2.2.1. Uma linguagem de programação

Como linguagem de programação, Java pode ser utilizado para criar todos os tipos de aplicações existentes, de programas de Inteligência Artificial para Robôs até programas para aparelhos celulares.

Introdução à Programação I 5

Page 23: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2.2.2. Um ambiente de desenvolvimento

Como ambiente de desenvolvimento, a tecnologia Java fornece um grande conjunto de ferramentas: um compilador, um interpretador, um gerador de documentação, ferramenta de empacotamento de classes de arquivos e outros.

2.2.3. Um ambiente de aplicação

Aplicações de tecnologia Java são tipicamente programas de propósito geral que executam sobre uma máquina onde o Java Runtime Environment é instalado.

2.2.4. Um ambiente de distribuição

Há dois ambientes de distribuição principais: Primeiro, o JRE, fornecido através do Java 2 Software Development Kit (SDK), contém um conjunto completo de arquivos de classes para todos pacotes de tecnologia Java. Outro ambiente de distribuição é o navegador web, ou seja, o browser. Os navegadores web atuais fornecem interpretação à tecnologia e ambiente Java em tempo de execução.

Figura 3: JDK e JRE

2.3. Algumas características do Java

2.3.1. Máquina Virtual Java

A Máquina Virtual Java é uma máquina imaginária que é implementada através de um software emulador em uma máquina real. A JVM provê especificações de plataforma de hardware na qual compila-se todo código de tecnologia Java. Essas especificações permitem que o software Java seja uma plataforma independente pois a compilação é feita por uma máquina genérica conhecida como JVM.

O bytecode é uma linguagem de máquina especial que pode ser entendida pela Máquina Virtual Java (JVM). O bytecode é independente de qualquer hardware de computador particular. Assim, qualquer computador com o interpretador Java pode executar um programa Java compilado, não importando em que tipo de computador o programa foi compilado.

Introdução à Programação I 6

Page 24: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2.3.2. Garbage Collection

Muitas linguagens de programação permitem ao programador alocar memória durante o tempo de execução. Entretanto, após utilizar a memória alocada, deve existir uma maneira para desalocar o bloco de memória de forma que os demais programas a utilizem novamente. Em C, C++ e outras linguagens o programador é o responsável por isso. Isso, às vezes, pode ser difícil já que instâncias podem ser esquecidas de serem desalocadas da memória pelos programadores e resultar no que chamamos de escapes da memória.

Em Java, o programador não possui a obrigação da retirar uma variável criada das áreas de memória, isto é feito por uma parte da JVM específica que chamamos de Garbage Collection. O Garbage Collection é o grande responsável pela liberação automática do espaço em memória. Isso acontece automaticamente durante o tempo de vida do programa Java.

2.3.3. Segurança do Código

Segurança do Código é alcançada em Java através da implementação da Java Runtime Environment (JRE). A JRE roda códigos compilados para a JVM e executa o carregamento de classes (através do Class Loader), verificação de código (através do verificador de bytecode) e finalmente o código executável.

O Class Loader é responsável por carregar todas as classes necessárias ao programa Java. Isso adiciona segurança através da separação do namespace entre as classes do sistema de arquivos local e aquelas que são importadas pela rede. Isso limita qualquer ação de programas que podem causar danos, pois as classes locais são carregadas primeiro. Depois de carregar todas as classes, a quantidade de memória que o executável irá ocupar é determinada. Isto acrescenta, novamente, uma proteção ao acesso não autorizado de áreas restritas ao código pois a quantidade de memória ocupada é determinada em tempo de execução.

Após carregar as classes e definir a quantidade de memória, o verificador de bytecode verifica o formato dos fragmentos de código e pesquisa nestes fragmentos por códigos ilegais que possam violar o direito de acesso aos objetos.

Depois que tudo isso tiver sido feito, o código é finalmente executado.

2.4. Fases do Programa Java

A figura seguinte descreve o processo de compilação e execução de um programa Java.

O primeiro passo para a criação de um programa Java é escrever os programas em um editor de texto. Exemplos de editores de texto que podem ser utilizados: bloco de notas, vi, emacs, etc. Esses arquivos são armazenados no disco rígido com a extensão .java.

Introdução à Programação I 7

Figura 1: Fases de um Programa Java.

Page 25: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Após o programa Java ter sido criado e salvo, compile o programa utilizando o Compilador Java. A saída desse processo é um arquivo de bytecode com extensão .class.

O arquivo .class é então lido pelo Interpretador Java que converte os bytecodes em linguagem de máquina do computador que se está usando.

Tarefa Ferramenta utilizada Saída

Escrever o programa Qualquer editor de texto Arquivo com extensão .java

Compilar o programa Compilador Java Arquivo com extensão .class (Java bytecode)

Executar o programa Interpretador Java Saída do programa

Tabela 1: Resumo das fases de um programa Java.

Introdução à Programação I 8

Page 26: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 3Primeiros passos no ambiente de programação

Versão 1.0 - Jan/2007

Page 27: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição discutiremos como escrever, compilar e rodar os programas em Java. Existem duas maneiras para se fazer isso: a primeira é por intermédio de uma console e um editor de texto e a segunda é utilizando a IDE NetBeans como ambiente integrado de desenvolvimento.

Ao final desta lição, o estudante será capaz de:

• Criar programas usando o editor de texto com uma console de desenvolvimento do Linux (sugerimos o Ubuntu Dapper) ou Windows

• Diferenciar entre erros de sintaxe e de tempo de execução (Run Time)• Criar programas utilizando a IDE NetBeans

Introdução à Programação I 4

Page 28: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Introdução

Uma IDE é um ambiente de desenvolvimento integrado. É um software aplicativo que provê um construtor de interfaces GUI, um editor de códigos, um compilador e/ou interpretador e um depurador.

Nesta lição utilizaremos o Ubuntu Dapper como sistema operacional ou o Windows. Antes de realizar esta tenha certeza de que já tenha instalado no sistema operacional a Java JDK e o NetBeans. Instruções como instalar o Java JDK e o NetBeans podem ser vistas no Apêndice A e para os ambientes na versão Windows XP no Apêndice B.

Antes de entrar em detalhes, veremos o primeiro programa Java que poderemos escrever.

Introdução à Programação I 5

Page 29: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Primeiro Programa Java

Antes de explicar o que o programa significa, vamos escrevê-lo e executá-lo.

3.1 Utilizando a console e um editor de texto

Neste exemplo utilizaremos um simples editor de texto, que pode ser o gedit do Linux ou o notepad do Windows, para editar o código fonte. Em seguida será necessário abrir uma janela terminal para compilar e executar os programas. Passo 1: executar um editor de texto

Para iniciar um editor de texto no Linux selecione Applications ⇒ Accessories ⇒ Text Editor.

Para iniciar um editor de texto no Windows selecione Start ⇒ Programs ⇒ Accessories ⇒ Notepad.

Passo 2: Abrir a janela de console

Para abrir o terminal no Linux, selecione Applications ⇒ Accessories ⇒ Terminal.

Para abrir o terminal no Windows, selecione Start ⇒ Run... e na janela que se apresenta, digite cmd e pressione o botão OK.

Passo 3: Escrever as instruções utilizando o Editor de Texto

Digite as seguintes instruções no editor de textos:

public class Hello { /** * Meu primeiro programa Java */ public static void main(String[] args) {

// Mostra na tela o texto "Hello world" System.out.println("Hello world!"); } }

Passo 4: Salvar o programa Java

Chamaremos o programa de "Hello.java" e o colocaremos em uma pasta denominada "myJavaPrograms".

Caso esta pasta não tenha sido criada, retorne à janela de terminal aberta e insira as seguintes instruções:

Para o Linux:

$ md myJavaPrograms

Para o Windows:

C:\> md myJavaPrograms

Retorne ao Editor de textos e salve o programa. Para abrir a caixa de diálogo salvar selecione a

Introdução à Programação I 6

Page 30: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

opção "File" localizada na barra de menus e depois clique na opção "Save".

Selecione a nova pasta criada como myJavaPrograms para entrar nela. A pasta deve estar vazia porque ainda não salvamos nada dentro dela.

Na caixa de texto "Name", digite o nome do programa (Hello.java), e depois clique no botão salvar.

ATENÇÃO: Para o Notepad no Windows, mude o Tipo para "All Files" (em Save as Type).

Após salvar o arquivo observe que o título da janela mudou de "Untitled" para "Hello.java", caso deseje alterar novamente o arquivo basta editá-lo e depois salvá-lo novamente clicando em File

⇒ Save.

Passo 5: Entrar na pasta que contém o programa

O próximo passo deve ser o de compilar o programa. Inicialmente, precisamos entrar na pasta que o contém. Retorne à janela do terminal.

Em Linux:

Normalmente, quando abrimos uma janela terminal, ela vai diretamente para sua pasta home (identificada por $). Para ver o que tem dentro do diretório digite ls (LS em minúscula, significando "List Sources") e pressione ENTER. Isso fará com que sejam listados os arquivos e pastas da pasta home.

Verifique a existência de uma pasta chamada "myJavaPrograms", criada a pouco, sendo esta o local em que foi salvo o programa "Hello.java". Mudaremos o contexto para esta pasta.

Para entrar nesta pasta devemos utilizar o comando: cd [nome da pasta]. O comando "cd" significa "Change Directory". Digitaremos:

$ cd myJavaPrograms

Agora que estamos dentro da pasta onde o arquivo do programa está, poderemos então compilá-lo. Certifique-se de que o arquivo está realmente dentro desta, executando o comando ls (LS em minúscula) novamente.

Em Windows:

Normalmente, quando abrimos uma janela terminal ela vai diretamente para sua pasta raiz (identificada por C:\). Para conhecer o conteúdo do diretório digite dir (significando "directory") e pressione ENTER. Isso fará com que sejam listados os arquivos e pastas da pasta principal.

Verifique a existência de uma pasta chamada "myJavaPrograms", criada a pouco, sendo esta o local em que foi salvo o programa "Hello.java". Mudaremos o contexto para esta pasta.

Para entrar nesta pasta devemos utilizar o comando: cd [nome da pasta]. O comando "cd" significa "Change Directory". Digitaremos:

C:\>cd myJavaPrograms

Agora que estamos dentro da pasta onde o arquivo do programa está, poderemos então compilá-lo. Certifique-se de que o arquivo está realmente dentro desta, executando o comando dir novamente.

Passo 6: Compilar o programa

Introdução à Programação I 7

Page 31: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Para compilar o programa, utilizamos o comando: javac [Nome do Arquivo]. Ou seja:

javac Hello.java

Durante a compilação, é criado o arquivo: [Nome do Arquivo].class, neste caso, Hello.class, que contém o código em linguagem de máquina (chamado de bytecode).

Passo 7: Executar o programa

Assumindo que não ocorreu problemas na compilação (caso tenha ocorrido qualquer problema refaça os passos realizados), estamos prontos para executar o programa.

Para executar o programa, utilizamos o comando: java [nome do arquivo sem a extensão]. No caso do exemplo, digite:

java Hello

Veremos na mesma tela, em que foi executado o comando, a seguinte mensagem:

Hello world!

3.2 Erros

Vimos um pequeno programa Java, geralmente não encontraremos qualquer problema para compilar e executar esses programas, entretanto nem sempre este é o caso, como mencionamos na primeira parte deste curso, ocasionalmente encontramos erros durante esse processo.

Como mencionamos antes, há dois tipos de erros: o primeiro pode ocorrer durante a compilação, chamado de erro de sintaxe, o segundo pode ocorrer durante a execução, chamado runtime error.

3.2.1 Erros de Sintaxe

Os erros de sintaxe normalmente são erros de digitação, ocasionados pelo programador que pode ter se equivocado e digitar uma instrução errada, ou por esquecimento de alguma parte da instrução, por exemplo, um ponto e vírgula. O Compilador tenta isolar o erro exibindo a linha de instrução e mostrando o primeiro caractere incorreto naquela linha, entretanto, um erro pode não estar exatamente neste ponto.

Outros erros comuns são a troca de letras, troca de letras maiúscula por minúscula (a linguagem Java é completamente case-sensitive, ou seja, o caractere "a" é completamente diferente do caractere "A", e o uso incorreto da pontuação.

Vamos retornar ao exemplo, o programa Hello.java. Intencionalmente, escreveremos a palavra-chave "static" de forma errada e omitiremos o ponto-e-vírgula em uma instrução e a deixaremos errada.

public class Hello { /** * Meu primeiro programa Java */ public statict void main(String[] args) {

// A linha abaixo foi retirado o ; System.out.println("Hello world!") }

Introdução à Programação I 8

Page 32: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}

Salve o programa e execute os passos necessários para compilá-lo. Observe a mensagem de erro gerada ao se tentar compilar novamente o programa:

Hello.java:6: <identifier> expected public statict void main(String[] args) { ^Hello.java:10: ';' expected } ^1 error

A primeira mensagem de erro sugere que existe um erro na linha 6 do programa apontado para a palavra void, entretanto esta palavra está correta. O erro é na palavra anterior statict que deve ser digitada como static.

A segunda mensagem de erro sugere que faltou um ponto-e-vírgula na linha 10, entretanto, esta contém simplesmente o comando de fechar o bloco do método main. O erro está exatamente na linha anterior.

Como regra, ao encontrar muitas mensagens de erros devemos corrigir o primeiro erro da lista e tente novamente compilar o programa. Deste modo reduziremos o número total de mensagens de erro dramaticamente, pois podem existir o que chamamos de erros derivados, ou seja, um erro que tem por causa a instrução anterior.

3.2.2 Erros em tempo de execução (Erros de run-time)

Os erros em tempo de execução são erros que não aparecerão até que tentemos executar o programa. Os programas são compilados com sucesso, mas apresentarão respostas erradas, que podem ter como causa se o programador não obedeceu uma lógica coerente ou no caso em erro de estruturas do programa.

Introdução à Programação I 9

Page 33: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Usando NetBeans

Construímos o programa sem utilizar nenhum recurso sofisticado, iremos aprender como fazer todo o processo da seção anterior utilizando uma IDE.

Nesta parte da lição utilizaremos o NetBeans que é um Ambiente de Desenvolvimento Integrado (IDE - Integrated Development Environment).

Um ambiente de desenvolvimento integrado é um software aplicativo que possui uma interface construtora, um editor de texto, um editor de código, um compilador e/ou interpretador e um depurador.

Passo 1 : executar o NetBeans

Existem duas formas de executar o NetBeans: a primeira é utilizando a linha de comandos de uma janela terminal e segunda é selecionar o ícone de atalho encontrado na janela da área de trabalho.

Para executar o NetBeans por intermédio da linha de comando, abra uma janela terminal (Os passos para abrir a janela terminal foram discutidos anteriormente) e digite:

Figura 1: Executando o NetBeans pela linha de comandos

Para o Windows, este comando deve ser executado na pasta em que o NetBeans foi instalado, por exemplo:

C:\Program Files\netbeans-5.5\bin>netbeans

A segunda maneira de executar o NetBeans é clicando no ícone de atalho encontrado na área de trabalho do computador.

Figura 2: Ícone do NetBeans 5.5 no Desktop

Depois de abrir a IDE NetBeans será mostrada a interface gráfica GUI, conforme à Figura 3:

Introdução à Programação I 10

Page 34: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 2: construir o projeto

Clique em File ⇒ New Project, depois de fazer isso, uma janela de diálogo aparecerá. Neste momento deve-se clicar em "Java Application" e em seguida clicar no botão "Next >".

Introdução à Programação I 11

Figura 4: Escolhendo o tipo do projeto

Figura 3: Janela de Welcome do NetBeans

Page 35: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Será mostrada uma nova janela de diálogo, conforme a figura 5.

Troque o local da aplicação clicando no botão "Browse...". Aparecerá uma janela de diálogo para localização do diretório. Dê um clique duplo no seu diretório home.

Introdução à Programação I 12

Figura 5: Inserindo as informações do projeto

Figura 6: Acertando a Localização do Projeto

Page 36: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

O conteúdo da raiz do diretório será apresentado. Dê um clique duplo no diretório MYJAVAPROGRAMS e depois dê um clique no botão "Open".

Veja que a localização do projeto mudou para /home/florence/MYJAVAPROGRAMS.Finalmente, no campo "Create Main Class", digite "Hello", que será o nome da classe principal, e em seguida clique no botão "Finish".

Introdução à Programação I 13

Figura 7: Definindo o Nome da Classe Principal

Page 37: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 3: escrever os detalhes do programa

Antes de escrever o programa descreveremos a janela principal.

Como mostrado na figura 8, automaticamente, o NetBeans cria um código básico para o programa Java. Poderemos adicionar as declarações neste código gerado. No lado esquerdo da janela visualizamos uma lista de pastas e arquivos que o NetBeans gerou antes de criar o projeto. Tudo se encontra dentro da sua pasta MYJAVAPROGRAMS, onde foi configurado o local do projeto. No lado direito, visualizamos o código gerado.

Modifique o código gerado pelo NetBeans, por hora ignoraremos as outras partes das instruções discutindo os detalhes destas posteriormente. Insira a seguinte instrução:

System.out.println("Hello world!");

Isto significa que você deseja que seja mostrada a mensagem "Hello world!" na saída padrão do computador, em seguida seja feito um salto de linha. Poderíamos substituir esta instrução por duas equivalentes:

System.out.print("Hello");System.out.println(" world!");

O método print() faz com que não seja provocado o salto de linha, utilizaremos para este exemplo a primeira instrução. Insira esta instrução após a linha de comentário (que será desprezada pelo compilador):

//TODO code application logic here.

Introdução à Programação I 14

Figura 8: Visão do projeto criado

Page 38: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 4 : compilar o projeto

Para compilar o programa, a partir do Menu Principal selecione Build ⇒ Build Main Project, ou utilize a tecla de atalho F11, ou utilize o botão de atalho para compilar o código.

Figura 10: Botão de Atalho para executar o Projeto

Introdução à Programação I 15

Figura 9: Inserindo sua instrução

Page 39: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Se não existir erros no programa, veremos a mensagem de sucesso na janela de saída.

Passo 5: Executar o projeto

Para executar o programa, clique em Run ⇒ Run Main Project, ou utilize a tecla de atalho F6, ou utilize o botão de atalho para executar o programa.

Introdução à Programação I 16

Figura 11: Verificando o Sucesso da Compilação

Figura 12: Executando o projeto

Page 40: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

O resultado final do programa, será mostrado na janela de saída.

Introdução à Programação I 17

Figura 13: Resultado final da execução do projeto

Page 41: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Exercícios

5.1 Melhorando o Hello World!

Utilizando o NetBeans crie uma classe chamada [SeuNome], o programa deverá mostrar como resultado a mensagem:

Welcome to Java Programming [SeuNome]!!!

5.2 A árvore

Utilizando o NetBeans, crie uma classe chamada TheTree. O programa deverá mostrar as seguintes linhas na saída:

I think that I shall never see,[Eu acho que nunca verei,]a poem as lovely as a tree. [um poema tão adorável quanto uma árvore.]A tree whose hungry mouth is pressed [Uma árvore cuja boca faminta é pressionada]Against the Earth’s sweet flowing breast.[Contra a Terra fluindo em seu seio docemente.]

Introdução à Programação I 18

Page 42: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 4Fundamentos da programação

Versão 1.01 - Jan/2008

Page 43: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição discutiremos as partes básicas de um programa em Java. Começaremos explicando as partes do programa Hello.java mostrado na última lição. Discutiremos ao longo desta lição também dicas e convenções para se escrever programas de fácil entendimento.

Ao final desta lição, o estudante será capaz de:

• Identificar e entender as partes básicas de um programa escrito em Java.• Diferenciar, em um programa, o que são: os tipos primitivos de dados, variáveis,

identificadores e operadores.• Desenvolver, em Java, um programa usando os conceitos compreendidos nesta lição.

Introdução à Programação I 4

Page 44: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Entendendo meu primeiro programa em Java

Tentaremos compreender este primeiro programa.

public class Hello { /** * Meu primeiro programa em Java */ public static void main(String[] args) { // Exibir a mensagem "Hello world" na tela System.out.println("Hello world!"); } }

Esta primeira linha do código:

public class Hello

Indica o nome da classe, que neste caso é Hello. Em Java, todo e qualquer código deverá ser escrito dentro da declaração de uma classe. Fazemos isso usando a palavra-chave class. Além disso, a classe usa um identificador de acesso public, indicando que a classe é acessível para outras classes de diferentes pacotes (pacotes são coleções de classes). Trataremos de pacotes e identificadores de acesso mais tarde, ainda neste módulo.

A próxima linha contém uma chave {. Indica o início de um bloco de instruções. Neste programa posicionamos a chave na linha após a declaração da classe, entretanto, poderíamos também colocá-la na mesma linha em que a declaração foi feita. Então, o código seria escrito da seguinte forma:

public class Hello {

oupublic class Hello {

As próximas 3 linhas indicam um comentário em Java. Um comentário é uma explicação do programador usada na documentação de uma parte do código. Este comentário não é propriamente uma parte do código, é usado apenas para fins de documentação do programa. É uma boa prática de programação adicionar comentários relevantes ao código.

/*** Meu primeiro programa em Java*/

Um comentário pode ser indicado pelos delimitadores “/*” e “*/”. Qualquer coisa entre estes delimitadores é ignorado pelo compilador Java e é tratado como comentário. A próxima linha,

public static void main(String[] args) {

que também pode ser escrita da seguinte forma:

public static void main(String[] args) {

indica o nome de um método no programa que é o método principal main. O método main é o ponto de partida para qualquer programa feito em Java. Todo e qualquer programa escrito

Introdução à Programação I 5

Page 45: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

em Java, com exceção de Applets, inicia com o método main. Certifique-se de que a assinatura do método (conforme descrita acima) está correta.

A linha seguinte é também um comentário em Java,

// exibe a mensagem "Hello world" na tela

Até agora, já aprendemos duas maneiras de fazer comentários em Java. Uma é posicionar o comentário entre “/*” e “*/”, e a outra é colocar “//” antes do comentário. A linha de instrução abaixo,

System.out.println("Hello world!");

escreve o texto "Hello World!" na tela. O comando System.out.println( ), escreve na saída padrão do computador o texto situado entre aspas duplas.

As últimas duas linhas, que contêm somente uma chave em cada, simbolizam, respectivamente, o fechamento do método main e da classe.

Dicas de programação :

1. Os programas em Java devem sempre conter a terminação .java no nome do arquivo.

2. O nome do arquivo deve sempre ser idêntico ao nome da classe pública. Então, por exemplo, se o nome da classe pública é Hello o arquivo deverá ser salvo com o nome: Hello.java.

3. Inserir comentários sobre o que a classe ou método realiza, isso facilitará o entendimento de quem posteriormente ler o programa, incluindo o próprio autor.

Introdução à Programação I 6

Page 46: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Comentários em Java

Comentários são notas escritas pelo programador para fins de documentação. Estas notas não fazem parte do programa e não afetam o fluxo de controle.

Java suporta três tipos de comentários: comentário de linha estilo C++, comentário de bloco estilo C e um comentário estilo Javadoc (utilizado compor a documentação do programa).

3.1. Comentário de linha

Comentários com estilo em C++ se iniciam por "//". Todo e qualquer texto colocado após as // é ignorado pelo compilador e tratado como comentário. Por exemplo:

// Este é um comentário estilo C++ ou comentário de linha

3.2. Comentário de bloco

Comentários com estilo em C, também chamados de comentários multi-linhas, se iniciam com /* e terminam com */. Todo o texto posto entre os dois delimitadores é tratado como comentário. Diferente do comentário estilo C++, este pode se expandir para várias linhas. Por exemplo:

/* * Este é um exemplo de comentário * estilo C ou um comentário de bloco * */

3.3. Comentário estilo Javadoc

Este comentário é utilizado na geração da documentação em HTML dos programas escritos em Java. Para se criar um comentário em estilo Javadoc deve se iniciar o comentário com /** e terminá-lo com */. Assim como os comentários estilo C, este também pode conter várias linhas. Este comentário também pode conter certas tags que dão mais informações à documentação. Por exemplo:

/** Este é um exemplo de um comentário especial usado para \n gerar uma documentação em HTML. Este utiliza tags como:

@author Florence Balagtas @version 1.2

*/

Este tipo de comentário deve ser utilizado antes da assinatura da classe:

public class Hello {

Para documentar o objetivo do programa ou antes da assinatura de métodos:

public static void main(String[] args) {

Para documentar a utilidade de um determinado método.

Introdução à Programação I 7

Page 47: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Instruções e Blocos em Java

Uma instrução é composta de uma ou mais linhas terminadas por ponto-e-vírgula. Um exemplo de uma simples instrução pode ser:

System.out.println("Hello world");

Um bloco é formado por uma ou mais instruções agrupadas entre chaves indicando que formam uma só unidade. Blocos podem ser organizados em estruturas aninhadas indefinidamente. Qualquer quantidade de espaços em branco é permitida. Um exemplo de bloco pode ser:

public static void main(String[] args) {System.out.print("Hello ");System.out.println("world");

}

Dicas de programação:

1. Na criação de blocos, a chave que indica o início pode ser colocada ao final da linha anterior ao bloco, como no exemplo:

public static void main(String [] args) {

ou na próxima linha, como em:

public static void main(String [] args){

2. É uma boa prática de programação organizar as instruções que serão colocadas após o início de um bloco, como por exemplo:

public static void main(String [] args) { System.out.print("Hello "); System.out.println("world");}

Introdução à Programação I 8

Page 48: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Identificadores em Java

Identificadores são representações de nomes de variáveis, métodos, classes, etc. Exemplos de identificadores podem ser: Hello, main, System, out.

O compilador Java difere as letras maiúsculas de minúsculas (case-sensitive). Isto significa que o identificador Hello não é o mesmo que hello. Os identificadores em Java devem começar com uma letra, um underscore “_”, ou um sinal de cifrão “$”. As letras podem estar tanto em maiúsculo quanto em minúsculo. Os caracteres subseqüentes podem usar números de 0 a 9.

Os identificadores não podem ter nomes iguais às palavras-chave ou palavras reservadas do Java, como: class, public, void, int, etc. Discutiremos mais sobre estas palavras mais tarde.

Dicas de programação:

1. Para nomes de classes, a primeira letra deve ser maiúscula. Nomes de métodos ou variáveis devem começar com letra minúscula. Por exemplo:

ExemploDeNomeDeUmaClasseexemploDeNomeDeUmMetodo

2. No caso de identificadores com mais de uma palavra, a primeira letra de cada palavra, com exceção da primeira, deve vir em maiúsculo. Por exemplo:

charArray – fileNumber - className

3. Evite o uso de undescores no início de um identificador. Por exemplo:

_NomeDeClasse.

Introdução à Programação I 9

Page 49: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Palavras-chave em Java

Palavras-chave são identificadores que, em Java, foram pré-definidas para propósitos específicos. Não se pode usar esses identificadores como nomes de variáveis, métodos, classes, etc. A seguir, temos a lista com as palavras-chave em Java.

Figura 1: Palavras-Chave em Java

Ao longo dos tópicos seguintes, iremos abordar os significados destas palavras-chave e como são usadas nos programas em Java.

Nota: true, false e null não são palavras-chave, porém, são palavras-reservadas, e, da mesma maneira, não é permitido seu uso na atribuição a nomes de variáveis, métodos ou classes.

Introdução à Programação I 10

Page 50: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Tipos de Dados em Java

Java possui 4 tipos de dados. Estes tipos de dados são divididos em: boolean, character, integer e float-point.

7.1. Boolean

Um dado boolean poderá assumir somente dois valores: true ou false.

7.2. Character

Os characters são representações da tabela Unicode. Um símbolo da tabela Unicode é um valor de 16 bits que pode substituir os símbolos da tabela ASCII (que possuem 8 bits). A tabela Unicode permite a inserção de símbolos especiais ou de outros idiomas. Para representar um caractere usam-se aspas simples. Por exemplo, a letra "a" será representada como 'a'. Para representar caracteres especiais, usa-se a "\" seguido pelo código do caractere especial. Por exemplo, '\n' para o caractere de nova linha, '\'' representar o character ' (aspas simples) e '\u0061' representação Unicode do símbolo 'a'.

7.3. Integer

Os dados do tipo integer vêm em diferentes formatos: decimal (base 10), hexadecimal (base 16), e octal (base 8). Ao usar estes diferentes tipos de dados Integer nos programas é necessário seguir algumas notações preestabelecidas. Para dados decimais não existe notação, basta escrever o número. Os números hexadecimais deverão ser precedidos por "0x" ou "0X". E os octais deverão ser precedidos por "0".

Por exemplo, considere o número 12. Sua representação em decimal é apenas o número 12, sem nenhuma notação adicional, enquanto que sua representação em hexadecimal é 0xC (pois o número 12 em hexadecimal é representado pela letra C), e em octal ele é representado por 014. O valor padrão para tipos de dados Integer é o tipo int. Um int é um valor, com sinal, de 32 bits.

Em alguns casos pode ser necessário forçar o dado Integer a ser do tipo long, para fazer isso basta colocar a letra "l" (L minúscula) ou "L" após o número. Um dado do tipo long é um valor com sinal de 64 bits. Falaremos mais sobre os tipos de dados mais tarde.

7.4. Float-Point

Os tipos de float-point representam dados Integer com parte fracionária. Um exemplo é o número 3.1415 (lembrando que o padrão inglês utiliza o "." como divisor da parte fracionária). Esses tipos podem ser expressos em notação científica ou padrão. Um exemplo de notação padrão é o número 583.45 enquanto que em notação científica ele seria representado por 5.8345e2. O valor padrão para um dado ponto-flutuante é o double, que é um valor de 64 bits. Se for necessário usar um número com uma precisão menor (32 bits) usa-se o float, que é finalizado pela letra "f" ou "F" acrescida ao número em questão, por exemplo, 583.45f.

Introdução à Programação I 11

Page 51: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

8. Tipos de Dados Primitivos

A linguagem Java possui 8 tipos de dados primitivos. Eles são divididos nas seguintes representações:

Representação Tipo de Dado Dado Primitivo

lógico Boolean boolean

inteiro Integer e Character char, byte, short e int

inteiro longo Integer long

número fracionário Float-point float e double

Tabela 1: Representações dos dados primitivos

8.1. Lógico

O tipo boolean pode representar dois estados: true (verdadeiro) ou false (falso). Um exemplo é:

boolean resultado = true;

No exemplo demonstrado acima, é declarado um atributo chamado resultado do tipo boolean e atribuído a este o valor verdadeiro.

8.2. Inteiro

Os inteiros em Java podem ser representados em 5 formas, como já foi visto, e estas são: decimal, octal, hexadecimal, ASCII e Unicode. Como por exemplo:

2 // valor 2 em decimal077 // 0 indica que ele está representado em octal.0xBACC // 0x indica que ele está representado em hexadecimal.'a' // representação ASCII'\u0061' // representação Unicode

O dado do tipo char é um inteiro especial, sendo exclusivamente positivo e representa um único Unicode. Ele deve ser, obrigatoriamente, colocado entre aspas simples (''). Sua representação como inteiro pode ser confusa para o iniciante, entretanto, o tempo e a prática farão com que se acostume com este tipo. Por exemplo:

char c = 97; // representa o símbolo 'a'byte b = 'a'; // em inteiro representa o número 97

É possível definir para qualquer inteiro nas formas mostradas. O que difere o tipo char dos demais inteiros é que a sua saída sempre será mostrada como um valor ASCII. Enquanto que os inteiros serão sempre mostrados por números decimais. Por exemplo:

char c = 97;byte b = 'a';System.out.println("char = " + c + " - byte = " + b);

Resultará:

char = a - byte = 97

Introdução à Programação I 12

Page 52: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Um cuidado deve ser tomado quanto aos inteiros: qualquer operação efetuada entre eles terá sempre como resultado um tipo int. Por exemplo:

byte b1 = 1;byte b2 = 2;byte resultado = b1 + b2;

Esta instrução final causará um erro de compilação, devendo ser modificada para:

int resultado = b1 + b2;

8.3. Inteiro Longo

Os inteiros têm por padrão o valor representado pelo tipo primitivo int. Pode-se representá-los como long adicionando, ao final do número, um "l" ou "L". Os tipos de dados inteiros assumem valores nas seguintes faixas:

Tamanho em memória Dado primitivo Faixa

8 bits byte -27 até 27-1

16 bits char 0 até 216-1

16 bits short -215 até 215-1

32 bits int -231 até 231-1

64 bits long -263 até 263-1

Tabela 2: Tipos e faixa de valores dos Inteiros e Inteiro Longo

Dicas de programação:

1. Para declarar um número como sendo um long é preferível usar “L” maiúsculo, pois, se este estiver em minúsculo, pode ser difícil distinguí-lo do dígito 1.

8.4. Número FracionárioOs dados do tipo ponto-flutuante possuem o valor double como padrão. Os números flutuantes possuem um ponto decimal ou um dos seguintes caracteres:

E ou e // expoenteF ou f // floatD ou d // double

São exemplos,

3.14 // tipo double6.02E23 // double com expoente2.718F // float123.4E+306D // double

No exemplo acima, o número 23 após o E é implicitamente positivo. É equivalente a 6.02E

Introdução à Programação I 13

Page 53: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

+23. Os dados de tipo ponto-flutuante podem assumir valores dentro das seguintes faixas:

Tamanho em memória Dado primitivo Faixa

32 bits float -1038 até 1038-164 bits double -10308 até 10308-1

Tabela 3: Tipos e faixa de valores dos Número Fracionários

Introdução à Programação I 14

Page 54: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

9. Variáveis

Uma variável é um espaço na memória usado para armazenar o estado de um objeto.

Uma variável deve ter um nome e um tipo. O tipo da variável indica o tipo de dado que ela pode conter. O nome das variáveis deve seguir as mesmas regras de nomenclatura que os identificadores.

9.1. Declarando e inicializando VariáveisA seguir, vemos como é feita a declaração de uma variável:

<tipo do dado> <nome> [= valor inicial];

nota: os valores colocados entre < > são obrigatórios, enquanto que os valores contidos entre [ ] são opcionais.

Aqui vemos um exemplo de programa que declara e inicializa algumas variáveis:

public class VariableSamples { public static void main( String[] args ){ // declara uma variável com nome result e tipo boolean boolean result;

// declara uma variável com nome option e tipo char char option; // atribui o símbolo C para a variável option = 'C';

// declara uma variável com nome grade e tipo double // e a inicializa com o valor 0.0 double grade = 0.0; }}

Dicas de programação:

1. É sempre preferível que se inicialize uma variável assim que ela for declarada.

2. Use nomes com significado para suas variáveis. Se usar uma variável para armazenar a nota de um aluno, declare-a com o nome 'nota' e não simplesmente com uma letra aleatória 'x'.

3. É preferível declarar uma variável por linha, do que várias na mesma linha. Por exemplo:

int variavel1;int variavel2;

E não:int variavel1, variavel2;

9.2. Exibindo o valor de uma Variável

Introdução à Programação I 15

Page 55: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Para exibirmos em qualquer dispositivo de saída o valor de uma variável, fazemos uso dos seguintes comandos:

System.out.println() System.out.print()

Aqui está um simples programa como exemplo:

public class OutputVariable { public static void main( String[] args ){ int value = 10; char x; x = 'A';

System.out.println(value); System.out.println("The value of x = " + x ); }}

A saída deste programa será a seguinte:

10 The value of x = A

9.3. System.out.println( ) e System.out.print( )

Qual é a diferença entre os comandos System.out.println( ) e o System.out.print( )? O primeiro faz iniciar uma nova linha após ser exibido seu conteúdo, enquanto que o segundo não.

Considere as seguintes instruções:

System.out.print("Hello ");System.out.print("world!");

Essas instruções apresentarão a seguinte saída:

Hello world!

Considere as seguintes:

System.out.println("Hello ");System.out.println("world!");

Estas apresentarão a seguinte saída:

Hello world!

9.4. Referência de Variáveis e Valor das Variáveis

Iremos diferenciar os dois tipos de variáveis suportados pelo Java. Estes podem ser de referência ou de valor.

As variáveis de “valor”, ou primitivas, são aquelas que armazenam dados no exato espaço de memória onde a variável está.

Introdução à Programação I 16

Page 56: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

As variáveis de referência são aquelas que armazenam o endereço de memória onde o dado está armazenado. Ao declarar uma variável de certa classe (variável de classe), se declara uma variável de referência a um objeto daquela classe.

Por exemplo, vamos supor que se tenha estas duas variáveis do tipo int e da classe String.

int num = 10;String nome = “Hello”;

Suponha que o quadro abaixo represente a memória do computador, com seus endereços de memória, o nome das variáveis e os tipos de dados que ele pode suportar.

Endereço de memória Nome da variável Dado1001 num 10

: :1563 nome Endereço (2000)

:

:

::

2000 "Hello"

A variável (do tipo int) num o dado é o atual valor contido por ela e, a referência da variável (do tipo string) nome somente é armazenado o endereço de memória que contém o valor da variável.

Introdução à Programação I 17

Page 57: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

10. Operadores

Em Java temos diferentes tipos de operadores. Existem operadores aritméticos, operadores relacionais, operadores lógicos e operadores condicionais. Estes operadores obedecem a uma ordem de precedência para que o compilador saiba qual operação executar primeiro, no caso de uma sentença possuir grande variedade destes.

10.1. Operadores Aritméticos

Aqui temos a lista dos operadores aritméticos que podem ser utilizados na criação de expressões matemáticas:

Operador Uso Descrição

* op1 * op2 Multiplica op1 por op2

/ op1 / op2 Divide op1 por op2

% op1 % op2 Resto da divisão de op1 por op2

- op1 - op2 Subtrai op2 de op1

+ op1 + op2 Soma op1 e op2

Tabela 4: Operadores aritméticos e suas funções

Aqui temos um programa que exemplifica o uso destes operadores:

public class ArithmeticDemo { public static void main(String[] args) {

// alguns números int i = 37; int j = 42; double x = 27.475; double y = 7.22; System.out.println("Variables values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" x = " + x); System.out.println(" y = " + y);

// adição dos números System.out.println("Adding..."); System.out.println(" i + j = " + (i + j)); System.out.println(" x + y = " + (x + y));

// subtração dos números System.out.println("Subtracting..."); System.out.println(" i - j = " + (i - j)); System.out.println(" x - y = " + (x - y));

// multiplicação dos números System.out.println("Multiplying..."); System.out.println(" i * j = " + (i * j)); System.out.println(" x * y = " + (x * y));

Introdução à Programação I 18

Page 58: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

// divisão dos números System.out.println("Dividing..."); System.out.println(" i / j = " + (i / j)); System.out.println(" x / y = " + (x / y));

// resto da divisão System.out.println("Comuting the remainder..."); System.out.println(" i % j = " + (i % j)); System.out.println(" x % y = " + (x % y));

// misturando operações System.out.println("Mixing types..."); System.out.println(" j + y = " + (j + y)); System.out.println(" i * x = " + (i * x)); } }

e como saída, temos:

Variables values... i = 37 j = 42 x = 27.475 y = 7.22 Adding... i + j = 79 x + y = 34.695 Subtracting... i - j = -5 x - y = 20.255 Multiplying... i * j = 1554 x * y = 198.37 Dividing... i / j = 0 x / y = 3.8054 Comuting the remainder... i % j = 37 x % y = 5.815 Mixing types... j + y = 49.22 i * x = 1016.58

Nota: Quando um número de tipo inteiro e um outro de número fracionário são usados numa única operação, o resultado será dado pela variável de maior tipo, no caso, valor de número fracionário. O número inteiro é implicitamente convertido para o número fracionário antes da operação ter início.

Introdução à Programação I 19

Page 59: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

11. Operadores de Incremento e DecrementoAlém dos operadores aritméticos básicos, Java dá suporte ao operador unário de incremento (++) e ao operador unário de decremento (--). Operadores de incremento ou decremento aumentam ou diminuem em 1 o valor da variável. Por exemplo, a expressão,

count = count + 1; // incrementa o valor de count em 1

é equivalente a,

count++;

Operador Uso Descrição

++ op++ Incrementa op em 1; Avalia a expressão antes do valor ser acrescido

++ ++op Incrementa op em 1; Incrementa o valor antes da expressão ser avaliada

-- op-- Decrementa op em 1; Avalia a expressão antes do valor ser decrescido

-- --op Decrementa op em 1; Decrementa op em 1 antes da expressão ser avaliada

Tabela 5: Operadores de incremento e decremento

Como visto na tabela acima, os operadores de incremento e decremento podem ser usados tanto antes como após o operando. E sua utilização dependerá disso. Quando usado antes do operando, provoca acréscimo ou decréscimo de seu valor antes da avaliação da expressão em que ele aparece. Por exemplo:

int i = 10,int j = 3;int k = 0;k = ++j + i; //resultará em k = 4+10 = 14

Quando utilizado depois do operando, provoca, na variável, acréscimo ou decréscimo do seu valor após a avaliação da expressão na qual ele aparece. Por exemplo:

int i = 10,int j = 3;int k = 0;k = j++ + i; //resultará em k = 3+10 = 13

Dicas de programação:

1. Mantenha sempre as operações incluindo operadores de incremento ou decremento de forma simples e de fácil compreensão.

Introdução à Programação I 20

Page 60: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

12. Operadores Relacionais

Os operadores relacionais são usados para comparar dois valores e determinar o relacionamento entre eles. A saída desta avaliação será fornecida com um valor lógico: true ou false.

Operador Uso Descrição

> op1 > op2 op1 é maior do que op2

>= op1 >= op2 op1 é maior ou igual a op2

< op1 < op2 op1 é menor do que op2

<= op1 <= op2 op1 é menor ou igual a op2

== op1 == op2 op1 é igual a op2

!= op1 != op2 op1 não igual a op2

Tabela 6: Operadores relacionais

O programa a seguir, mostra a utilização destes operadores:

public class RelationalDemo { public static void main(String[] args) { // alguns números int i = 37; int j = 42; int k = 42; System.out.println("Variables values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" k = " + k);

// maior que System.out.println("Greater than..."); System.out.println(" i > j = " + (i > j)); //false System.out.println(" j > i = " + (j > i)); //true System.out.println(" k > j = " + (k > j)); //false

// maior ou igual a System.out.println("Greater than or equal to..."); System.out.println(" i >= j = " + (i >= j)); //false System.out.println(" j >= i = " + (j >= i)); //true System.out.println(" k >= j = " + (k >= j)); //true

// menor que System.out.println("Less than..."); System.out.println(" i < j = " + (i < j)); //true System.out.println(" j < i = " + (j < i)); //false System.out.println(" k < j = " + (k < j)); //false

// menor ou igual a System.out.println("Less than or equal to..."); System.out.println(" i <= j = " + (i <= j)); //true System.out.println(" j <= i = " + (j <= i)); //false

Introdução à Programação I 21

Page 61: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

System.out.println(" k <= j = " + (k <= j)); //true

// igual a System.out.println("Equal to..."); System.out.println(" i == j = " + (i == j)); //false System.out.println(" k == j = " + (k == j)); //true

// diferente System.out.println("Not equal to..."); System.out.println(" i != j = " + (i != j)); //true System.out.println(" k != j = " + (k != j)); //false

} }

A seguir temos a saída deste programa:

Variables values... i = 37 j = 42 k = 42 Greater than... i > j = false j > i = true k > j = false Greater than or equal to... i >= j = false j >= i = true k >= j = true Less than... i < j = true j < i = false k < j = false Less than or equal to... i <= j = true j <= i = false k <= j = true Equal to... i == j = false k == j = true Not equal to... i != j = true k != j = false

Introdução à Programação I 22

Page 62: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

13. Operadores Lógicos

Operadores lógicos avaliam um ou mais operandos lógicos que geram um único valor final true ou false como resultado da expressão. São seis os operadores lógicos: && (e lógico), & (e binário), || (ou lógico), | (ou binário), ^ (ou exclusivo binário) e ! (negação).

A operação básica para um operador lógico é:

x1 op x2

Onde x1 e x2 podem ser expressões, variáveis ou constantes lógicas, e op pode tanto ser &&, &, ||, | ou ^.

13.1. && (e lógico) e & (e binário)

x1 x2 ResultadoVERDADEIRO VERDADEIRO VERDADEIROVERDADEIRO FALSO FALSO

FALSO VERDADEIRO FALSOFALSO FALSO FALSO

Tabela 7: Tabela para && e &

A diferença básica do operador && para & é que o && suporta uma avaliação de curto-circuito (ou avaliação parcial), enquanto que o & não. O que isso significa?

Dado o exemplo:

exp1 && exp2

o operador e lógico irá avaliar a expressão exp1, e, imediatamente, retornará um valor false se a operação exp1 for falsa. Se a expressão exp1 resultar em um valor false o operador nunca avaliará a expressão exp2, pois o valor de toda a expressão será falsa mesmo que o resultado isolado de exp2 seja verdadeiro. Já o operador & sempre avalia as duas partes da expressão, mesmo que a primeira tenha o valor false.

O programa a seguir, mostra a utilização destes operadores:

public class TestAND {public static void main( String[] args ) {

int i = 0;int j = 10;boolean test = false;

// demonstração do operador &&test = (i > 10) && (j++ > 9);System.out.println(i);System.out.println(j);System.out.println(test);

// demonstração do operador &test = (i > 10) & (j++ > 9);System.out.println(i);System.out.println(j);System.out.println(test);

Introdução à Programação I 23

Page 63: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}}

Como resultado, o programa produzirá a seguinte saída:

010false011false

Note que o comando j++, na linha contendo &&, nunca será executado, pois o operador não o avalia, visto que a primeira parte da expressão (i>10) retorna um valor booleano false.

13.2. || ( ou lógico) e | ( ou binário)

x1 x2 ResultadoVERDADEIRO VERDADEIRO VERDADEIROVERDADEIRO FALSO VERDADEIRO

FALSO VERDADEIRO VERDADEIROFALSO FALSO FALSO

Tabela 8: Tabela para || e |

A diferença básica entre os operadores || e |, é que, semelhante ao operador &&, o || também suporta a avaliação parcial. O que isso significa?

Dada a expressão,

exp1 || exp2o operador ou lógico irá avaliar a expressão exp1, e, imediatamente, retornará um valor lógico true para toda a expressão se a primeira parte for avaliada como verdadeira. Se a expressão exp1 resultar em verdadeira a segunda parte exp2 nunca será avaliada, pois o valor final da expressão será true independentemente do resultado da segunda expressão.

O programa a seguir, mostra a utilização destes operadores:

public class TestOR {public static void main( String[] args ){

int i = 0;int j = 10;boolean test = false;

// demonstração do operador ||test = (i < 10) || (j++ > 9);System.out.println(i);System.out.println(j);System.out.println(test);

// demonstração do operador |test = (i < 10) | (j++ > 9);System.out.println(i);System.out.println(j);System.out.println(test);

}

Introdução à Programação I 24

Page 64: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}

Como resultado, o programa produzirá a seguinte saída:

010true011true

Note que a expressão j++ nunca será avaliada na instrução que usa o operador ||, pois a primeira parte da expressão (i<10) já retorna true como valor final da expressão.

13.3. ^ (ou exclusivo binário)

x1 x2 ResultadoVERDADEIRO VERDADEIRO FALSOVERDADEIRO FALSO VERDADEIRO

FALSO VERDADEIRO VERDADEIROFALSO FALSO FALSO

Tabela 9: Tabela para o operador ^

O resultado de uma expressão usando o operador ou exclusivo binário terá um valor true somente se uma das expressões for verdadeira e a outra falsa. Note que ambos os operandos são necessariamente avaliados pelo operador ^.

O programa a seguir, mostra a utilização deste operador:

public class TestXOR {public static void main( String[] args ){

boolean val1 = true;boolean val2 = true;System.out.println(val1 ^ val2);

val1 = false;val2 = true;System.out.println(val1 ^ val2);

val1 = false;val2 = false;System.out.println(val1 ^ val2);

val1 = true;val2 = false;System.out.println(val1 ^ val2);

}}

Como resultado, o programa produzirá a seguinte saída:

falsetruefalsetrue

Introdução à Programação I 25

Page 65: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

13.4. ! (negação)

x1 ResultadoVERDADEIRO FALSO

FALSO VERDADEIROTabela 10: Tabela para o operador !

O operador de negação inverte o resultado lógico de uma expressão, variável ou constante, ou seja, o que era verdadeiro será falso e vice-versa.

O programa a seguir, mostra a utilização deste operador:

public class TestNOT {public static void main( String[] args ){

boolean val1 = true;boolean val2 = false;System.out.println(!val1);System.out.println(!val2);

}}

Como resultado, o programa produzirá a seguinte saída:

falsetrue

Introdução à Programação I 26

Page 66: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

14. Operador Condicional ( ?: )

O operador condicional é também chamado de operador ternário. Isto significa que ele tem 3 argumentos que juntos formam uma única expressão condicional. A estrutura de uma expressão utilizando um operador condicional é a seguinte:

exp1?exp2:exp3

Onde exp1 é uma expressão lógica que deve retornar true ou false. Se o valor de exp1 for verdadeiro, então, o resultado será a expressão exp2, caso contrário, o resultado será exp3.

O programa a seguir, mostra a utilização deste operador:

public class ConditionalOperator {public static void main( String[] args ){

String status = "";int grade = 80;

//status do alunostatus = (grade >= 60)?"Passed":"Fail";//print statusSystem.out.println( status );

}}

Como resultado, o programa produzirá a seguinte saída:

Passed

Veremos na Figura 2 um fluxograma que demonstra como o operador condicional funciona.

Figura 2: Fluxograma utilizando o operador condicional

Veremos outro programa que também utiliza o operador condicional:

public class ConditionalOperator {public static void main( String[] args ){

int score = 0;char answer = 'a';

Introdução à Programação I 27

Page 67: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

score = (answer == 'a') ? 10 : 0;System.out.println("Score = " + score );

}}

Como resultado, o programa produzirá a seguinte saída:

Score = 10

Introdução à Programação I 28

Page 68: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

15. Precedência de Operadores

A precedência serve para indicar a ordem na qual o compilador interpretará os diferentes tipos de operadores, para que ele sempre tenha como saída um resultado coerente e não ambíguo.

Ordem Operador

1 ( ) parênteses

2 ++ pós-incremento e -- pós-decremento

3 ++ pré-incremento e -- pré-decremento

4 ! negação lógica

5 * multiplicação e / divisão

6 % resto da divisão

7 + soma e – subtração

8 < menor que, <= menor ou igual, > maior que e >= maior ou igual

9 == igual e != não igual

10 & e binário

11 | ou binário

12 ^ ou exclusivo binário

13 && e lógico

14 || ou lógico

15 ?: condicional

16 = atribuição

Tabela 11: Precedência de operadores

No caso de dois operadores com mesmo nível de precedência, terá prioridade o que estiver mais à esquerda da expressão. Dada uma expressão complexa como:

6%2*5+4/2+88-10

O ideal seria fazer uso de parênteses para reescrevê-la de maneira mais clara:

((6%2)*5)+(4/2)+88-10

Dicas de programação:

1. Para evitar confusão na avaliação de suas expressões matemáticas, deixe-as o mais simples possível e use parênteses.

Introdução à Programação I 29

Page 69: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

16. Exercícios

16.1. Declarar e mostrar variáveis

Dada a tabela abaixo, declare as variáveis que se seguem de acordo com seus tipos correspondentes e valores iniciais. Exiba o nomes e valor das variáveis.

Nome das Variáveis Tipo do dado Valor inicialnumber integer 10letter character aresult boolean truestr String hello

O resultado esperado do exercício é:

number = 10 letter = a result = true str = hello

16.2. Obter a média entre três números

Crie um programa que obtenha a média de 3 números. Considere o valor para os três números como sendo 10, 20 e 45. O resultado esperado do exercício é:

número 1 com o valor 10 número 2 com o valor 20 número 3 com o valor 45 A média é 25

16.3. Exibir o maior valor

Dados três números, crie um programa que exiba na tela o maior dentre os números informados. Use o operador ?: que já foi estudado nesta sessão (dica: será necessário utilizar dois operadores ?: para se chegar ao resultado). Por exemplo, dados os números 10, 23 e 5, o resultado esperado do exercício deve ser:

número 1 com o valor 10 número 2 com o valor 23 número 3 com o valor 5 O maior número é 23

16.4. Precedência de operadores

Dadas as expressões abaixo, reescreva-as utilizando parênteses de acordo com a forma como elas são interpretadas pelo compilador.

1. a / b ^ c ^ d – e + f – g * h + i2. 3 * 10 *2 / 15 – 2 + 4 ^ 2 ^ 23. r ^ s * t / u – v + w ^ x – y++

Introdução à Programação I 30

Page 70: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 5Capturando entrada de dados através do

teclado

Versão 1.0 - Jan/2007

Page 71: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Agora que já estudamos alguns conceitos básicos e escrevemos alguns códigos simples, vamos fazer as aplicações ficarem mais interativas começando com a captura de dados digitados pelo usuário. Nesta lição, discutiremos três modos de obter dados de entrada (input). O primeiro é através do uso da classe BufferedReader do pacote java.util; o segundo, através do uso da nova classe Scanner no mesmo pacote; e, por fim, envolveremos a utilização da interface gráfica utilizando JOptionPane.

Ao final desta lição, o estudante será capaz de:

• Criar códigos para a captura de dados pelo teclado.

• Usar a classe BufferedReader para captura, através de uma janela de console, dos dados

digitados no teclado.

• Utilizar a classe Scanner para captura, através de uma janela de console, dos dados

digitados no teclado.

• Utilizar a classe JOptionPane para captura, através da uma interface gráfica, dos dados

digitados no teclado.

Introdução à Programação I 4

Page 72: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. BufferedReader para capturar dados

Primeiramente, utilizaremos a classe BufferedReader do pacote java.io para capturar dados de entrada através do teclado.

Passos para capturar os dados digitados, tomemos por base o programa visto na lição anterior:

1. Digite a seguinte instrução no início do programa:

import java.io.*;

2. Adicione as seguintes instruções no corpo do método main:

BufferedReader dataIn = new BufferedReader( new InputStreamReader(System.in));

3. Declare uma variável temporária do tipo String para gravar os dados digitados pelo usuário e chame o método readLine() que vai capturar linha por linha do que o usuário digitar. Isso deverá ser escrito dentro de um bloco try-catch para tratar possíveis exceções.

try { String temp = dataIn.readLine();} catch (IOException e) { System.out.println("Error in getting input");}

Abaixo, segue o programa completo:

import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;

public class GetInputFromKeyboard {public static void main(String[] args) {BufferedReader dataIn = new BufferedReader(new

InputStreamReader(System.in));String name = "";System.out.print("Please Enter Your Name:");try { name = dataIn.readLine();

} catch (IOException e) { System.out.println("Error!");

}System.out.println("Hello " + name +"!");

}}

Faremos uma análise deste programa linha por linha:

import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;

Estas linhas acima mostram que estamos utilizando as classes BufferedReader, InputStreamReader e IOException cada qual dentro do pacote java.io. Essas APIs ou

Introdução à Programação I 5

Page 73: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Interfaces de Programação de Aplicações (Application Programming Interface) contêm centenas de classes pré-definidas que se pode usar nos programas. Essas classes são organizadas dentro do que chamamos de pacotes.

Pacotes contêm classes que se relacionam com um determinado propósito. No exemplo, o pacote java.io contém as classes que permitem capturar dados de entrada e saída. Estas linhas poderiam ser reescritas da seguinte forma:

import java.io.*;

que importará todas as classes encontradas no pacote java.io, deste modo é possível utilizar todas classes desse pacote no programa.

As próximas linhas:

public class GetInputFromKeyboard {public static void main( String[] args ) {

já foram discutidas na lição anterior. Isso significa que declaramos uma classe nomeada GetInputFromKeyboard e, em seguida, iniciamos o método principal (main).

Na instrução:

BufferedReader dataIn = new BufferedReader(new InputStreamReader(System.in));

declaramos a variável dataIn do tipo BufferedReader. Não se preocupe com o significado da sintaxe, pois será abordado mais à frente.

A seguir, declaramos a variável name do tipo String:

String name = "";

na qual armazenaremos a entrada de dados digitada pelo usuário. Note que foi inicializada como uma String vazia "". É uma boa prática de programação inicializar as variáveis quando declaradas.

Na próxima instrução, solicitamos que o usuário escreva um nome:

System.out.print("Please Enter Your Name:");

As seguinte linhas definem um bloco try-catch:

try {name = dataIn.readLine();

} catch (IOException e) {System.out.println("Error!");

}

que asseguram, caso ocorram exceções serão tratadas.

Falaremos sobre o tratamento de exceções na última parte deste curso. Por hora, é necessário adicionar essas linhas para utilizar o método readLine() e receber a entrada de dados do usuário.

Em seguida:

Introdução à Programação I 6

Page 74: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

name = dataIn.readLine();

capturamos a entrada dos dados digitados pelo usuário e as enviamos para a variável String criada anteriormente. A informação é guardada na variável name.

Como última instrução:

System.out.println("Hello " + name + "!");

montamos a mensagem final para cumprimentar o usuário.

Introdução à Programação I 7

Page 75: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Classe Scanner para capturar dados

Vimos uma maneira para obter dados de entrada através do teclado. O JDK 5.0 lançou uma nova classe chamada Scanner que engloba diversos métodos para facilitar este serviço.

Abaixo, segue o programa completo utilizando esta classe:

import java.util.Scanner;

public class GetInputFromScanner{

public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("Please Enter Your Name:");String name = sc.next(); System.out.println("Hello " + name +"!");

}}

Compare-o com o programa visto anteriormente. Percebe-se que fica mais simples conseguir a mesma funcionalidade.

Inicialmente, definimos a chamada ao pacote que contém a classe Scanner:

import java.util.Scanner;

Em seguida, as instruções que define a classe e o método main:

public class GetInputFromScanner{

public static void main(String[] args) {

Definimos uma variável, denominada sc, que será criada a partir da classe Scanner e direcionada para a entrada padrão:

Scanner sc = new Scanner(System.in);

De forma semelhante, mostramos uma mensagem solicitando informação do usuário:

System.out.println("Please Enter Your Name:");

Utilizamos a variável sc para chamarmos o método que fará o recebimento dos dados digitados:

String name = sc.nextLine();

A classe Scanner possui diversos métodos que podem ser utilizados para realizar este serviço. Os principais métodos que podemos utilizar, neste caso, são:

Método Finalidade

next() Aguarda uma entrada em formato String

nextInt() Aguarda uma entrada em formato Inteiro

nextByte() Aguarda uma entrada em formato Inteiro

Introdução à Programação I 8

Page 76: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

nextLong() Aguarda uma entrada em formato Inteiro Longo

nextFloat() Aguarda uma entrada em formato Número Fracionário

nextDouble() Aguarda uma entrada em formato Número Fracionário

Tabela 1: Métodos da Classe Scanner para obter dados

Por fim, mostramos o resultado e encerramos o método main e a classe:

System.out.println("Hello " + name +"!");}

}

Introdução à Programação I 9

Page 77: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Utilizando a JOptionPane para receber dadosUm outro modo de receber os dados de entrada é utilizar a classe JOptionPane, que pertence ao pacote javax.swing. A JOptionPane possui métodos que conseguem criar caixas de diálogo na qual o usuário pode informar ou visualizar algum dado.

Dado o seguinte código:

import javax.swing.JOptionPane;

public class GetInputFromKeyboard { public static void main( String[] args ){

String name = "";name = JOptionPane.showInputDialog("Please enter your name");String msg = "Hello " + name + "!";JOptionPane.showMessageDialog(null, msg);

}}

esta classe apresentará o seguinte resultado:

Figura 1: Aguardando dados no JOptionPane

Figura 2: Digitando florence no JOptionPane

Figura 3: Respondendo com JOptionPane

A primeira instrução:

import javax.swing.JOptionPane;

mostra que estamos importando a classe JOptionPane do pacote javax.swing.

Poderíamos, de forma semelhante, escrever estas instruções do seguinte modo:

Introdução à Programação I 10

Page 78: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

import javax.swing.*;

A instrução seguinte:

name = JOptionPane.showInputDialog("Please enter your name");

cria uma caixa de entrada que exibirá um diálogo com uma mensagem, um campo de texto para receber os dados do usuário e um botão OK, conforme mostrado na figura 1. O resultado será armazenado na variável do tipo String name.

Na próxima instrução, criamos uma mensagem de cumprimento, que ficará armazenada na variável msg:

String msg = "Hello " + name + "!";

Finalizando a classe, exibiremos uma janela de diálogo que conterá a mensagem e o botão de OK, conforme mostrado na figura 3.

JOptionPane.showMessageDialog(null, msg);

Introdução à Programação I 11

Page 79: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Exercícios

5.1. As 3 palavras (versão Console)

Utilizando a classe BufferedReader ou Scanner, capture três palavras digitadas pelo usuário e mostre-as como uma única frase na mesma linha. Por exemplo:

Palavra 1: GoodbyePalavra 2: andPalavra 3: Hello

Goodbye and Hello

5.2. As 3 palavras (versão Interface Gráfica)

Utilizando a classe JOptionPane, capture palavras em três caixas de diálogos distintas e mostre-as como uma única frase. Por exemplo:

Figura 4: Primeira Palavra

Figura 5: Segunda Palavra

Figura 6: Terceira Palavra

Figura 7: Mostrando a Mensagem

Introdução à Programação I 12

Page 80: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 6Estruturas de controle

Versão 1.01 - Fev/2008

Page 81: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nas lições anteriores, foram mostrados programas seqüenciais, onde as instruções foram executadas uma após a outra de forma fixa. Nesta lição, discutiremos estruturas de controle que permitem mudar a ordem na qual as instruções são executadas.

Ao final desta lição, o estudante será capaz de:

• Usar estruturas de controle de decisão (if e switch) que permitem a seleção de partes

específicas do código para execução

• Usar estruturas de controle de repetição (while, do-while e for) que permitem a

repetição da execução de partes específicas do código

• Usar declarações de interrupção (break, continue e return) que permitem o

redirecionamento do fluxo do programa

Introdução à Programação I 4

Page 82: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Estruturas de controle de decisão

Estruturas de controle de decisão são instruções em linguagem Java que permitem que blocos específicos de código sejam escolhidos para serem executados, redirecionando determinadas partes do fluxo do programa.

2.1. Declaração if A declaração if especifica que uma instrução ou bloco de instruções seja executado se, e somente se, uma expressão lógica for verdadeira.

A declaração if possui a seguinte forma:

if (expressão_lógica) instrução;

ou:

if (expressão_lógica) { instrução1; instrução2 ... }

onde, expressão_lógica representa uma expressão ou variável lógica.

Figura 1: Fluxograma da declaração if

Por exemplo, dado o trecho de código:

int grade = 68;if (grade > 60) System.out.println("Congratulations!");

ou:int grade = 68;if (grade > 60) {

System.out.println("Congratulations!");System.out.println("You passed!");

}

Introdução à Programação I 5

Page 83: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. Expressão lógica é uma declaração que possui um valor lógico. Isso significa que a execução desta expressão deve resultar em um valor true ou false.

2. Coloque as instruções de forma que elas façam parte do bloco if. Por exemplo:

if (expressão_lógica) { // instrução1; // instrução2;}

2.2. Declaração if-else

A declaração if-else é usada quando queremos executar determinado conjunto de instruções se a condição for verdadeira e outro conjunto se a condição for falsa.

Possui a seguinte forma:

if (expressão_lógica) instrução_caso_verdadeiro;else instrução_caso_falso;

Também podemos escrevê-la na forma abaixo:

if (expressão_lógica) { instrução_caso_verdadeiro1; instrução_caso_verdadeiro2; ... } else { instrução_caso_falso1; instrução_caso_falso2; ... }

Por exemplo, dado o trecho de código:

int grade = 68;if (grade > 60) System.out.println("Congratulations! You passed!");else System.out.println("Sorry you failed");

ou:

int grade = 68;if (grade > 60) { System.out.print("Congratulations! "); System.out.println("You passed!");} else { System.out.print("Sorry "); System.out.println("you failed");}

Introdução à Programação I 6

Page 84: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. Para evitar confusão, sempre coloque a instrução ou instruções contidas no bloco if ou if-else entre chaves {}.

2. Pode-se ter declarações if-else dentro de declarações if-else, por exemplo:

if (expressão_lógica) { if (expressão_lógica) { ... } else { ... }} else { ...}

2.3. Declaração if-else-if A declaração else pode conter outra estrutura if-else. Este cascateamento de estruturas permite ter decisões lógicas muito mais complexas.

A declaração if-else-if possui a seguinte forma:

if (expressão_lógica1) instrução1;else if(expressão_lógica2) instrução2;else instrução3;

Podemos ter várias estruturas else-if depois de uma declaração if. A estrutura else é opcional e pode ser omitida. No exemplo mostrado acima, se a expressão_lógica1 é verdadeira, o programa executa a instrução1 e salta as outras instruções. Caso contrário, se a expressão_lógica1 é falsa, o fluxo de controle segue para a análise da expressão_lógica2. Se esta for verdadeira, o programa executa a instrução2 e salta a instrução3. Caso contrário, se a expressão_lógica2 é falsa, então a instrução3 é executada.

Introdução à Programação I 7

Figura 2: Fluxograma da declaração if-else

Page 85: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Observe um exemplo da declaração if-else-if no seguinte trecho de código:

public class Grade { public static void main( String[] args ) { double grade = 92.0; if (grade >= 90) { System.out.println("Excellent!"); } else if((grade < 90) && (grade >= 80)) { System.out.println("Good job!"); } else if((grade < 80) && (grade >= 60)) { System.out.println("Study harder!"); } else { System.out.println("Sorry, you failed."); } }}

2.4. Erros comuns na utilização da declaração if

1. A condição na declaração if não avalia um valor lógico. Por exemplo:

// ERRADO int number = 0; if (number) { // algumas instruções aqui}

a variável number não tem valor lógico.

2. Usar = (sinal de atribuição) em vez de == (sinal de igualdade) para comparação. Por exemplo:

Introdução à Programação I 8

Figura 3: Fluxograma da declaração if-else-if

Page 86: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

// ERRADO int number = 0; if (number = 0) { // algumas instruções aqui}

3. Escrever elseif em vez de else if.

// ERRADO int number = 0; if (number == 0) { // algumas instruções aqui} elseif (number == 1) { // algumas instruções aqui}

2.5. Declaração switch

Outra maneira de indicar uma condição é através de uma declaração switch. A construção switch permite que uma única variável inteira tenha múltiplas possibilidades de finalização.

A declaração switch possui a seguinte forma:

switch (variável_inteira) { case valor1: instrução1; // instrução2; // bloco 1 ... // break; case valor2: instrução1; // instrução2; // bloco 2 ... // break; default: instrução1; // instrução2; // bloco n ... // break;}

onde, variável_inteira é uma variável de tipo byte, short, char ou int. valor1, valor2, e assim por diante, são valores constantes que esta variável pode assumir.

Quando a declaração switch é encontrada, o fluxo de controle avalia inicialmente a variável_inteira e segue para o case que possui o valor igual ao da variável. O programa executa todas instruções a partir deste ponto, mesmo as do próximo case, até encontrar uma instrução break, que interromperá a execução do switch.

Se nenhum dos valores case for satisfeito, o bloco default será executado. Este é um bloco opcional. O bloco default não é obrigatório na declaração switch.

Introdução à Programação I 9

Page 87: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Notas:

1. Ao contrário da declaração if, múltiplas instruções são executadas sem a necessidade das chaves que determinam o início e término de bloco {}.

2. Quando um case for selecionado, todas as instruções vinculadas ao case serão executadas. Além disso, as instruções dos case seguintes também serão executadas.

3. Para prevenir que o programa execute instruções dos outros case subseqüentes, utilizamos a declaração break após a última instrução de cada case.

Dicas de Programação:

1. A decisão entre usar uma declaração if ou switch é subjetiva. O programador pode decidir com base na facilidade de entendimento do código, entre outros fatores.

2. Uma declaração if pode ser usada para decisões relacionadas a conjuntos, escalas de variáveis ou condições, enquanto que a declaração switch pode ser utilizada para situações que envolvam variável do tipo inteiro. Também é necessário que o valor de cada cláusula case seja único.

2.6. Exemplo para switchpublic class Grade { public static void main(String[] args) {

Introdução à Programação I 10

Figura 4: Fluxograma da declaração switch

Page 88: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

int grade = 92; switch(grade) { case 100: System.out.println("Excellent!"); break;

case 90: System.out.println("Good job!"); break; case 80: System.out.println("Study harder!"); break; default: System.out.println("Sorry, you failed."); } } }

Compile e execute o programa acima e veremos que o resultado será:

Sorry, you failed.

pois a variável grade possui o valor 92 e nenhuma das opções case atende a essa condição. Note que para o caso de intervalos a declaração if-else-if é mais indicada.

Introdução à Programação I 11

Page 89: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Estruturas de controle de repetição

Estruturas de controle de repetição são comandos em linguagem Java que permitem executar partes específicas do código determinada quantidade de vezes. Existem 3 tipos de estruturas de controle de repetição: while, do-while e for.

3.1. Declaração while A declaração while executa repetidas vezes um bloco de instruções enquanto uma determinada condição lógica for verdadeira.

A declaração while possui a seguinte forma:

while (expressão_lógica) { instrução1; instrução2; ...}

Figura 5: Fluxograma da declaração while

As instruções contidas dentro do bloco while são executadas repetidas vezes enquanto o valor de expressão_lógica for verdadeira.

Por exemplo, dado o trecho de código:

int i = 4;while (i > 0){ System.out.print(i); i--;}

O código acima irá imprimir 4321 na tela. Se a linha contendo a instrução i-- for removida, teremos uma repetição infinita, ou seja, um código que não termina. Portanto, ao usar laços while, ou qualquer outra estrutura de controle de repetição, tenha a certeza de utilizar uma estrutura de repetição que encerre em algum momento.

Abaixo, temos outros exemplos de declarações while:

Exemplo 1:

int x = 0; while (x<10) { System.out.println(x);

Introdução à Programação I 12

Page 90: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

x++; }

Exemplo 2:

// laço infinito while (true) System.out.println("hello");

Exemplo 3:

// a instrução do laço não será executada while (false) System.out.println("hello");

3.2. Declaração do-whileA declaração do-while é similar ao while. As instruções dentro do laço do-while serão executadas pelo menos uma vez.

A declaração do-while possui a seguinte forma:

do { instrução1; instrução2; ...} while (expressão_lógica);

Figura 6: Fluxograma da declaração do-while

Inicialmente, as instruções dentro do laço do-while são executadas. Então, a condição na expressão_lógica é avaliada. Se for verdadeira, as instruções dentro do laço do-while serão executadas novamente.

A diferença entre uma declaração while e do-while é que, no laço while, a avaliação da expressão lógica é feita antes de se executarem as instruções nele contidas enquanto que, no laço do-while, primeiro se executam as instruções e depois realiza-se a avaliação da expressão lógica, ou seja, as instruções dentro em um laço do-while são executadas pelo menos uma vez.

Abaixo, temos alguns exemplos que usam a declaração do-while:

Exemplo 1:

int x = 0;

Introdução à Programação I 13

Page 91: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

do { System.out.println(x); x++; } while (x<10);

Este exemplo terá 0123456789 escrito na tela.

Exemplo 2:

// laço infinitodo { System.out.println("hello");} while(true);

Este exemplo mostrará a palavra hello escrita na tela infinitas vezes.

Exemplo 3:

// Um laço executado uma vezdo System.out.println(“hello”);while (false);

Este exemplo mostrará a palavra hello escrita na tela uma única vez.

Dicas de programação:

1. Erro comum de programação ao utilizar o laço do-while é esquecer o ponto-e-vírgula (;) após a declaração while.

do { ...} while (boolean_expression) // ERRADO -> faltou ;

2. Como visto para a declaração while, tenha certeza que a declaração do-while poderá terminar em algum momento.

3.3. Declaração forA declaração for, como nas declarações anteriores, permite a execução do mesmo código uma quantidade determinada de vezes.

A declaração for possui a seguinte forma:

for (declaração_inicial; expressão_lógica; salto) { instrução1; instrução2; ...}

onde:

declaração_inicial – inicializa uma variável para o laçoexpressão_lógica – compara a variável do laço com um valor limite

Introdução à Programação I 14

Page 92: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

salto – atualiza a variável do laço

Figura 7: Fluxograma da declaração for

Um exemplo para a declaração for é:

for (int i = 0; i < 10; i++) { System.out.print(i);}

Neste exemplo, uma variável i, do tipo int, é inicializada com o valor zero. A expressão lógica "i é menor que 10" é avaliada. Se for verdadeira, então a instrução dentro do laço é executada. Após isso, a expressão i terá seu valor adicionado em 1 e, novamente, a condição lógica será avaliada. Este processo continuará até que a condição lógica tenha o valor falso.

Este mesmo exemplo, utilizando a declaração while, é mostrado abaixo:

int i = 0;while (i < 10) { System.out.print(i); i++;}

Introdução à Programação I 15

Page 93: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Declarações de Interrupção

Declarações de interrupção permitem que redirecionemos o fluxo de controle do programa. A linguagem Java possui três declarações de interrupção. São elas: break, continue e return.

4.1. Declaração break A declaração break possui duas formas: unlabeled (não identificada - vimos esta forma com a declaração switch) e labeled (identificada).

4.1.1. Declaração unlabeled break

A forma unlabeled de uma declaração break encerra a execução de um switch e o fluxo de controle é transferido imediatamente para o final deste. Podemos também utilizar a forma para terminar declarações for, while ou do-while.

Por exemplo:

String names[] = {"Beah", "Bianca", "Lance", "Belle", "Nico", "Yza", "Gem", "Ethan"};

String searchName = "Yza";boolean foundName = false;for (int i=0; i < names.length; i++) { if (names[i].equals(searchName)) { foundName = true; break; }}if (foundName) { System.out.println(searchName + " found!");} else { System.out.println(searchName + " not found.");}

Neste exemplo, se a String “Yza” for encontrada, a declaração for será interrompida e o controle do programa será transferido para a próxima instrução abaixo da declaração for.

4.1.2. Declaração labeled break

A forma labeled de uma declaração break encerra o processamento de um laço que é identificado por um label especificado na declaração break.

Um label, em linguagem Java, é definido colocando-se um nome seguido de dois-pontos, como por exemplo:

teste:

esta linha indica que temos um label com o nome teste.

O programa a seguir realiza uma pesquisa de um determinado valor em um array bidimensional. Dois laços são criados para percorrer este array. Quando o valor é encontrado, um labeled break termina a execução do laço interno e retorna o controle para o laço mais externo.

int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};int searchNum = 5;

Introdução à Programação I 16

Page 94: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

boolean foundNum = false;searchLabel: for (int i=0; i<numbers.length; i++) { for (int j=0; j<numbers[i].length; j++) { if (searchNum == numbers[i][j]) { foundNum = true; break searchLabel; } } // final do laço j} // final do laço iif (foundNum) { System.out.println(searchNum + " found!");} else { System.out.println(searchNum + " not found!");}

A declaração break, ao terminar a declaração for, não transfere o controle do programa ao final de seu laço, controlado pela variável j. O controle do programa segue imediatamente para a declaração for marcada com o label, neste caso, interrompendo o laço controlado pela variável i.

4.2. Declaração continueA declaração continue tem duas formas: unlabeled e labeled. Utilizamos uma declaração continue para saltar a repetição atual de declarações for, while ou do-while.

4.2.1. Declaração unlabeled continue

A forma unlabeled salta as instruções restantes de um laço e avalia novamente a expressão lógica que o controla. O exemplo seguinte conta a quantidade de vezes que a expressão "Beah" aparece no array.

String names[] = {"Beah", "Bianca", "Lance", "Beah"};int count = 0;for (int i=0; i < names.length; i++) { if (!names[i].equals("Beah")) { continue; // retorna para a próxima condição } count++;}System.out.println(count + " Beahs in the list");

4.2.2. Declaração labeled continue

A forma labeled da declaração continue interrompe a repetição atual de um laço e salta para a repetição exterior marcada com o label indicado.

outerLoop: for (int i=0; i<5; i++) { for (int j=0; j<5; j++) { System.out.println("Inside for(j) loop"); // mensagem1 if (j == 2) continue outerLoop;

}System.out.println("Inside for(i) loop"); // mensagem2

}

Neste exemplo, a mensagem 2 nunca será mostrada, pois a declaração continue outerloop interromperá este laço cada vez que j atingir o valor 2 do laço interno.

Introdução à Programação I 17

Page 95: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.3. Declaração returnA declaração return é utilizada para sair de um método. O fluxo de controle retorna para a declaração que segue a chamada do método original. A declaração de retorno possui dois modos: o que retorna um valor e o que não retorna nada. Para retornar um valor, escreva o valor (ou uma expressão que calcula este valor) depois da palavra chave return. Por exemplo:

return ++count;ou

return "Hello";

Os dados são processados e o valor é devolvido de acordo com o tipo de dado do método. Quando um método não tem valor de retorno, deve ser declarado como void. Use a forma de return que não devolve um valor. Por exemplo:

return;

Abordaremos as declarações return nas próximas lições, quando falarmos sobre métodos.

Introdução à Programação I 18

Page 96: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Exercícios

5.1. NotasObtenha do usuário três notas de exame e calcule a média dessas notas. Reproduza a média dos três exames. Junto com a média, mostre também um :-) no resultado se a média for maior ou igual a 60; caso contrário mostre :-(

Faça duas versões deste programa:

1. Use a classe BufferedReader (ou a classe Scanner) para obter as notas do usuário, e System.out para mostrar o resultado.

2. Use JOptionPane para obter as notas do usuário e para mostrar o resultado.

5.2. Número por ExtensoSolicite ao usuário para digitar um número, e mostre-o por extenso. Este número deverá variar entre 1 e 10. Se o usuário introduzir um número que não está neste intervalo, mostre: "número inválido".

Faça duas versões deste programa:

1. Use uma declaração if-else-if para resolver este problema 2. Use uma declaração switch para resolver este problema

5.3. Cem vezesCrie um programa que mostre seu nome cem vezes. Faça três versões deste programa:

1. Use uma declaração while para resolver este problema 2. Use uma declaração do-while para resolver este problema3. Use uma declaração for para resolver este problema

5.4. PotênciasReceba como entrada um número e um expoente. Calcule este número elevado ao expoente. Faça três versões deste programa:

1. Use uma declaração while para resolver este problema 2. Use uma declaração do-while para resolver este problema3. Use uma declaração for para resolver este problema

Introdução à Programação I 19

Page 97: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 7Array em Java

Versão 1.01 - Fev/2008

Page 98: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição, abordaremos Array em Java. Primeiro, definiremos o que é array e, então, discutiremos como declará-los e usá-los.

Ao final desta lição, o estudante será capaz de:

• Declarar e criar array

• Acessar elementos de um array

• Determinar o número de elementos de um array

• Declarar e criar array multidimensional

Introdução à Programação I 4

Page 99: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Introdução a Array

Em lições anteriores, discutimos como declarar diferentes variáveis usando os tipos de dados primitivos. Na declaração de variáveis, freqüentemente utilizamos um identificador ou um nome e um tipo de dados. Para se utilizar uma variável, deve-se chamá-la pelo nome que a identifica.

Por exemplo, temos três variáveis do tipo int com diferentes identificadores para cada variável:

int number1;int number2;int number3;

number1 = 1;number2 = 2;number3 = 3;

Como se vê, inicializar e utilizar variáveis pode torna-se uma tarefa tediosa, especialmente se elas forem utilizadas para o mesmo objetivo. Em Java, e em outras linguagens de programação, pode-se utilizar uma variável para armazenar e manipular uma lista de dados com maior eficiência. Este tipo de variável é chamado de array.

Um array armazena múltiplos itens de um mesmo tipo de dado em um bloco contínuo de memória, dividindo-o em certa quantidade de posições. Imagine um array como uma variável esticada – que tem um nome que a identifica e que pode conter mais de um valor para esta mesma variável.

Introdução à Programação I 5

Figura 1: Exemplo de um array de inteiros

Page 100: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Declarando Array

Array precisa ser declarados como qualquer variável. Ao declarar um array, defina o tipo de dados deste seguido por colchetes [] e pelo nome que o identifica. Por exemplo:

int [] ages;

ou colocando os colchetes depois do identificador. Por exemplo:

int ages[];

Depois da declaração, precisamos criar o array e especificar seu tamanho. Este processo é chamado de construção (a palavra, em orientação a objetos, para a criação de objetos). Para se construir um objeto, precisamos utilizar um construtor. Por exemplo:

// declaraçãoint ages[];

// construindoages = new int[100];

ou, pode ser escrito como:

// declarar e construirint ages[] = new int[100];

No exemplo, a declaração diz ao compilador Java que o identificador ages será usado como um nome de um array contendo inteiros, usado para criar, ou construir, um novo array contendo 100 elementos.

Em vez de utilizar uma nova linha de instrução para construir um array, também é possível automaticamente declarar, construir e adicionar um valor uma única vez.

Exemplos:

// criando um array de valores lógicos em uma variável// results. Este array contém 4 elementos que são// inicializados com os valores {true, false, true, false}boolean results[] ={ true, false, true, false };

// criando um array de 4 variáveis double inicializados// com os valores {100, 90, 80, 75};double []grades = {100, 90, 80, 75};

// criando um array de Strings com identificador days e// também já inicializado. Este array contém 7 elementosString days[] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};

Uma vez que tenha sido inicializado, o tamanho de um array não pode ser modificado, pois é armazenado em um bloco contínuo de memória.

Introdução à Programação I 6

Figura 2: Instanciando Arrays

Page 101: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Acessando um elemento do Array

Para acessar um elemento do array, ou parte de um array, utiliza-se um número inteiro chamado de índice.

Um índice é atribuído para cada membro de um array, permitindo ao programa e ao programador acessar os valores individualmente quando necessário. Os números dos índices são sempre inteiros. Eles começam com zero e progridem seqüencialmente por todas as posições até o fim do array. Lembre-se que os elementos dentro do array possuem índice de 0 a tamanhoDoArray-1.

Por exemplo, dado o array ages que declaramos anteriormente, temos:

// atribuir 10 ao primeiro elemento do arrayages[0] = 10;

// imprimir o último elemento do arraySystem.out.print(ages[99]);

Lembre-se que o array, uma vez declarado e construído, terá o valor de cada membro inicializado automaticamente. Conforme a seguinte tabela:

Tipo primitivo Iniciado com

boolean false

byte, short e int 0

char '\u0000'

long 0L

float 0.0F

double 0.0Tabela 1: Valor de inicialização automatica para os tipos primitivos

Entretanto, tipos de dados por referência, como as Strings, não serão inicializados caracteres em branco ou com uma string vazia "", serão inicializados com o valor null. Deste modo, o ideal é preencher os elementos do arrays de forma explícita antes de utilizá-los. A manipulação de objetos nulos pode causar a desagradável surpresa de uma exceção do tipo NullPointerException, por exemplo, ao tentar executar algum método da classe String, conforme o exemplo a seguir:

public class ArraySample { public static void main(String[] args){ String [] nulls = new String[2]; System.out.print(nulls[0]); // Linha correta, mostra null System.out.print(nulls[1].trim()); // Causa erro }}

O código abaixo utiliza uma declaração for para mostrar todos os elementos de um array.

public class ArraySample { public static void main(String[] args){ int[] ages = new int[100]; for (int i = 0; i < 100; i++) { System.out.print(ages[i]);

Introdução à Programação I 7

Page 102: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} }}

Dicas de programação:

1. Normalmente, é melhor inicializar, ou instanciar, um array logo após declará-lo. Por exemplo, a instrução:

int []arr = new int[100];

é preferível, ao invés de:

int [] arr;arr = new int[100];

2. Os elementos de um array de n elementos tem índices de 0 a n-1. Note que não existe o elemento arr[n]. A tentativa de acesso a este elemento causará uma exceção do tipo ArrayIndexOutOfBoundsException, pois o índice deve ser até n-1.

3. Não é possível modificar o tamanho de um array.

Introdução à Programação I 8

Page 103: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Tamanho de Array

Para se obter o número de elementos de um array, pode-se utilizar o atributo length. O atributo length de um array retorna seu tamanho, ou seja, a quantidade de elementos. É utilizado como no código abaixo:

nomeArray.length

Por exemplo, dado o código anterior, podemos reescrevê-lo como:

public class ArraySample { public static void main (String[] args) { int[] ages = new int[100]; for (int i = 0; i < ages.length; i++) { System.out.print(ages[i]); } }}

Dicas de programação:

1. Quando criar laços com for para o processamento de um array, utilize o campo length como argumento da expressão lógica. Isto irá permitir ao laço ajustar-se, automaticamente para tamanhos de diferentes arrays.

2. Declare o tamanho dos arrays utilizando variáveis do tipo constante para facilitar alterações posteriores. Por exemplo:

final int ARRAY_SIZE = 1000; // declarando uma constante...int[] ages = new int[ARRAY_SIZE];

Introdução à Programação I 9

Page 104: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Arrays Multidimensionais

Arrays multidimensionais são implementados como arrays dentro de arrays. São declarados ao atribuir um novo conjunto de colchetes depois do nome do array. Por exemplo:

// array inteiro de 512 x 128 elementosint [][] twoD = new int[512][128];

// array de caracteres de 8 x 16 x 24char [][][] threeD = new char[8][16][24];

// array de String de 4 linhas x 2 colunasString [][] dogs = {{"terry", "brown"},

{"Kristin", "white"}, {"toby", "gray"},

{"fido", "black"}};

Acessar um elemento em um array multidimensional é semelhante a acessar elementos em um array de uma dimensão. Por exemplo, para acessar o primeiro elemento da primeira linha do array dogs, escreve-se:

System.out.print(dogs[0][0]);

Isso mostrará a String "terry" na saída padrão. Caso queira mostrar todos os elementos deste array, escreve-se:

for (int i = 0; i < dogs.length; i++) { for (int j = 0; j < dogs[i].length; j++) { System.out.print(dogs[i][j] + " "); }}

Introdução à Programação I 10

Page 105: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Exercícios

7.1. Dias da semanaCriar um array de Strings inicializado com os nomes dos sete dias da semana. Por exemplo:

String days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

Usando uma declaração while, imprima todo o conteúdo do array. Faça o mesmo para as declarações do-while e for.

7.2. Maior númeroUsando as classes BufferedReader, Scanner ou JOptionPane, solicite 10 números ao usuário. Utilize um array para armazenar o valor destes números. Mostre o número de maior valor.

7.3. Entradas de agenda telefônicaDado o seguinte array multidimensional, que contém as entradas da agenda telefônica:

String entry = {{"Florence", "735-1234", "Manila"}, {"Joyce", "983-3333", "Quezon City"}, {"Becca", "456-3322", "Manila"}};

mostre-as conforme o formato abaixo:

Name : FlorenceTel. # : 735-1234Address: Manila

Name : JoyceTel. # : 983-3333Address: Quezon City

Name : BeccaTel. # : 456-3322Address: Manila

Introdução à Programação I 11

Page 106: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 8Argumentos de linha de comando

Versão 1.0 - Jan/2007

Page 107: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição, aprenderemos sobre como processar a entrada que vem da linha de comando usando argumentos passados para um programa feito em Java.

Ao final desta lição, o estudante será capaz de:

• Utilizar o argumento de linha de comando

• Receber dados enviados pelo usuário utilizando os argumentos de linha de comando

• Aprender como passar argumentos para os programas no NetBeans

Introdução à Programação I 4

Page 108: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Argumentos de linha de comando

Uma aplicação em Java aceita qualquer quantidade de argumentos passados pela linha de comando. Argumentos de linha de comando permitem ao usuário modificar a operação de uma aplicação a partir de sua execução. O usuário insere os argumentos na linha de comando no momento da execução da aplicação. Deve-se lembrar que os argumentos de linha de comando são especificados depois do nome da classe a ser executada.

Por exemplo, suponha a existência de uma aplicação Java, chamada Sort, que ordena cinco números que serão recebidos. Essa aplicação seria executada da seguinte maneira:

java Sort 5 4 3 2 1

Lembre-se que os argumentos são separados por espaços.

Em linguagem Java, quando uma aplicação é executada, o sistema repassa os argumentos da linha de comando para a o método main da aplicação através de um array de String. Cada elemento deste array conterá um dos argumentos de linha de comando passados. Lembre-se da declaração do método main:

public static void main(String[] args) {}

Os argumento que são passados para o programa são salvos em um array de String com o identificador args. No exemplo anterior, os argumentos de linha de comando passados para a aplicação Sort estarão em um array que conterá cinco strings: "5", "4", "3", "2" e "1". É possível conhecer o número de argumentos passados pela linha de comando utilizando-se o atributo length do array.

Por exemplo:

int numberOfArgs = args.length;

Se o programa precisa manipular argumento de linha de comando numérico, então, deve-se converter o argumento do tipo String, que representa um número, assim como "34", para um número. Aqui está a parte do código que converte um argumento de linha de comando para inteiro:

int firstArg = 0;if (args.length > 0) { firstArg = Integer.parseInt(args[0]);}

parseInt dispara uma exceção do tipo NumberFormatException se o conteúdo do elemento arg[0] não for um número.

Dicas de programação:

1. Antes de usar os argumentos de linha de comando, observe a quantidade de argumentos passados para a aplicação. Deste modo, nenhuma exceção será disparada.

Introdução à Programação I 5

Page 109: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Argumentos de linha de comando no NetBeans

Para ilustrar a passagem de alguns argumentos para um projeto no NetBeans, vamos criar um projeto em Java que mostrará na tela o número de argumentos e o primeiro argumento passado.

public class CommandLineExample { public static void main( String[] args ) { System.out.println("Number of arguments=" + args.length); System.out.println("First Argument="+ args[0]); }}

Abra o NetBeans, crie um novo projeto e dê o nome de CommandLineExample. Copie o código mostrado anteriormente e o compile. Em seguida, siga estas etapas para passar argumentos para o programa, utilizando o NetBeans.

Dê um clique com o botão direito do mouse no ícone CommandLineExample, conforme destacado na Figura 1. Um menu aparecerá, conforme a Figura 2. Selecione a opção "Properties".

Introdução à Programação I 6

Figura 1: Abrindo o projeto

Page 110: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 2: Abrindo a janela de propriedades

A janela "Project Properties" irá aparecer, conforme a Figura 3.

Figura 3: Janela de propriedades

Acesse a opção Run ⇒ Running Project.

Introdução à Programação I 7

Page 111: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 4: Acessando através de Running Project

Na caixa de texto dos argumentos, digite os argumentos que se quer passar para o programa. Neste caso, digitamos os argumentos 5 4 3 2 1. Pressione o botão OK.

Figura 5: Salvando os Argumentos de Linha de Comando

Introdução à Programação I 8

Page 112: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Execute o projeto.

Figura 6: Executando o programa com botão de atalho

Como pode-se ver, a saída do projeto é a quantidade de argumentos, que é 5, e o primeiro argumento passado, que também é 5.

Introdução à Programação I 9

Figura 7: Saída do Programa

Page 113: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Exercícios

4.1. Argumentos de Exibição

Utilizando os dados passados pelo usuário através dos argumentos de linha de comando, exiba os argumentos recebidos. Por exemplo, se o usuário digitar:

java Hello world that is all

o programa deverá mostrar na tela:

worldthatisall

4.2. Operações aritméticas

Obtenha dois números, passados pelo usuário usando argumentos de linha de comando, e mostre o resultado da soma, subtração, multiplicação e divisão destes números. Por exemplo, se o usuário digitar:

java ArithmeticOperation 20 4

o programa deverá mostrar na tela:

sum = 24subtraction = 16multiplication = 80division = 5

Introdução à Programação I 10

Page 114: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 9Trabalhando com Bibliotecas de Classe

Versão 1.0 - Jan/2007

Page 115: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição, abordaremos alguns conceitos básicos da Programação Orientada a Objetos ou POO. Mais adiante, discutiremos o conceito de classes e objetos e como usar as classes e seus membros. Comparação, conversão e casting de objetos, também serão vistos. Por enquanto, o foco será o uso das classes já definidas nas bibliotecas Java e, posteriormente, discutiremos como criar nossas próprias classes.

Ao final desta lição, o estudante será capaz de:

• Explicar o que é Programação Orientada a Objetos e alguns dos seus conceitos

• Diferenciar entre classes e objetos

• Diferenciar atributos e métodos de objeto de atributos e métodos de classe

• Explicar o que são métodos, como invocá-los e como enviar argumentos

• Identificar o escopo de um atributo

• Realizar conversões entre tipos de dados primitivos e entre objetos

• Comparar objetos e determinar suas classes

Introdução à Programação I 4

Page 116: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Introdução à Programação Orientada a Objeto

Programação Orientada a Objetos (POO) refere-se ao conceito de objetos como elemento básico das classes. O mundo físico é constituído por objetos tais como carro, leão, pessoa, dentre outros. Estes objetos são caracterizados pelas suas propriedades (ou atributos) e seus comportamentos.

Por exemplo, um objeto "carro" tem as propriedades, tipo de câmbio, fabricante e cor. O seu comportamento pode ser 'virar', 'frear' e 'acelerar'. Igualmente, podemos definir diferentes propriedades e comportamentos para um leão. Veja exemplos na Tabela 1.

Objeto Propriedades Comportamentos

carro tipo de câmbiofabricantecor

virarfrearacelerar

leão pesocorapetite (faminto ou saciado)temperamento (dócil ou selvagem)

rugirdormircaçar

Tabela 1: Exemplos de objetos do mundo real

Com tais descrições, os objetos do mundo físico podem ser facilmente modelados como objetos de software usando as propriedades como atributos e os comportamentos como métodos. Estes atributos e métodos podem ser usados em softwares de jogos ou interativos para simular objetos do mundo real! Por exemplo, poderia ser um objeto de 'carro' numa competição de corrida ou um objeto de 'leão' num aplicativo educacional de zoologia para crianças.

Introdução à Programação I 5

Page 117: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Classes e Objetos

3.1. Diferenças entre Classes e Objetos

No mundo do computador, um objeto é um componente de software cuja estrutura é similar a um objeto no mundo real. Cada objeto é composto por um conjunto de atributos (propriedades) que são as variáveis que descrevem as características essenciais do objeto e, consiste também, num conjunto de métodos (comportamentos) que descrevem como o objeto se comporta. Assim, um objeto é uma coleção de atributos e métodos relacionados. Os atributos e métodos de um objeto Java são formalmente conhecidos como atributos e métodos de objeto, para distinguir dos atributos e métodos de classes, que serão discutidos mais adiante.

A classe é a estrutura fundamental na Programação Orientada a Objetos. Ela pode ser pensada como um gabarito, um protótipo ou, ainda, uma planta para a construção de um objeto. Ela consiste em dois tipos de elementos que são chamados atributos (ou propriedades) e métodos. Atributos especificam os tipos de dados definidos pela classe, enquanto que os métodos especificam as operações. Um objeto é uma instância de uma classe.

Para diferenciar entre classes e objetos, vamos examinar um exemplo. O que temos aqui é uma classe Carro que pode ser usada pra definir diversos objetos do tipo carro. Na tabela mostrada abaixo, Carro A e Carro B são objetos da classe Carro. A classe tem os campos número da placa, cor, fabricante e velocidade que são preenchidos com os valores correspondentes do carro A e B. O carro também tem alguns métodos: acelerar, virar e frear.

Classe Carro Objeto Carro A Objeto Carro B

Atributos deObjeto

Número da placa ABC 111 XYZ 123

Cor Azul Vermelha

Fabricante Mitsubishi Toyota

Velocidade 50 km/h 100 km/h

Métodos deObjeto

Método Acelerar

Método Girar

Método Frear

Tabela 2: Exemplos da classe Carro e seus objetos

Quando construídos, cada objeto adquire um conjunto novo de estado. Entretanto, as implementações dos métodos são compartilhadas entre todos os objetos da mesma classe.

As classes fornecem o benefício do Reutilização de Classes (ou seja, utilizar a mesma classe em vários projetos). Os programadores de software podem reutilizar as classes várias vezes para criar os objetos.

3.2. Encapsulamento

Encapsulamento é um princípio que propõe ocultar determinados elementos de uma classe das demais classes. Ao colocar uma proteção ao redor dos atributos e criar métodos para prover o acesso a estes, desta forma estaremos prevenindo contra os efeitos colaterais indesejados que podem afetá-los ao ter essas propriedades modificadas de forma inesperada.

Introdução à Programação I 6

Page 118: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Podemos prevenir o acesso aos dados dos nossos objetos declarando que temos controle desse acesso. Aprenderemos mais sobre como Java implementa o encapsulamento quando discutirmos mais detalhadamente sobre as classes.

3.3. Atributos e Métodos de Classe

Além dos atributos de objeto, também é possível definir atributos de classe, que são atributos que pertencem à classe como um todo. Isso significa que possuem o mesmo valor para todos os objetos daquela classe. Também são chamados de atributos estáticos.

Para melhor descrever os atributos de classe, vamos voltar ao exemplo da classe Carro. Suponha que a classe Carro tenha um atributo de classe chamado Contador. Ao mudarmos o valor de Contador para 2, todos os objetos da classe Carro terão o valor 2 para seus atributos Contador.

Classe Carro Objeto Carro A Objeto Carro B

Atributos de Objeto

Número da placa ABC 111 XYZ 123

Cor Azul Vermelho

Fabricante Mitsubishi Toyota

Velocidade 50 km/h 100 km/h

Atributos deClasse

Contador = 2

Métodos deObjeto

Método Acelerar

Método virar

Método Frear

Tabela 3: Atributos e métodos da classe Carro

3.4. Instância de Classe

Para criar um objeto ou uma instância da classe, utilizamos o operador new. Por exemplo, para criar uma instância da classe String, escrevemos o seguinte código:

String str2 = new String("Hello world!");

ou, o equivalente:

String str2 = "Hello world!";

O operador new aloca a memória para o objeto e retorna uma referência para essa alocação. Ao criar um objeto, invoca-se, na realidade, o construtor da classe. O construtor é um método onde todas as inicializações do objeto são declaradas e possui o mesmo nome da classe.

Introdução à Programação I 7

Figura 1: Instanciação de uma classe

Page 119: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Métodos

4.1. O que são métodos e porque usar métodos?

Nos exemplos apresentados anteriormente, temos apenas um método, o método main(). Em Java, nós podemos definir vários métodos e podemos chamá-los a partir de outros métodos.

Um método é um trecho de código distinto que pode ser chamado por qualquer outro método para realizar alguma função específica.

Métodos possuem as seguintes características:

• Podem ou não retornar um valor• Podem aceitar ou não argumentos• Após o método encerrar sua execução, o fluxo de controle é retornado a quem o

chamou

O que é necessário para se criar métodos? Porque não colocamos todas as instruções dentro de um grande método? O foco destas questões é chamado de decomposição. Conhecido o problema, nós o separamos em partes menores, que torna menos crítico o trabalho de escrever grandes classes.

4.2. Chamando Métodos de Objeto e Enviando Argumentos

Para ilustrar como chamar os métodos, utilizaremos como exemplo a classe String. Pode-se usar a documentação da API Java para conhecer todos os atributos e métodos disponíveis na classe String. Posteriormente, iremos criar nossos próprios métodos.

Para chamar um método a partir de um objeto, escrevemos o seguinte:

nomeDoObjeto.nomeDoMétodo([argumentos]);

Vamos pegar dois métodos encontrados na classe String como exemplo:

Declaração do método Definição

public char charAt(int index) Retorna o caractere especificado no índice. Um índice vai de 0 até length() - 1. O primeiro caractere da seqüência está no índice 0, o seguinte, no índice 1, e assim sucessivamente por todo o array.

public boolean equalsIgnoreCase (String anotherString) Compara o conteúdo de duas Strings, ignorando

maiúsculas e minúsculas. Duas strings são consideradas iguais quando elas têm o mesmo tamanho e os caracteres das duas strings são iguais, sem considerar caixa alta ou baixa.

Tabela 4: Exemplos de Métodos da classe String

Usando os métodos:

String str1 = "Hello";char x = str1.charAt(0); // retornará o caracter H // e o armazenará no atributo x

Introdução à Programação I 8

Page 120: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

String str2 = "hello";

// aqui será retornado o valor booleano trueboolean result = str1.equalsIgnoreCase(str2);

4.3. Envio de Argumentos para Métodos

Em exemplos anteriores, enviamos atributos para os métodos. Entretanto, não fizemos nenhuma distinção entre os diferentes tipos de atributos que podem ser enviados como argumento para os métodos. Há duas formas para se enviar argumentos para um método, o primeiro é envio por valor e o segundo é envio por referência.

4.3.1. Envio por valor

Quando ocorre um envio por valor, a chamada do método faz uma cópia do valor do atributo e o reenvia como argumento. O método chamado não modifica o valor original do argumento mesmo que estes valores sejam modificados durante operações de cálculo implementadas pelo método. Por exemplo:

public class TestPassByValue {public static void main( String[] args ){int i = 10;//exibe o valor de iSystem.out.println( i );

//chama o método test//envia i para o método testtest( i );//exibe o valor de i não modificadoSystem.out.println( i );

}

public static void test( int j ){//muda o valor do argumento jj = 33;

}}

No exemplo dado, o método test foi chamado e o valor de i foi enviado como argumento. O valor de i é copiado para o atributo do método j. Já que j é o atributo modificado no método test, não afetará o valor do atributo i, o que significa uma cópia diferente do atributo.

Como padrão, todo tipo primitivo, quando enviado para um método, utiliza a forma de envio por valor.

4.3.2. Envio por referência

Quando ocorre um envio por referência, a referência de um objeto é enviada para o método chamado. Isto significa que o método faz uma cópia da referência do objeto enviado. Entretanto, diferentemente do que ocorre no envio por valor, o método pode modificar o objeto para o qual a referência está apontando. Mesmo que diferentes referências sejam usadas nos métodos, a localização do dado para o qual ela aponta é a mesma.

Por exemplo:

Introdução à Programação I 9

Page 121: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

class TestPassByReference { public static void main(String[] args) { // criar um array de inteiros int []ages = {10, 11, 12}; // exibir os valores do array for (int i=0; i < ages.length; i++) { System.out.println( ages[i] ); } // chamar o método test e enviar a // referência para o array test( ages ); // exibir os valores do array for (int i=0; i < ages.length; i++) { System.out.println(ages[i]); } } public static void test( int[] arr ){ // mudar os valores do array for (int i=0; i < arr.length; i++) { arr[i] = i + 50; } }}

Dicas de programação:

1. Um erro comum sobre envio por referência acontece quando criamos um método para fazer trocas (swap) usando referência. Note que Java manipula objetos 'por referência', entretanto envia-se a referência para um método 'por valor'. Como conseqüência, não se escreve um método padrão para fazer troca de valores (swap) entre objetos.

Introdução à Programação I 10

Figura 2: Exemplo de Envio por referência

Page 122: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.4. Chamando métodos estáticos

Métodos estáticos são métodos que podem ser invocados sem que um objeto tenha sido instanciado pela classe (sem utilizar a palavra-chave new). Métodos estáticos pertencem a classe como um todo e não ao objeto especifico da classe. Métodos estáticos são diferenciados dos métodos de objeto pela declaração da palavra-chave static na definição do método.

Para chamar um método estático, digite:

NomeClasse.nomeMétodoEstático(argumentos);

Alguns métodos estáticos, que já foram usados em nossos exemplos são:

// Converter a String 10 em um atributo do tipo inteiroint i = Integer.parseInt("10"); // Retornar uma String representando um inteiro sem o sinal da // base 16String hexEquivalent = Integer.toHexString(10);

4.5. Escopo de um atributo

Além do atributo ter um nome e um tipo, ele também possui um escopo. O escopo determina onde o atributo é acessível dentro da classe. O escopo também determina o tempo de vida do atributo ou quanto tempo o atributo irá existir na memória. O escopo é determinado pelo local onde o atributo é declarado na classe.

Para simplificar, vamos pensar no escopo como sendo algo existente entre as chaves {...}. A chave à direita é chamada de chave de saída do bloco (outer) e a chave à esquerda é chamada chave de entrada do bloco (inner).

Ao declarar atributos fora de um bloco, eles serão visíveis (usáveis) inclusive pelas linhas da classe dentro do bloco. Entretanto, ao declarar os atributo dentro do bloco, não será possível utilizá-los fora do bloco.

O escopo de um atributo é dito local quando é declarado dentro do bloco. Seu escopo inicia com a sua declaração e vai até a chave de saída do bloco.

Por exemplo, dado o seguinte fragmento de código:

public class ScopeExample { int i = 0; public static void main(String[] args) { int j = 0; { int k = 0; int m = 0; int n = 0; } }}

O código acima representa cinco escopos indicado pelas letras. Dados os atributos i, j, k, m e n, e os cinco escopos A, B, C, D e E, temos os seguintes escopos para cada atributo:

O escopo do atributo i é A.

Introdução à Programação I 11

BD C

C

A

Page 123: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

O escopo do atributo j é B.O escopo do atributo k é C.O escopo do atributo m é D.O escopo do atributo n é E.

Dado dois métodos: main e test teremos o seguinte exemplo:

class TestPassByReference { public static void main(String[] args) { // criar um array de inteiros int []ages = {10, 11, 12};

//exibir os valores do array for (int i=0; i < ages.length; i++){ System.out.println( ages[i] ); }

// chamar o método test e enviar a referência para o array test(ages);

//exibe novamente os valores do array for (int i = 0; i < ages.length; i++) { System.out.println( ages[i] ); } } public static void test(int[] arr) { // modificar os valores do array for (int i = 0; i < arr.length; i++) { arr[i] = i + 50; } }}

Para o método main, os escopos dos atributos são:

ages[] - escopo Ai em B - escopo Bi em C – escopo C

E, no método test, os escopos dos atributos são:

arr[] - escopo Di em E - escopo E

Quando atributos são declarados, o identificador deve ser único no escopo. Isto significa que se você tiver a seguinte declaração:

{int test = 10;int test = 20;

}

o compilador irá gerar um erro pois deve-se ter um nome único para o atributos dentro do bloco. Entretanto, é possível ter atributos definidos com o mesmo nome, se não estiverem declarados no mesmo bloco. Por exemplo:

public class TestBlock { int test = 10;

Introdução à Programação I 12

A

B

C

ED

Page 124: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public void test() { System.out.print(test); int test = 20; System.out.print(test); } public static void main(String[] args) { TestBlock testBlock = new TestBlock(); testBlock.test(); }}

Quando a primeira instrução System.out.print for invocada, exibirá o valor 10 contido na primeira declaração do atributo test. Na segunda instrução System.out.print, o valor 20 é exibido, pois é o valor do atributos test neste escopo.

Dicas de programação:

1. Evite ter atributos declarados com o mesmo nome dentro de um método para não causar confusão.

Introdução à Programação I 13

Page 125: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Casting, Conversão e Comparação de Objetos

Nesta seção, vamos aprender como realizar um casting. Casting, ou typecasting, é o processo de conversão de um certo tipo de dado para outro. Também aprenderemos como converter tipos de dados primitivos para objetos e vice-versa. E, finalmente, aprenderemos como comparar objetos.

5.1. Casting de Tipos Primitivos

Casting entre tipos primitivos permite converter o valor de um dado de um determinado tipo para outro tipo de dado primitivo. O casting entre primitivos é comum para os tipos numéricos.

Há um tipo de dado primitivo que não aceita o casting, o tipo de dado boolean.

Como demonstração de casting de tipos, considere que seja necessário armazenar um valor do tipo int em um atributo do tipo double. Por exemplo:

int numInt = 10;double numDouble = numInt; // cast implícito

uma vez que o atributo de destino é double, pode-se armazenar um valor cujo tamanho seja menor ou igual aquele que está sendo atribuído. O tipo é convertido implicitamente.

Quando convertemos um atributo cujo tipo possui um tamanho maior para um de tamanho menor, necessariamente devemos fazer um casting explícito. Esse possui a seguinte forma:

(tipoDado)valoronde:

tipoDado é o nome do tipo de dado para o qual se quer converter o valorvalor é um valor que se quer converter.

Por exemplo:

double valDouble = 10.12;int valInt = (int)valDouble; //converte valDouble para o tipo intdouble x = 10.2;int y = 2;int result = (int)(x/y); //converte o resultado da operação para int

Outro exemplo é quando desejamos fazer um casting de um valor do tipo int para char. Um caractere pode ser usado como int porque para cada caractere existe um correspondente numérico que representa sua posição no conjunto de caracteres. O casting (char)65 irá produzir a saída 'A'. O código numérico associado à letra maiúscula A é 65, segundo o conjunto de caracteres ASCII. Por exemplo:

char valChar = 'A';System.out.print((int)valChar); //casting explícito produzirá 65

5.2. Casting de Objetos

Para objetos, a operação de casting também pode ser utilizada para fazer a conversão para outras classes, com a seguinte restrição: a classe de origem e a classe de destino devem ser da mesma família, relacionadas por herança; uma classe deve ser subclasse da outra. Veremos mais em lições posteriores sobre herança.

Introdução à Programação I 14

Page 126: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Analogamente à conversão de valores primitivos para um tipo maior, alguns objetos não necessitam ser convertidos explicitamente. Em conseqüência de uma subclasse conter todas as informações da sua superclasse, pode-se usar um objeto da subclasse em qualquer lugar onde a superclasse é esperada.

Por exemplo, um método que recebe dois argumentos, um deles do tipo Object e outro do tipo Window. Pode-se enviar um objeto de qualquer classe como argumento Object porque todas as classes Java são subclasses de Object. Para o argumento Window, é possível enviar apenas suas subclasses, tais como Dialog, FileDialog, Frame (ou quaisquer de subclasses de suas subclasses, indefinidamente). Isso vale para qualquer parte da classe, não apenas dentro da chamadas do método. Para um objeto definido como uma classe Window, é possível atribuir objetos dessa classe ou qualquer uma de suas subclasses para esse objeto sem o casting.

O contrário também é verdadeiro. Uma superclasse pode usada quando uma subclasse é esperada. Entretanto, nesse caso, o casting é necessário porque as subclasses contém mais métodos que suas superclasses, e isso acarreta em perda de precisão. Os objetos das superclasses podem não dispor de todo o comportamento necessário para agir como um objeto da subclasse. Por exemplo, se uma operação faz a chamada a um método de um objeto da classe Integer, usando um objeto da classe Number, ele não terá muitos dos métodos que foram especificados na classe Integer. Erros ocorrerão se você tentar chamar métodos que não existem no objeto de destino.

Para usar objetos da superclasse onde uma subclasse é esperada, é necessário fazer o casting explícito. Nenhuma informação será perdida no casting, entretanto, ganhará todos os atributos e métodos que a subclasse define. Para fazer o casting de um objeto para outro, utiliza-se a mesma operação utilizada com os tipos primitivos:

Para fazer o casting:

(nomeClasse)objetoonde:

nomeClasse é o nome da classe destinoobjeto é a referência para o objeto origem que se quer converter

Uma vez que casting cria uma referência para o antigo objeto de nomeClasse; ele continua a existir depois do casting.

Introdução à Programação I 15

Figura 3: Exemplo de Hierarquia de Classes

Page 127: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 4: Hierarquia de classes para a superclasse Employee

O exemplo a seguir realiza um casting de um objeto da classe VicePresident para um objeto da classe Employee. VicePresident é uma subclasse de Employee com mais informações, supondo que tenha sido definido que a classe VicePresident tem mais privilégios que um Employee.

Employee emp = new Employee();VicePresident veep = new VicePresident();emp = veep; // casting não é necessário de baixo para cimaveep = (VicePresident)emp; // necessita do casting explícito

5.3. Convertendo Tipos Primitivos para Objetos e Vice-Versa

Não se pode fazer sob qualquer circunstância é um casting de um objeto para um tipo de dado primitivo, ou vice-versa. Tipos primitivos e objetos são muito diferentes em Java e não se pode fazer o casting automaticamente entre os dois ou intercambiar o seu uso.

Como alternativa, o pacote java.lang oferece classes que fazem a correspondência para cada tipo primitivo: Float, Boolean, Byte, dentre outros. Muitas dessas classes têm o mesmo nome dos tipos de dados primitivos, exceto pelo fato que o nome dessas classe começam com letra maiúscula (Short ao invés de short, Double ao invés de double, etc). Há duas classes que possuem nomes que diferem do correspondente tipo de dado primitivo: Character é usado para o tipo char e Integer usado para o tipo int. Estas classes são chamadas de Wrapper Class.

Versões anteriores a 5.0 de Java tratam os tipos de dados e suas Wrapper Class de forma muito diferente e uma classe não será compilada com sucesso se for utilizado uma quando deveria usar a outra. Por exemplo:

Integer ten = 10;Integer two = 2;System.out.println(ten + two);

Usando as classes que correspondem a cada um dos tipos primitivos, é possível criar objetos que armazenam este mesmo valor. Por exemplo:

// A declaração seguinte cria um objeto de uma classe Integer // com o valor do tipo int 7801 (primitivo -> objeto)Integer dataCount = new Integer(7801);

// A declaração seguinte converte um objeto Integer para um// tipo de dado primitivo int. O resultado é o valor 7801int newCount = dataCount.intValue();

// Uma conversão comum de se fazer é de String para um tipo// numérico (objeto -> primitivo)String pennsylvania = "65000";int penn = Integer.parseInt(pennsylvania);

Introdução à Programação I 16

Page 128: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. A classe Void representa vazio em Java. Deste modo, não existem motivos para ela ser usada na conversão de valores primitivos e objetos. Ela é um tratador para a palavra-chave void, que é utilizada na assinatura de métodos indicando que estes não retornam valor.

5.4. Comparando Objetos

Em lições prévias, aprendemos sobre operadores para comparar valores — igualdade, negação, menor que, etc. Muitos desses operadores trabalham apenas com dados de tipo primitivo, não com objetos. Ao tentar utilizar outros tipos de dados, o compilador produzirá erros.

Uma exceção para esta regra são os operadores de igualdade: == (igual) e != (diferente). Quando aplicados a objetos, estes operadores não fazem o que se poderia supor. Ao invés de verificar se um objeto tem o mesmo valor de outro objeto, eles determinam se os dois objetos comparados pelo operador têm a mesma referência. Por exemplo:

String valor1 = new String;Integer dataCount = new Integer(7801);

Para comparar objetos de uma classe e ter resultados apropriados, deve-se implementar e chamar métodos especiais na sua classe. Um bom exemplo disso é a classe String.

É possível ter dois objetos String diferentes que contenham o mesmo valor. Caso se empregue o operador == para comparar objetos, estes serão considerados diferentes. Mesmo que seus conteúdos sejam iguais, eles não são o mesmo objeto.

Para ver se dois objetos String têm o mesmo conteúdo, um método chamado equals() é utilizado. O método compara cada caractere presente no conteúdo das Strings e retorna true se ambas strings tiverem o mesmo valor.

O código seguinte ilustra essa comparação,

class EqualsTest { public static void main(String[] args) { String str1, str2; str1 = "Free the bound periodicals."; str2 = str1;

System.out.println("String1: " + str1); System.out.println("String2: " + str2); System.out.println("Same object? " + (str1 == str2));

str2 = new String(str1);

System.out.println("String1: " + str1); System.out.println("String2: " + str2); System.out.println("Same object? " + (str1 == str2)); System.out.println("Same value? " + str1.equals(str2)); } }

Introdução à Programação I 17

Page 129: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A saída dessa classe é a seguinte:

String1: Free the bound periodicals.String2: Free the bound periodicals.Same object? trueString1: Free the bound periodicals.String2: Free the bound periodicals.Same object? falseSame value? true

Vamos entender o processo envolvido.

String str1, str2;str1 = "Free the bound periodicals.";str2 = str1;

A primeira parte dessa classe declara dois atributos (str1 e str2) e atribui a literal "Free the bound periodicals." a str1, e depois atribui esse valor a str2. Como visto anteriormente, str1 e str2 agora apontam para o mesmo objeto, e o teste de igualdade prova isso.

Em seguida, temos a seguinte instrução:

str2 = new String(str1);

Na segunda parte da classe, cria-se um novo objeto String com o mesmo valor de str1 e faz-se a atribuição de str2 para esse novo objeto String. Agora temos dois diferentes tipos de objetos na str1 e str2, ambos com o mesmo conteúdo. Testando para ver se eles são o mesmo objeto usando o operador de igualdade obtemos a resposta esperada: false — eles não são o mesmo objeto na memória. Utilizando o método equals() recebemos a resposta esperada: true — eles tem o mesmo conteúdo.

Figura 6: As referências apontam agora para objetos diferentes

Dicas de programação:

1. Porque não se pode ter a mesma literal quando mudamos str2, a não ser quando utilizamos o new? Literais String são otimizadas em Java; se uma String é criada utilizando uma literal e cria-se outra String com os mesmos caracteres,

Introdução à Programação I 18

Figura 5: Duas referências apontando para o mesmo objeto

Page 130: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Java tem inteligência suficiente para retornar apenas a posição em memória do primeiro objeto String criado. Ou seja, ambas strings se referem ao mesmo objeto como se fosse um apelido. Para obrigar ao Java criar um novo objeto String, deve-se utilizar o operador new.

5.5. Determinando a Classe de um Objeto

Existem duas maneiras de se descobrir a qual classe determinado objeto pertence:

1. Para obter o nome da classe:

Utiliza-se o método getClass() que retorna a classe do objeto (onde Class é a classe em si). Esta, por sua vez, possui o método chamado getName() que retorna o nome da classe.

Por exemplo:

String name = key.getClass().getName();

2. Para testar se um objeto qualquer foi instanciado de uma determinada classe:

Utiliza-se a palavra-chave instanceof. Esta palavra-chave possui dois operadores: a referência para o objeto à esquerda e o nome da classe à direita. A expressão retorna um lógico dependendo se o objeto é uma instância da classe declarada ou qualquer uma de suas subclasses.

Por exemplo:

String ex1 = "Texas";System.out.println(ex1 instanceof String); // retorna trueString ex2;System.out.println(ex2 instanceof String); // retorna false

Introdução à Programação I 19

Page 131: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Exercícios

6.1. Definindo termos

Em suas palavras, defina os seguintes termos:

1. Classe2. Objeto3. Instanciação4. Atributo de objeto5. Método de objeto6. Atributo de classe ou atributos estáticas7. Construtor8. Método de classe ou métodos estáticos

6.2. Java Scavenger Hunt

Pipoy é um novato na linguagem de programação Java. Ele apenas ouviu que existem Java APIs (Application Programming Interface) prontas para serem usadas em suas classes e ele está ansioso para fazer uns testes com elas. O problema é que Pipoy não tem uma cópia da documentação Java e ele também não tem acesso à Internet, deste modo, não há como ele ver as APIs java.

Sua tarefa é ajudar Pipoy a procurar as APIs. Você deve informar as classes às quais os métodos pertencem e como o método deve ser declarado com um exemplo de uso deste.

Por exemplo, se Pipoy quer saber qual o método que converte uma String para int, sua resposta deve ser:

Classe: IntegerDeclaração do Método: public static int parseInt( String value )Exemplo de Uso:

String strValue = "100";int value = Integer.parseInt( strValue );

Tenha certeza de que o fragmento de código que você escreveu em seu exemplo de uso compila e que produza o resultado correto. Enfim, não deixe Pipoy confuso. (Dica: Todos os métodos estão no package java.lang). Caso haja mais de um método para atender à tarefa, utilize apenas um.

Agora vamos iniciar a busca! Aqui estão alguns métodos que Pipoy necessita:

1. Procure pelo método que verifica se uma String termina com um determinado sufixo. Por exemplo, se a String dada é "Hello", o método deve retornar true se o sufixo informado é "lo", e false se o sufixo for "alp".

2. Procure pelo método que determina a representação do caractere para um dígito e base específicos. Por exemplo, se o dígito informado é 15 e a base é 16, o método retornará o caractere 'F', uma vez que 'F' é a representação hexadecimal para o número 15 em base 10.

3. Procure por um método que retorna a parte inteira de um valor double. Por exemplo, se a entrada for 3.13, o método deve retornar o valor 3.

4. Procure por um método que determina se um certo caractere é um dígito. Por exemplo, se a entrada for '3', retornará o valor true.

5. Procure por um método que interrompe a execução da Java Virtual Machine corrente.

Introdução à Programação I 20

Page 132: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação 1

Lição 10Criando nossas classes

Versão 1.0 - Jan/2007

Page 133: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Agora que já estudamos como usar as classes existentes na biblioteca de classes do Java, estudaremos como criar nossas próprias classes. Nesta lição, para facilmente entender como criá-las, realizaremos um exemplo de classe no qual adicionaremos dados e funcionalidades à medida em que avançarmos no curso.

Criaremos uma classe com informações de um Estudante e com operações necessárias para seu registro.

Algumas observações devem ser feitas quanto à sintaxe que será usada nesta e nas próximas seções:

* - significa que pode haver nenhuma ou diversas ocorrências na linha em que for aplicada

<descrição> - indica a substituição deste trecho por um certo valor, ao invés de digitá-lo como está

[] - indica que esta parte é opcional

Ao final desta lição, o estudante será capaz de:

• Criar nossas classes

• Declarar atributos e métodos para as classes

• Usar o objeto this para acessar dados de instância

• Utilizar overloading de métodos

• Importar e criar pacotes

• Usar modificadores de acesso para controlar o acesso aos elementos de

uma classe

Introdução à Programação I 4

Page 134: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Definindo nossas classes

Antes de escrever sua classe, primeiro pense onde e como sua classe será usada. Pense em um nome apropriado para a classe e liste todas as informações ou propriedades que deseje que ela tenha. Liste também os métodos que serão usados para a classe.

Para definir uma classe, escrevemos:

<modificador>* class <nome> { <declaraçãoDoAtributo>* <declaraçãoDoConstrutor>* <declaraçãoDoMétodo>*}

onde:

<modificador> é um modificador de acesso, que pode ser usado em combinação com outros

<nome> nome da sua classe<declaraçãoDoAtributo> atributos definidos para a classe<declaraçãoDoConstrutor> método construtor<declaraçãoDoMétodo> métodos da classe

Dicas de programação:

1. Lembre-se de que, para a declaração da classe, o único modificador de acesso válido é o public. De uso exclusivo para a classe que possuir o mesmo nome do arquivo externo.

Nesta lição, criaremos uma classe que conterá o registro de um estudante. Como já identificamos o objetivo da nossa classe, agora podemos nomeá-la. Um nome apropriado para nossa classe seria StudentRecord.

Para definir nossa classe, escrevemos:

public class StudentRecord {// adicionaremos mais código aqui

}

onde:

public modificador de acesso e significa que qualquer classe pode acessar esta

class palavra-chave usada para criar uma classeStudentRecord identificador único que identifica a classe

Introdução à Programação I 5

Page 135: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. Pense em nomes apropriados para a sua classe. Não a chame simplesmente de classe XYZ ou qualquer outro nome aleatório.

2. Os nomes de classes devem ser iniciadas por letra MAIÚSCULA.3. O nome do arquivo de sua classe obrigatoriamente possui o

MESMO NOME da sua classe pública.

Introdução à Programação I 6

Page 136: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Declarando Atributos

Para declarar um certo atributo para a nossa classe, escrevemos:

<modificador>* <tipo> <nome> [= <valorInicial>];

onde:

modificador tipo de modificador do atributotipo tipo do atributonome pode ser qualquer identificador válidovalorInicial valor inicial para o atributo

Relacionaremos a lista de atributos que um registro de estudante pode conter. Para cada informação, listaremos os tipos de dados apropriados que serão utilizados. Por exemplo, não seria ideal usar um tipo int para o nome do estudante ou String para a nota do estudante.

Abaixo, por exemplo, temos algumas informações que podemos adicionar ao registro do estudante:

nome - Stringendereço - Stringidade - intnota de matemática - doublenota de inglês - doublenota de ciências - double

Futuramente, é possível adicionar mais informações. Para este exemplo, utilizaremos somente estas.

3.1. Atributos de Objeto

Agora que temos uma lista de todos os atributos que queremos adicionar à nossa classe, vamos adicioná-los ao nosso código. Uma vez que queremos que estes atributos sejam únicos para cada objeto (ou para cada estudante), devemos declará-los como atributos de objeto.

Por exemplo:

public class StudentRecord { private String name; private String address; private int age; private double mathGrade;

Introdução à Programação I 7

Page 137: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

private double englishGrade; private double scienceGrade;}

onde:

private significa que os atributos são acessíveis apenas de dentro da classe. Outros objetos não podem acessar diretamente estes atributos.

Dicas de programação:

1. Declare todas os atributos de objeto na parte superior da declaração da classe.

2. Declare cada atributo em uma linha.3. Atributos de objeto, assim como qualquer outro atributo devem

iniciar com letra MINÚSCULA.4. Use o tipo de dado apropriado para cada atributo declarado.5. Declare atributos de objetos como private de modo que somente

os métodos da classe possam acessá-los diretamente.

3.2. Atributos de Classe ou Atributos Estáticos

Além das atributos de objeto, podemos também declarar atributos de classe ou atributos que pertençam à classe como um todo. O valor destes atributos é o mesmo para todos os objetos da mesma classe. Suponha que queiramos saber o número total de registros criados para a classe. Podemos declarar um atributo estático que armazenará este valor. Vamos chamá-lo de studentCount.

Para declarar um atributo estático:

public class StudentRecord { // atributos de objeto declarados anteriormente

private static int studentCount;}

usamos a palavra-chave static para indicar que é um atributo estático.

Então, nosso código completo deve estar assim:

public class StudentRecord { private String name; private String address;

Introdução à Programação I 8

Page 138: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

private int age; private double mathGrade; private double englishGrade; private double scienceGrade;

private static int studentCount;}

Introdução à Programação I 9

Page 139: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Declarando Métodos

Antes de discutirmos quais métodos que a nossa classe deverá conter, vejamos a sintaxe geral usada para a declaração de métodos.

Para declararmos métodos, escrevemos:

<modificador>* <tipoRetorno> <nome>(<argumento>*) { <instruções>*}

onde:

<modificador> pode ser utilizado qualquer modificador de acesso

<tipoRetorno> pode ser qualquer tipo de dado (incluindo void)

<nome> pode ser qualquer identificador válido<argumento> argumentos recebidos pelo método separados

por vírgulas. São definidos por:

<tipoArgumento> <nomeArgumento>

4.1. Métodos assessores

Para que se possa implementar o princípio do encapsulamento, isto é, não permitir que quaisquer objetos acessem os nossos dados de qualquer modo, declaramos campos, ou atributos, da nossa classe como particulares. Entretanto, há momentos em que queremos que outros objetos acessem estes dados particulares. Para que possamos fazer isso, criamos métodos assessores.

Métodos assessores são usados para ler valores de atributos de objeto ou de classe. O método assessor recebe o nome de get<NomeDoAtributo>. Ele retorna um valor.

Para o nosso exemplo, queremos um método que possa ler o nome, endereço, nota de inglês, nota de matemática e nota de ciências do estudante.

Vamos dar uma olhada na implementação deste:

public class StudentRecord { private String name; : : public String getName() {

Introdução à Programação I 10

Page 140: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

return name; }}

onde:

public significa que o método pode ser chamado por objetos externos à classe

String é o tipo do retorno do método. Isto significa que o método deve retornar um valor de tipo String

getName o nome do método() significa que o nosso método não tem nenhum

argumento

A instrução:

return name;

no método, significa que retornará o conteúdo do atributo name ao método que o chamou. Note que o tipo do retorno do método deve ser do mesmo tipo do atributo utilizado na declaração return. O seguinte erro de compilação ocorrerá caso o método e o atributo de retorno não tenham o mesmo tipo de dados:

StudentRecord.java:14: incompatible typesfound : intrequired: java.lang.String return name; ^1 error

Outro exemplo de um método assessor é o método getAverage:

public class StudentRecord { private String name; : : public double getAverage(){ double result = 0; result = (mathGrade+englishGrade+scienceGrade)/3; return result; }}

O método getAverage calcula a média das 3 notas e retorna o resultado.

Introdução à Programação I 11

Page 141: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.2. Métodos modificadores

Para que outros objetos possam modificar os nossos dados, disponibilizamos métodos que possam gravar ou modificar os valores dos atributos de objeto ou de classe. Chamamos a estes métodos modificadores. Este método é escrito como set<NomeDoAtributoDeObjeto>.

Vamos dar uma olhada na implementação de um método modificador:

public class StudentRecord { private String name; : : public void setName(String temp) { name = temp; }}

onde:

public significa que o método pode ser chamado por objetos externos à classe

void significa que o método não retorna valorsetName o nome do método(String temp) argumento que será utilizado dentro do nosso

método

A instrução:

name = temp;

atribuir o conteúdo de temp para name e, portanto, alterar os dados dentro do atributo de objeto name.

Métodos modificadores não retornam valores. Entretanto, eles devem receber um argumento com o mesmo tipo do atributo no qual estão tratando.

4.3. Múltiplos comandos return

É possível ter vários comandos return para um método desde que eles não pertençam ao mesmo bloco. É possível utilizar constantes para retornar valores, ao invés de atributos.

Por exemplo, considere o método:

public String getNumberInWords(int num) { String defaultNum = "zero";

Introdução à Programação I 12

Page 142: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

if (num == 1) { return "one"; // retorna uma constante } else if( num == 2) { return "two"; // retorna uma constante } // retorna um atributo return defaultNum;}

4.4. Métodos estáticos

Para o atributo estático studentCount, podemos criar um método estático para obter o seu conteúdo.

public class StudentRecord {private static int studentCount;

public static int getStudentCount(){return studentCount;

}}

onde:

public significa que o método pode ser chamado por objetos externos à classe

static significa que o método é estático e deve ser chamado digitando-se [NomeClasse].[nomeMétodo]

int é o tipo do retorno do método. Significa que o método deve retornar um valor de tipo int

getStudentCount nome do método () significa que o método não tem nenhum

argumento

Por enquanto, getStudentCount retornará sempre o valor zero já que ainda não fizemos nada na nossa classe para atribuir o seu valor. Modificaremos o valor de studentCount mais tarde, quando discutirmos construtores.

Dicas de programação:

1. Nomes de métodos devem iniciar com letra MINÚSCULA.2. Nomes de métodos devem conter verbos3. Sempre faça documentação antes da declaração do método. Use o

estilo javadoc para isso.

Introdução à Programação I 13

Page 143: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.5. Exemplo de Código Fonte para a classe StudentRecord

Aqui está o código para a nossa classe StudentRecord:

public class StudentRecord { private String name; private String address; private int age; private double mathGrade; private double englishGrade; private double scienceGrade; private static int studentCount;

/** * Retorna o nome do estudante */ public String getName(){ return name; }

/** * Muda o nome do estudante */ public void setName( String temp ){ name = temp; }

// outros métodos modificadores aqui ....

/** * Calcula a média das classes de inglês, matemática * e ciências */ public double getAverage(){ double result = 0; result = (mathGrade+englishGrade+scienceGrade)/3; return result; } /** * Retorna o número de ocorrências em StudentRecords */ public static int getStudentCount(){ return studentCount; }}

Aqui está um exemplo do código de uma classe que utiliza a nossa classe

Introdução à Programação I 14

Page 144: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

StudentRecord.

public class StudentRecordExample { public static void main( String[] args ){ // criar três objetos para StudentRecord StudentRecord annaRecord = new StudentRecord(); StudentRecord beahRecord = new StudentRecord(); StudentRecord crisRecord = new StudentRecord();

// enviar o nome dos estudantes annaRecord.setName("Anna"); beahRecord.setName("Beah"); crisRecord.setName("Cris");

// mostrar o nome de anna System.out.println(annaRecord.getName()); //mostrar o número de estudantes System.out.println("Count=" + StudentRecord.getStudentCount()); }}

A saída desta classe é:

AnnaCount = 0

Introdução à Programação I 15

Page 145: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. this

O objeto this é usado para acessar atributos de objeto ou métodos da classe. Para entender isso melhor, tomemos o método setAge como exemplo. Suponha que tenhamos o seguinte método para setAge:

public void setAge(int age){ age = age; // Não é uma boa prática}

O nome do argumento nesta declaração é age, que tem o mesmo nome do atributo de objeto age. Já que o argumento age é a declaração mais próxima do método, o valor do argumento age será usado. Na instrução:

age = age;

estamos simplesmente associando o valor do argumento age para si mesmo! Isto não é o que queremos que aconteça no nosso código. A fim de corrigir esse erro, usamos o objeto this. Para utilizar o objeto this, digitamos:

this.<nomeDoAtributo>

O ideal é reescrever o nosso método do seguinte modo:

public void setAge(int age){ this.age = age;}

Este método irá atribuir o valor do argumento age para a atributo de objeto age do objeto StudentRecord.

Introdução à Programação I 16

Page 146: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Overloading de Métodos

Nas nossas classes, podemos necessitar de criar métodos que tenham os mesmos nomes, mas que funcionem de maneira diferente dependendo dos argumentos que informamos. Esta capacidade é chamada de overloading de métodos.

Overloading de métodos permite que um método com o mesmo nome, entretanto com diferentes argumentos, possa ter implementações diferentes e retornar valores de diferentes tipos. Ao invés de inventar novos nomes todas as vezes, o overloading de métodos pode ser utilizado quando a mesma operação tem implementações diferentes.

Por exemplo, na nossa classe StudentRecord, queremos ter um método que mostre as informações sobre o estudante. Entretanto, queremos que o método print mostre dados diferentes dependendo dos argumentos que lhe informamos. Por exemplo, quando não enviamos qualquer argumento queremos que o método print mostre o nome, endereço e idade do estudante. Quando passamos 3 valores double, queremos que o método mostre o nome e as notas do estudante.

Temos os seguintes métodos dentro da nossa classe StudentRecord:

public void print(){ System.out.println("Name:" + name); System.out.println("Address:" + address); System.out.println("Age:" + age);}

public void print(double eGrade, double mGrade, double sGrade) System.out.println("Name:" + name); System.out.println("Math Grade:" + mGrade); System.out.println("English Grade:" + eGrade); System.out.println("Science Grade:" + sGrade);}

Quando tentamos chamar estes métodos no método main, criado para a classe StudantRecordExample:

public static void main(String[] args) { StudentRecord annaRecord = new StudentRecord();

annaRecord.setName("Anna"); annaRecord.setAddress("Philippines"); annaRecord.setAge(15);

Introdução à Programação I 17

Page 147: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

annaRecord.setMathGrade(80); annaRecord.setEnglishGrade(95.5); annaRecord.setScienceGrade(100);

// overloading de métodos annaRecord.print(); annaRecord.print( annaRecord.getEnglishGrade(), annaRecord.getMathGrade(), annaRecord.getScienceGrade());}

teremos a saída para a primeira chamada ao método print:

Name:AnnaAddress:PhilippinesAge:15

e, em seguida, a saída para a segunda chamada ao método print:

Name:AnnaMath Grade:80.0English Grade:95.5Science Grade:100.0

Lembre-se sempre que métodos overload possuem as seguintes propriedades:

1. o mesmo nome2. argumentos diferentes3. tipo do retorno igual ou diferente

Introdução à Programação I 18

Page 148: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Declarando Construtores

Discutimos anteriormente o conceito de construtores. Construtores são importantes na criação de um objeto. É um método onde são colocadas todas as inicializações.

A seguir, temos as propriedades de um construtor:

1. Possuem o mesmo nome da classe2. Construtor é um método, entretanto, somente as seguintes informações

podem ser colocadas no cabeçalho do construtor: ○ Escopo ou identificador de acessibilidade (como public)○ Nome do construtor○ Argumentos, caso necessário

3. Não retornam valor4. São executados automaticamente na utilização do operador new durante

a instanciação da classe

Para declarar um construtor, escrevemos:

[modificador] <nomeClasse> (<argumento>*) { <instrução>*}

7.1. Construtor Padrão (default)

Toda classe tem o seu construtor padrão. O construtor padrão é um construtor público e sem argumentos. Se não for definido um construtor para a classe, então, implicitamente, é assumido um construtor padrão.

Por exemplo, na nossa classe StudentRecord, o construtor padrão é definido do seguinte modo:

public StudentRecord() {}

7.2. Overloading de Construtores

Como mencionamos, construtores também podem sofrer overloading, por exemplo, temos aqui quatro construtores:

public StudentRecord() { // qualquer código de inicialização aqui}public StudentRecord(String temp){

Introdução à Programação I 19

Page 149: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

this.name = temp;}public StudentRecord(String name, String address) { this.name = name; this.address = address;}public StudentRecord(double mGrade, double eGrade, double sGrade) { mathGrade = mGrade; englishGrade = eGrade; scienceGrade = sGrade;}

7.3. Usando Construtores

Para utilizar estes construtores, temos as seguintes instruções:

public static void main(String[] args) { // criar três objetos para o registro do estudante StudentRecord annaRecord = new StudentRecord("Anna"); StudentRecord beahRecord = new StudentRecord("Beah", "Philippines"); StudentRecord crisRecord = new StudentRecord(80,90,100); // algum código aqui}

Antes de continuarmos, vamos retornar o atributo estático studentCount que declaramos agora a pouco. O objetivo de studentCount é contar o número de objetos que são instanciados com a classe StudentRecord. Então, o que desejamos é incrementar o valor de studentCount toda vez que um objeto da classe StudentRecord é instanciado. Um bom local para modificar e incrementar o valor de studentCount é nos construtores, pois são sempre chamados toda vez que um objeto é instanciado. Por exemplo:

public StudentRecord() { studentCount++; // adicionar um estudante}public StudentRecord(String name) { studentCount++; // adicionar um estudante this.name = name;}public StudentRecord(String name, String address) { studentCount++; // adicionar um estudante this.name = name; this.address = address;

Introdução à Programação I 20

Page 150: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}public StudentRecord(double mGrade, double eGrade, double sGrade) { studentCount++; // adicionar um estudante mathGrade = mGrade; englishGrade = eGrade; scienceGrade = sGrade;}

7.4. Utilizando o this()

Chamadas a construtores podem ser cruzadas, o que significa ser possível chamar um construtor de dentro de outro construtor. Usamos a chamada this() para isso. Por exemplo, dado o seguinte código,

public StudentRecord() { this("some string");}public StudentRecord(String temp) { this.name = temp;}public static void main( String[] args ) { StudentRecord annaRecord = new StudentRecord();}

Dado o código acima, quando se executa a instrução do método main, será chamado o primeiro construtor. A instrução inicial deste construtor resultará na chamada ao segundo construtor.

Há algum detalhes que devem ser lembrados na utilização da chamada ao construtor por this():

1. A chamada ao construtor DEVE SEMPRE OCORRER NA PRIMEIRA LINHA DE INSTRUÇÃO

2. UTILIZADO PARA A CHAMADA DE UM CONSTRUTOR. A chamada ao this() pode ser seguida por outras instruções.

Como boa prática de programação, é ideal nunca construir métodos que repitam as instruções. Buscamos a utilização de overloading com o objetivo de evitarmos essa repetição. Deste modo, reescreveremos os construtores da classe StudentRecord para:

public StudentRecord() { studentCount++; // adicionar um estudante}public StudentRecord(String name) { this();

Introdução à Programação I 21

Page 151: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

this.name = name;}public StudentRecord(String name, String address) { this(name); this.address = address;}public StudentRecord(double mGrade, double eGrade, double sGrade) { this(); mathGrade = mGrade; englishGrade = eGrade; scienceGrade = sGrade;}

Introdução à Programação I 22

Page 152: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

8. Pacotes

São utilizados para agrupar classes e interfaces relacionadas em uma única unidade (discutiremos interfaces mais tarde). Esta é uma característica poderosa que oferece um mecanismo para gerenciamento de um grande grupo de classes e interfaces e evita possíveis conflitos de nome.

8.1. Importando Pacotes

Para utilizar classes externas ao pacote da classe, é necessário importar os pacotes dessas classes. Por padrão, todos as suas classes Java importam o pacote java.lang. É por isso que é possível utilizar classes como String e Integer dentro da sua classe, mesmo não tendo importado nenhum pacote explicitamente.

A sintaxe para importar pacotes é como segue:

import <nomeDoPacote>.<nomeDaClasse>;

Por exemplo, necessitar utilizar a classe Color dentro do pacote awt, é necessário a seguinte instrução:

import java.awt.Color;

ou:

import java.awt.*;

A primeira linha de instrução importa especificamente a classe Color enquanto que a seguinte importa todas as classes do pacote java.awt.

Outra maneira de importar classes de outros pacotes é através da referência explícita ao pacote. Isto é feito utilizando-se o nome completo do pacote para declaração do objeto na classe:

java.awt.Color color;

8.2. Criando pacotes

Para criar os nossos pacotes, escrevemos:

package <nomeDoPacote>;

Suponha que desejamos criar um pacote onde colocaremos a nossa classe StudentRecord juntamente com outras classes relacionadas. Chamaremos o

Introdução à Programação I 23

Page 153: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

nosso pacote de schoolClasses.

A primeira coisa que temos que fazer é criar uma pasta chamada schoolClasses. Em seguida, copiar para esta pasta todas as classes que pertençam a este pacote. Adicione a seguinte instrução no arquivo da classe, esta linha deve ser colocada antes da definição da classe. Por exemplo:

package schoolClasses;public class StudentRecord { // instruções da classe}

Pacotes podem ser aninhados. Neste caso, o interpretador espera que a estrutura de diretórios contendo as classes combinem com a hierarquia dos pacotes.

8.3. Definindo a variável de ambiente CLASSPATH

Suponha que colocamos o pacote schoolClasses sob o diretório C:\. Precisamos que a classpath aponte para este diretório de tal forma que quando executemos a classe, a JVM seja capaz de enxergar onde está armazenada.

Antes de discutirmos como ajustar a variável classpath, vamos ver um exemplo sobre o que aconteceria se esta não fosse ajustada.

Suponha que sigamos os passos para compilar e executar a classe StudentRecord que escrevemos:

C:\schoolClasses>javac StudentRecord.java

C:\schoolClasses>java StudentRecordException in thread "main" java.lang.NoClassDefFoundError: StudentRecord (wrong name: schoolClasses/StudentRecord) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$100(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source)

Surge o erro NoClassDefFoundError, que significa que o Java desconhece onde procurar por esta classe. A razão disso é que a sua classe

Introdução à Programação I 24

Page 154: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

StudentRecord pertence a um pacote denominado schoolClasses. Se desejamos executar esta classe, teremos que dizer ao Java o seu nome completo schoolClasses.StudentRecord. Também teremos que dizer à JVM onde procurar pelos nossos pacotes, que, neste caso, é no C:\. Para fazer isso, devemos definir a variável classpath.

Para definir a variável classpath no Windows, digitamos o seguinte na linha de comando:

C:\schoolClasses>set classpath=C:\

onde C:\ é o diretório onde colocamos os pacotes. Após definir a variável classpath, poderemos executar a nossa classe em qualquer pasta, digitando:

C:\schoolClasses>java schoolClasses.StudentRecord

Para sistemas baseados no Unix, suponha que as nossas classes estejam no diretório /usr/local/myClasses, escrevemos:

export classpath=/usr/local/myClasses

Observe que é possível definir a variável classpath em qualquer lugar. É possível definir mais de um local de pesquisa; basta separá-los por ponto-e-vírgula (no Windows) e dois-pontos (nos sistemas baseados em Unix). Por exemplo:

set classpath=C:\myClasses;D:\;E:\MyPrograms\Java

e para sistemas baseados no Unix:

export classpath=/usr/local/java:/usr/myClasses

Introdução à Programação I 25

Page 155: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

9. Modificadores de Acesso

Quando estamos criando as nossas classes e definindo as suas propriedades e métodos, queremos implementar algum tipo de restrição para se acessar esses dados. Por exemplo, ao necessitar que um certo atributo seja modificado apenas pelos métodos dentro da classe, é possível esconder isso dos outros objetos que estejam usando a sua classe. Para implementar isso, no Java, temos os modificadores de acesso.

Existem quatro diferentes tipos de modificadores de acesso: public, private, protected e default. Os três primeiros modificadores são escritos explicitamente no código para indicar o acesso, para o tipo default, não se utiliza nenhuma palavra-chave.

9.1. Acesso padrão

Especifica que os elementos da classe são acessíveis somente aos métodos internos da classe e às suas subclasses. Não há palavra chave para o modificador default; sendo aplicado na ausência de um modificador de acesso. Por exemplo :

public class StudentRecord { // acesso padrão ao atributo int name;

// acesso padrão para o método String getName(){ return name; }}

O atributo de objeto name e o método getName() podem ser acessados somente por métodos internos à classe e por subclasses de StudentRecord. Falaremos sobre subclasses em próximas lições.

9.2. Acesso público

Especifica que os elementos da classe são acessíveis tanto internamente quanto externamente à classe. Qualquer objeto que interage com a classe pode ter acesso aos elementos públicos da classe. Por exemplo:

public class StudentRecord { // acesso público o atributo public int name;

// acesso público para o método

Introdução à Programação I 26

Page 156: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public String getName(){ return name; }}

O atributo de objeto name e o método getName() podem ser acessados a partir de outros objetos.

9.3. Acesso protegido

Especifica que somente classes no mesmo pacote podem ter acesso aos atributos e métodos da classe. Por exemplo:

public class StudentRecord { //acesso protegido ao atributo protected int name;

//acesso protegido para o método protected String getName(){ return name; }}

O atributo de objeto name e o método getName() podem ser acessados por outros objetos, desde que o objetos pertençam ao mesmo pacote da classe StudentRecord.

9.4. Acesso particular

Especifica que os elementos da classe são acessíveis somente na classe que o definiu. Por exemplo:

public class StudentRecord { // acesso particular ao atributo private int name;

// acesso particular para o método private String getName(){ return name; }}

O atributo de objeto name e o método getName() podem ser acessados somente por métodos internos à classe.

Introdução à Programação I 27

Page 157: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. Normalmente, os atributos de objeto de uma classe devem ser declarados particulares e a classe pode fornecer métodos assessores e modificadores para estes.

Introdução à Programação I 28

Page 158: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

10. Exercícios

10.1. Registro de Agenda

Sua tarefa é criar uma classe que contenha um Registro de Agenda. A tabela 1 descreve as informações que um Registro de Agenda deve conter:

Atributos/Propriedades Descrição

Nome Nome da pessoa

Endereço Endereço da pessoa

Número de Telefone Número de telefone da pessoa

email Endereço eletrônico da pessoa

Tabela 1: Atributos e Descrições dos Atributos

Crie os seguintes métodos:

1. Forneça todos os métodos assessores e modificadores necessários para todos os atributos.

2. Construtores.

10.2. Agenda

Crie uma classe Agenda que possa conter entradas de objetos tipo Registro de Agenda (utilize a classe criada no primeiro exercício). Devem ser oferecidos os seguintes métodos para a agenda:

1. Adicionar registro2. Excluir registro3. Visualizar registros4. Modificar um registro

Introdução à Programação I 29

Page 159: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 11Herança, polimorfismo e interfaces

Versão 1.0 - Jan/2007

Page 160: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição será discutido como uma classe pode herdar as propriedades de outra classe já existente. Uma classe que faz isso é chamada de subclasse, e sua classe pai é chamada de superclasse. Será também discutida a aplicação automática dos métodos de cada objeto, independente da subclasse deste. Esta propriedade é conhecida como polimorfismo. E, por último, discutiremos sobre interfaces, que ajudam a reduzir no esforço de programação.

Ao final desta lição, o estudante será capaz de:

• Definir superclasses e subclasses

• Criar override de métodos das superclasses

• Criar métodos final e classes final

Introdução à Programação I 4

Page 161: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Herança

Todas as classes, incluindo as que compõem a API Java, são subclasses da classe Object. Um exemplo de hierarquia de classes é mostrado com a figura 1.

A partir de uma determinada classe, qualquer classe acima desta na hierarquia de classes é conhecida como uma superclasse (ou classe Pai). Enquanto que qualquer classe abaixo na hierarquia de classes é conhecia como uma subclasse (ou classe Filho).

Figura 1: Hierarquia de Classes

Herança é um dos principais princípios em orientação a objeto. Um comportamento (método) é definido e codificado uma única vez em uma única classe e este comportamento é herdado por todas suas subclasses. Uma subclasse precisa apenas implementar as diferenças em relação a sua classe pai, ou seja, adaptar-se ao meio em que vive.

2.1. Definindo Superclasses e Subclasses

Para herdar uma classe usamos a palavra-chave extends. Ilustraremos criando uma classe pai de exemplo. Suponha que tenhamos uma classe pai chamada Person.

public class Person { protected String name; protected String address; /** * Construtor Padrão */ public Person(){ System.out.println("Inside Person:Constructor"); name = ""; address = ""; } /** * Construtor com 2 parâmetros */ public Person( String name, String address ){ this.name = name; this.address = address; } /** * Métodos modificadores e acessores */ public String getName(){ return name;

Introdução à Programação I 5

Page 162: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} public String getAddress(){ return address; } public void setName( String name ){ this.name = name; } public void setAddress( String add ){ this.address = add; }}

Os atributos name e address são declarados como protected. A razão de termos feito isto é que queremos que estes atributos sejam acessíveis às subclasses dessa classe. Se a declararmos com o modificador private, as subclasses não estarão aptas a usá-los. Todas as propriedades de uma superclasse que são declaradas como public, protected e default podem ser acessadas por suas subclasses.

Vamos criar outra classe chamada Student. E, como um estudante também é uma pessoa, concluímos que iremos estender a classe Person, então, poderemos herdar todas as propriedades existêntes na classe Person. Para isto, escrevemos:

public class Student extends Person {public Student(){

System.out.println("Inside Student:Constructor");//Algum código aqui

}

// Algum código aqui}

O fluxo de controle é mostrado na figura 2.

Figura 2: Fluxo do Programa

Quando a classe Student for instanciada, o construtor padrão da superclasse Person é invocado implicitamente para fazer as inicializações necessárias. Após isso, as instruções dentro do construtor da subclasse são executadas. Para ilustrar, considere o seguinte código:

Introdução à Programação I 6

Page 163: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public static void main( String[] args ){Student anna = new Student();

}

No código, criamos um objeto da classe Student. O resultado da execução deste programa é:

Inside Person:ConstructorInside Student:Constructor

2.2. super

Uma subclasse pode, explicitamente, chamar um construtor de sua superclasse imediata. Isso é feito utilizando uma chamada ao objeto super. Uma chamada ao super no construtor de uma subclasse irá resultar na execução de um construtor específico da superclasse baseado nos argumentos passados.

Por exemplo, dada a seguinte instrução para a classe Student:

public Student(){super( "SomeName", "SomeAddress" );System.out.println("Inside Student:Constructor");

}

Este código chama o segundo construtor de sua superclasse imediata (a classe Person) e a executa. Outro código de exemplo é mostrado abaixo:

public Student(){super();System.out.println("Inside Student:Constructor");

}

Este código chama o construtor padrão de sua superclasse imediata (a classe Person) e o executa.

Devemos relembrar, quando usamos uma chamada ao objeto super:

1. A instrução super() DEVE SER A PRIMEIRA INSTRUÇÃO EM UM CONSTRUTOR.2. As instruções this() e super() não podem ocorrer simultaneamente no mesmo construtor.

O objeto super é uma referência aos membros da superclasse (assim como o objeto this é da sua própria classe). Por exemplo:

public Student() {super.name = "person name"; // Nome da classe paithis.name = "student name"; // Nome da classe atual

}

2.3. Override de Métodos

Se, por alguma razão, uma classe derivada necessita que a implementação de algum método seja diferente da superclasse, o polimorfismo por override pode vir a ser muito útil. Uma subclasse pode modificar um método definido em sua superclasse fornecendo uma nova implementação para aquele método.

Introdução à Programação I 7

Page 164: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Supondo que tenhamos a seguinte implementação para o método getName da superclasse Person:

public class Person { ... public String getName(){ System.out.println("Parent: getName"); return name; } ...}

Para realizar um polimorfismo por override no método getName da subclasse Student, escrevemos:

public class Student extends Person { ... public String getName(){ System.out.println("Student: getName"); return name; } ...}

Então, quando invocarmos o método getName de um objeto da classe Student, o método chamado será o de Student, e a saída será:

Student: getName

É possível chamar o método getName da superclasse, basta para isso:

public class Student extends Person { ... public String getName() { super.getName(); System.out.println("Student: getName"); return name; } ...}

Inserimos uma chamada ao objeto super e a saída será:

Parent: getName Student: getName

2.4. Métodos final e Classes final

Podemos declarar classes que não permitem a herança. Estas classes são chamadas classes finais. Para definir que uma classe seja final, adicionamos a palavra-chave final na declaração da classe (na posição do modificador). Por exemplo, desejamos que a classe Person não possa ser herdada por nenhuma outra classe, escrevemos:

public final class Person {// Código da classe aqui

}

Introdução à Programação I 8

Page 165: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Muitas classes na API Java são declaradas final para certificar que seu comportamento não seja herdado e, possivelmente , modificado. Exemplos, são as classes Integer, Double e Math.

Também é possível criar métodos que não possam ser modificados pelos filhos, impedindo o polimorfismo por override. Estes métodos são o que chamamos de métodos finais. Para declarar um método final, adicionamos a palavra-chave final na declaração do método (na posição do modificador). Por exemplo, se queremos que o método getName da classe Person não possa ser modificado, escrevemos:

public final String getName(){return name;

}

Caso o programador tente herdar uma classe final, ocorrerá um erro de compilação. O mesmo acontecerá ao se tentar fazer um override de um método final.

Introdução à Programação I 9

Page 166: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. PolimorfismoConsiderando a classe pai Person e a subclasse Student do exemplo anterior, adicionaremos outra subclasse a Person, que se chamará Employee. Abaixo está a hierarquia de classes que ilustra o cenário:

Podemos criar uma referência do tipo da superclasse para a subclasse. Por exemplo:

public static main( String[] args ) { Person ref; Student studentObject = new Student(); Employee employeeObject = new Employee(); ref = studentObject; //Person ref: ponteiro para um Student // algum código aqui}

Supondo que tenhamos um método getName em nossa superclasse Person, iremos realizar uma modificação deste nas subclasses Student e Employee:

public class Person { public String getName(){ System.out.println("Person Name:" + name); return name; }}public class Student extends Person { public String getName(){ System.out.println("Student Name:" + name); return name; }}public class Employee extends Person { public String getName(){ System.out.println("Employee Name:" + name); return name; }}

Voltando ao método main, quando tentamos chamar o método getName da referência ref do tipo Person, o método getName do objeto Student será chamado. Agora, se atribuirmos ref ao objeto Employee, o método getName de Employee será chamado.

public static main(String[] args) { Person ref; Student studentObject = new Student(); Employee employeeObject = new Employee(); ref = studentObject; //ponteiro de referência para um Student String temp = ref.getName(); //getName de Student é chamado

Introdução à Programação I 10

Figura 3: Hieraquia para a classe Person e suas subclasses.

Page 167: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

System.out.println(temp); ref = employeeObject; // ponteiro de referência Person para um // objeto Employee String temp = ref.getName(); // getName de Employee // classe é chamada System.out.println(temp);}

A capacidade de uma referência mudar de comportamento de acordo com o objeto a que se refere é chamada de polimorfismo. O polimorfismo permite que múltiplos objetos de diferentes subclasses sejam tratados como objetos de uma única superclasse, e que automaticamente sejam selecionados os métodos adequados a serem aplicados a um objeto em particular, baseado na subclasse a que ele pertença.

Outro exemplo que demonstra o polimorfismo é realizado ao passar uma referência a métodos. Supondo que exista um método estático printInformation que recebe como parâmetro um objeto do tipo Person, pode-se passar uma referência do tipo Employee e do tipo Student, porque são subclasses do tipo Person.

public static main(String[] args) { Student studentObject = new Student(); Employee employeeObject = new Employee(); printInformation(studentObject); printInformation(employeeObject);}public static printInformation(Person p){ ...}

Introdução à Programação I 11

Page 168: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Classes Abstratas

Para criar métodos em classes devemos, necessariamente, saber qual o seu comportamento. Entretanto, em muitos casos não sabemos como estes métodos se comportarão na classe que estamos criando, e, por mera questão de padronização, desejamos que as classes que herdem desta classe possuam, obrigatoriamente, estes métodos.

Por exemplo, queremos criar uma superclasse chamada LivingThing. Esta classe tem certos métodos como breath, sleep e walk. Entretanto, existem tantos métodos nesta superclasse que não podemos generalizar este comportamento. Tome por exemplo, o método walk (andar). Nem todos os seres vivos andam da mesma maneira. Tomando os humanos como exemplo, os humanos andam sobre duas pernas, enquanto que outros seres vivos como os cães andam sobre quatro. Entretanto, existem muitas características que os seres vivos têm em comum, isto é o que nós queremos ao criar uma superclasse geral.

Para realizarmos isto, teremos que criar uma superclasse que possua alguns métodos com implementações e outros não. Este tipo de classe é chamada de classe abstrata.

Uma classe abstrata é uma classe que não pode gerar um objeto. Freqüentemente aparece no topo de uma hierarquia de classes no modelo de programação orientada a objetos.

Os métodos nas classes abstratas que não têm implementação são chamados de métodos abstratos. Para criar um método abstrato, apenas escreva a assinatura do método sem o corpo e use a palavra-chave abstract. Por exemplo:

public abstract void someMethod();

Agora, vamos criar um exemplo de classe abstrata:

public abstract class LivingThing { public void breath(){ System.out.println("Living Thing breathing..."); } public void eat(){ System.out.println("Living Thing eating..."); } /** * método abstrato walk * Queremos que este método seja criado pela * subclasse de LivingThing */ public abstract void walk();}

Quando uma classe estende a classe abstrata LivingThing, ela é obrigada a implementar o método abstrato walk. Por exemplo:

Introdução à Programação I 12

Figura 4: Classe Abstrata

Page 169: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public class Human extends LivingThing { public void walk(){ System.out.println("Human walks..."); }}

Se a classe Human não implementar o método walk, será mostrada a seguinte mensagem de erro de compilação:

Human.java:1: Human is not abstract and does not override abstract method walk() in LivingThingpublic class Human extends LivingThing ^1 error

Dicas de programação:

1. Use classes abstratas para definir muitos tipos de comportamentos no topo de uma hierarquia de classes de programação orientada a objetos. Use suas subclasses para prover detalhes de implementação da classe abstrata.

Introdução à Programação I 13

Page 170: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Interfaces

Uma interface é um tipo especial de classe que contém unicamente métodos abstratos ou atributos finais. Interfaces, por natureza, são abstratas.

Interfaces definem um padrão e o caminho público para especificação do comportamento de classes. Permitem que classes, independente de sua localização na estrutura hierárquica, implementem comportamentos comuns.

5.1. Porque utilizar Interfaces?

Utilizamos interfaces quando queremos classes não relacionadas que implementem métodos similares. Através de interfaces, podemos obter semelhanças entre classes não relacionadas sem forçar um relacionamento artificial entre elas.

Tomemos como exemplo a classe Line, contém métodos que obtém o tamanho da linha e compara o objeto Line com objetos de mesma classe. Considere também que tenhamos outra classe, MyInteger, que contém métodos que comparam um objeto MyInteger com objetos da mesma classe. Podemos ver que ambas classes têm os mesmos métodos similares que os comparam com outros objetos do mesmo tipo, entretanto eles não são relacionados. Para se ter certeza de que essas classes implementem os mesmos métodos com as mesmas assinaturas, utilizamos as interfaces. Podemos criar uma interface Relation que terá declarada algumas assinaturas de métodos de comparação. A interface Relation pode ser implementada da seguinte forma:

public interface Relation { public boolean isGreater(Object a, Object b); public boolean isLess(Object a, Object b); public boolean isEqual(Object a, Object b);}

Outra razão para se utilizar interfaces na programação de objetos é revelar uma interface de programação de objeto sem revelar essas classes. Como veremos mais adiante, podemos utilizar uma interface como tipo de dados.

Finalmente, precisamos utilizar interfaces como mecanismo alternativo para herança múltipla, que permite às classes em ter mais de uma superclasse. A herança múltipla não está implementada em Java.

5.2. Interface vs. Classe Abstrata

A principal diferença entre uma interface e uma classe abstrata é que a classe abstrata pode possuir métodos implementados (reais) ou não implementados (abstratos). Na interface, todos os métodos são obrigatoriamente abstratos e públicos, tanto que para esta, a palavra-chave abstract ou public é opcional.

5.3. Interface vs. Classe

Uma característica comum entre uma interface e uma classe é que ambas são tipos. Isto significa que uma interface pode ser usada no lugar onde uma classe é esperada. Por exemplo,

Introdução à Programação I 14

Page 171: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

dadas a classe Person e a interface PersonInterface, as seguintes declarações são válidas:

PersonInterface pi = new Person();Person pc = new Person();

Entretanto, não se pode criar uma instância de uma interface sem implementá-la. Um exemplo disso é:

PersonInterface pi = new PersonInterface(); //ERRO DE //COMPILAÇÃO !!!

Outra característica comum é que ambas, interfaces e classes, podem definir métodos, embora uma interface não possa tê-los implementados. Já uma classe pode.

5.4. Criando Interfaces

Para criarmos uma interface, utilizamos:

[public] [abstract] interface <NomeDaInterface> { < [public] [final] <tipoAtributo> <atributo> = <valorInicial>; >* < [public] [abstract] <retorno> <nomeMetodo>(<parametro>*); >*}

Como exemplo, criaremos uma interface que define o relacionamento entre dois objetos de acordo com a "ordem natural" dos objetos:

interface Relation { boolean isGreater(Object a, Object b); boolean isLess(Object a, Object b); boolean isEqual( Object a, Object b);}

Para implementar esta interface, usaremos a palavra chave "implements". Por exemplo:

/** * Esta classe define um segmento de linha */public class Line implements Relation { private double x1; private double x2; private double y1; private double y2; public Line(double x1, double x2, double y1, double y2) { this.x1 = x1; this.x2 = x2; this.y2 = y2; this.y1 = y1; } public double getLength(){ double length = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); return length; } public boolean isGreater( Object a, Object b){ double aLen = ((Line)a).getLength(); double bLen = ((Line)b).getLength(); return (aLen > bLen);

Introdução à Programação I 15

Page 172: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} public boolean isLess( Object a, Object b){ double aLen = ((Line)a).getLength(); double bLen = ((Line)b).getLength(); return (aLen < bLen); } public boolean isEqual( Object a, Object b){ double aLen = ((Line)a).getLength(); double bLen = ((Line)b).getLength(); return (aLen == bLen); }}

Quando a classe implementa uma interface, deve-se implementar todos os métodos desta, caso contrário será mostrado o erro:

Line.java:4: Line is not abstract and does not override abstract method isGreater(java.lang.Object,java.lang.Object) in Relationpublic class Line implements Relation ^1 error

Dicas de programação:

1. Use interface para criar uma definição padrão de métodos em classes diferentes. Uma vez que o conjunto de definições de métodos é criado, e pode ser escrito um método simples para manipular todas as classes que implementam a interface.

5.5. Relacionamento de uma Interface para uma Classe

Como vimos nas seções anteriores, a classe pode implementar uma interface e para isso prover o código de implementação para todos os métodos definidos na interface.

Outro detalhe a se notar na relação entre uma interface e uma classe. A classe pode apenas estender uma única superclasse, mas pode implementar diversas interfaces. Um exemplo de uma classe que implementa diversas interfaces:

public class Person implements PersonInterface, LivingThing, WhateverInterface {

//algumas linhas de código}

Outro exemplo de uma classe que estende de outra superclasse e implementa interfaces:

public class ComputerScienceStudent extends Student implements PersonInterface, LivingThing {

// algumas linhas de código}

Uma interface não é parte de uma hierarquia de classes. Classes não relacionadas podem implementar a mesma interface.

Introdução à Programação I 16

Page 173: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5.6. Herança entre Interfaces

Interfaces não são partes de uma hierarquia de classes. Entretanto, interfaces podem ter relacionamentos entre si. Por exemplo, suponha que tenhamos duas interfaces, StudentInterface e PersonInterface. Se StudentInterface estende PersonInterface, esta herda todos os métodos declarados em PersonInteface.

public interface PersonInterface { ...}public interface StudentInterface extends PersonInterface { ...}

Introdução à Programação I 17

Page 174: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Exercícios

6.1. Estendendo StudentRecord

Neste exercício, queremos criar um registro mais especializado de Student que contém informações adicionais sobre um estudante de Ciência da Computação. Sua tarefa é estender a classe StudentRecord que foi implementada nas lições anteriores e acrescentar atributos e métodos que são necessários para um registro de um estudante de Ciência da Computação. Utilize override para modificar alguns métodos da superclasse StudentRecord, caso seja necessário.

6.2. A classe abstrata Shape

Crie uma classe abstrata chamada Shape com os métodos abstratos getArea() e getName(). Escreva duas de suas subclasses Circle e Square. E acrescente métodos adicionais a estas subclasses.

Introdução à Programação I 18

Page 175: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação I

Lição 12Tratamento básico de exceções

Versão 1.0 - Jan/2007

Page 176: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição, iremos aprender uma técnica utilizada em Java para tratar condições incomuns que interrompem a operação normal da classe. Esta técnica é chamada de tratamento de exceção.

Ao final desta lição, o estudante será capaz de:

• Definir o que são exceções

• Tratar exceções utilizando try-catch-finally

Introdução à Programação I 4

Page 177: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. O que são Exceções (Exception)?

Uma exceção é um evento que interrompe o fluxo normal de processamento de uma classe. Este evento é um erro de algum tipo. Isto causa o término anormal da classe.

Estes são alguns dos exemplos de exceções que podem ter ocorridos em exercícios anteriores:

● ArrayIndexOutOfBoundsException, ocorre ao acessar um elemento inexistente de um array.

● NumberFormatException, ocorre ao enviar um parâmetro não-numérico para o método Integer.parseInt().

Introdução à Programação I 5

Page 178: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Tratando Exceções

Para tratar exceções em Java utilizamos a declaração try-catch-finally. O que devemos fazer para proteger as instruções passíveis de gerar uma exceção, é inserí-las dentro deste bloco.

A forma geral de um try-catch-finally é:

try{ // escreva as instruções passíveis de gerar uma exceção // neste bloco} catch (<exceptionType1> <varName1>){ // escreva a ação que o seu programa fará caso ocorra // uma exceção de um determinado} . . .} catch (<exceptionTypen> <varNamen>){ // escreva a ação que o seu programa fará caso ocorra // uma exceção de um determinado tipo} finally { // escreva a ação que o seu programa executará caso ocorra // ou não um erro ou exceção}

Exceções geradas durante a execução do bloco try podem ser detectadas e tratadas num bloco catch. O código no bloco finally é sempre executado, ocorrendo ou não a exceção.

A seguir são mostrados os principais aspectos da sintaxe da construção de um try-catch-finally:

• A notação de bloco é obrigatória.• Para cada bloco try, pode haver um ou mais blocos catch, mas somente um bloco

finally.• Um bloco try deve que ser seguido de PELO MENOS um bloco catch OU um bloco

finally, ou ambos.• Cada bloco catch define o tratamento de uma exceção.• O cabeçalho do bloco catch recebe somente um argumento, que é a exceção

(Exception) que este bloco pretende tratar.• A exceção deve ser da classe Throwable ou de uma de suas subclasses.

Para um melhor entendimento, observe a figura 1 que demonstra o fluxo seguido pelo try-catch-finally:

Introdução à Programação I 6

Page 179: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Tomemos, por exemplo, uma classe que imprime o segundo argumento passado através da linha de comandos. Supondo que não há verificação no código para o número de argumentos.

public class ExceptionExample { public static void main( String[] args ) { System.out.println(args[1]); System.out.println("Finish"); }}

Ao executar esta classe sem informar nenhum argumento e, ao tentar acessar diretamente, conforme o exemplo descrito, o segundo argumento args[1], uma exceção é obtida que interromperá a execução normal do programa, e a seguinte mensagem será mostrada:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at ExceptionExample.main(ExceptionExample.java:5)

Para prevenir que isto ocorra, podemos colocar o código dentro de um bloco try-catch. O bloco finally é opcional. Neste exemplo, não utilizaremos o bloco finally.

public class ExceptionExample{ public static void main( String[] args ){

try { System.out.println( args[1] ); } catch (ArrayIndexOutOfBoundsException exp) { System.out.println("Exception caught!");

Introdução à Programação I 7

Figura 1: Fluxo em um try-catch-finally

Page 180: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} System.out.println("Finish"); }}

Assim, quando tentarmos rodar o programa novamente sem a informação dos argumentos, a saída trataria a exceção e o fluxo do programa não seria interrompido, mostrando o resultado:

Exception caught!Finish

Introdução à Programação I 8

Page 181: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Exercícios

4.1. Capturando Exceções 1

Dada a seguinte classe:

public class TestException { public static void main(String[] args) { for (int i=0; true; i++) { System.out.println("args["+i+"]="+ args[i]); } System.out.println("Quiting..."); }}

Compile e rode a classe TestException. E como saída será:

java TestExceptions one two threeargs[0]=oneargs[1]=twoargs[2]=threeException in thread "main"

java.lang.ArrayIndexOutOfBoundsException: 3 at TestExceptions.main(1.java:4)

Modifique a classe TestException para tratar esta exceção. A saída depois do tratamento da exceção deverá ser:

java TestExceptions one two threeargs[0]=oneargs[1]=twoargs[2]=threeException caught: java.lang.ArrayIndexOutOfBoundsException: 3Quiting...

4.2. Capturando Exceções 2

Há uma boa chance de que algumas classes escritas anteriormentes tenham disparados exceções. Como as exceções não foram tratadas, simplesmente interromperam a execução. Retorne a estes programas e implemente o tratamento de exceções.

Introdução à Programação I 9

Page 182: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação 1

Apêndice A

Instalação do Java e do NetBeans

Versão 1.0 - Jan/2007

Page 183: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Neste apêndice, veremos como instalar o Java, versão JDK, e o NetBeans no seu sistema (Ubuntu Dapper/Windows). Efetue os downloads na página web da Sun Microsystems no endereço http://java.sun.com para o JDK 5.0.x e na página web do projeto NetBeans no endereço http://www.netbeans.org/downloads para o NetBeans 5.5. Antes de começar a instalação, copie, primeiramente, os arquivos instaladores para seu disco rígido.

Para Ubuntu Dapper:Copie todos os instaladores para a pasta /usr.

Para Windows:Copie os instaladores em qualquer diretório temporário.

Introdução à Programação I 4

Page 184: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Instalando Java no Ubuntu Dapper

Passo 1: No diretório onde foi efetuado o download dos instaladores.

Passo 2: Antes de executar o instalador, assegure-se de que o arquivo seja um executável. Para tanto, pressione o botão direito do mouse no ícone do instalador, e em seguida selecione Properties. Selecione na aba Permissions, e então marque a opção Execute. Feche a janela.

Passo 3: Duplo-clique no arquivo jdk-1_5_0_07-linux-i586.bin. A caixa de diálogo abaixo será mostrada. Pressione o botão Run in Terminal.

Introdução à Programação I 5

Page 185: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

No console será mostrado o contrato de licença do software.

Pressione ENTER até ser mostrada a pergunta: Do you agree to the above license terms? [yes or no]. Caso concorde com os termos apresentados digite a palavra yes e pressione a tecla ENTER. Aguarde que o instalador termine de descompactar e instale o Java.

Passo 4: Devemos um caminho de pesquisa a fim de permitir a execução de comandos java em qualquer local. Para isto, entraremos na pasta /usr/local/bin. Digitando:

cd /usr/local/bin

Introdução à Programação I 6

Page 186: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Para criar os links simbólicos para os comandos, tecle:

sudo ln -s /usr/java/jdk1.5.0_07/bin/* .

Introdução à Programação I 7

Page 187: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Instalando Java no Windows

Passo 1: Utilizando o Windows Explorer, vá até a pasta onde estiver o instalador Java.

Figura 1: Pasta contendo os instaladores

Passo 2: Para executar o instalador, duplo-clique no ícone. A caixa de diálogo do instalador J2SE será mostrada com o contrato. Selecione a opção I accept the terms in the license agreement caso concorde com os termos apresentados e pressione o botão Next >.

Figura 2: Contrato de Licença

Esta próxima janela define o que será instalado. Pressione o botão Next > para continuar a instalação.

Introdução à Programação I 8

Page 188: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 3: Instalação Customizada

O processo de instalação poderá demorar um pouco, ao término a seguinte janela será mostrada, pressione o botão Finish para completar a instalação.

Introdução à Programação I 9

Figura 4: Fim da instalação

Page 189: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Instalando NetBeans no Ubuntu DapperPasso 1: Vá para a pasta onde estiver o instalador do NetBeans.

Passo 2: Antes de executar o instalador, assegure-se de que o arquivo seja executável. Para tanto, utilize o botão direito do mouse no ícone do instalador e, em seguida selecione Properties. Selecione a aba Permissions, e marque a opção Execute. Encerre a janela.

Introdução à Programação I 10

Page 190: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 3: Duplo-clique no arquivo de instalação do NetBeans. Pressione o botão Run in Terminal.

Será mostrada uma caixa de diálogo do NetBeans 5.5. Pressione o botão Next >.

Na próxima janela o termos da licença serão mostrados, caso concorde selecione a opção I accept the terms in the license agreement, e então pressione o botão Next >.

Introdução à Programação I 11

Page 191: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Modifique o nome do diretório para: /usr/java/netbeans-5.5, então pressione o botão Next >.

Na pasta do JDK, selecione /usr/java/jdk1.5.0_07, e então pressione o botão Next >.

Introdução à Programação I 12

Page 192: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A próxima caixa de diálogo mostra apenas informações sobre o NetBeans que você está instalando. Pressione o botão Next >. Aguarde o NetBeans terminar o processo de instalação.

Pressione o botão Finish para completar a instalação.

Introdução à Programação I 13

Page 193: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 4: A fim de possibilitar a execução do NetBeans a partir de qualquer pasta no computador, precisamos criar um caminho de pesquisa. Para isso, entramos na pasta :/usr/local/bin. com o comando:

cd /usr/local/bin

Crie um caminho de pesquisa para o NetBeans, digitando:

sudo ln -s /usr/java/netbeans-5.5 .

É possível executar o NetBeans a partir de qualquer pasta, digitando:

netbeans &

Introdução à Programação I 14

Page 194: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Instalando NetBeans no Windows

Passo 1: Através do Windows Explorer, localize a pasta do instalador do NetBeans.

Passo 2: Para executar o instalador, dê um duplo-clique no ícone do instalador. O assistente de instalação do NetBeans será mostrado. Pressione o botão Next > para iniciar o processo de instalação.

Figura 6: Instalação do NetBeans

Introdução à Programação I 15

Figura 5: Arquivo instalador do NetBeans

Page 195: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A página do contrato será mostrada. Caso concorde com os termos selecione a opção I accept the terms in the license agreement e pressione o botão Next > para continuar.

O instalador solicitará a pasta que deve ser instado o NetBeans. Se desejar modifique a pasta sugerida pressionando o botão Browse, e ao término pressione o botão Next >.

O próximo passo é selecionar uma JDK existente em seu computador. Pressione o botão Next > para continuar.

Introdução à Programação I 16

Figura 8: Selecione o diretório onde o NetBeans será instalado

Figura 7: Contrato de Licença

Page 196: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Em seguida, o instalador informará a localização e o espaço em disco que o NetBeans irá ocupar depois de instalado no seu computador. Pressione o botão Next > e aguarde o término da instalação.

Figura 10: Sumário da Instalação

No momento que o NetBeans terminar de ser instalado em seu computador. Pressione o botão Finish para encerrar o processo.

Introdução à Programação I 17

Figura 9: Selecione a JDK a ser utilizada

Page 197: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Introdução à Programação I 18

Figura 11: Instalação efetuada com sucesso

Page 198: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação 1

Apêndice B

Conhecendo seu ambiente de programação (versão Windows XP)

Versão 1.0 - Jan/2007

Page 199: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Neste apêndice, discutiremos como escrever, compilar e executar programas em Java. Existem duas maneiras para se fazer isto: a primeira é utilizando uma console e um editor de texto; e a segunda é utilizando o NetBeans, que é um Integrated Development Environment (Ambiente Integrado de Desenvolvimento) ou IDE.

Um IDE é um progama que contempla um construtor de interface gráfica (GUI builder), um editor de código ou texto, um compilador e um depurador de erros.

Introdução à Programação I 4

Page 200: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Primeiro Programa em JavaAntes de entrarmos em detalhes, vejamos o programa em Java que escreveremos:

public class Hello { /** * Meu primeiro programa em Java */ public static void main(String[] args) {

//imprime o texto "Hello world" na tela System.out.println("Hello world!"); } }

Introdução à Programação I 5

Page 201: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Utilizando um Editor de Texto e uma Console

Para este exemplo, utilizaremos o editor de texto "Notepad" (Bloco de notas do Windows) para editar o código-fonte em Java. Podem ser utilizados quaisquer outros editores de texto. Também será necessário abrir uma janela de console para compilar e executar o programa.

Passo 1: Para iniciar o Notepad, clique em Iniciar Todos os Programas Accessórios Notepad.

Figura 1: Clique em Start All Programs Accessories Notepad

Figura 2: Programa Notepad

Passo 2: Para abrir uma janela de console, clique em Start Programs Accessories Comand Prompt.

Figura 3: Janela de Console do Windows

Passo 3: Escreva o código-fonte, descrito na seção 2, no editor:

Introdução à Programação I 6

Page 202: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 4: Salve o programa em um arquivo chamado "Hello.java" dentro de uma pasta chamada MYJAVAPROGRAMS. Selecione no menu a opção File na barra de menus e então selecione a opção Save.

Depois de executar o procedimento acima descrito, uma caixa de diálogo será mostrada, conforme a Figura 4.

Figura 4: Esta caixa de diálogo aparece depois de clicar em File Save

Pressione o botão MY DOCUMENTS para abrir a pasta My Documents onde salvaremos nossos programas em Java.

Introdução à Programação I 7

Page 203: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 5: Selecione no botão circulado.

Criaremos uma nova pasta, dentro da pasta My Documents, onde salvaremos nossos programas. Iremos nomeá-la como MYJAVAPROGRAMS. Pressione o botão circulado conforme mostrado na Figura 6 para criar a pasta.

Figura 6: Clicar no botão circulado criará uma nova pasta.

Após criar a pasta, digite o nome MYJAVAPROGRAMS, e então pressione a tecla ENTER.

Introdução à Programação I 8

Page 204: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Criamos a pasta aonde salvaremos os arquivos, dê um duplo-clique nesta para abrí-la. Será mostrada uma janela como a figura seguinte. A pasta deverá estar vazia por ora, pois foi recém-criada e ainda não foi salvo nenhum arquivo.

Selecione a caixa de seleção Save as type, a fim de que possamos escolher o tipo de arquivo que queremos salvar. Marque a opção All Files.

Introdução à Programação I 9

Page 205: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Digite "Hello.java" como nome do seu programa na caixa de texto Filename, e então pressione o botão Save.

Observe que o título da janela mudou de Untitled - Notepad para Hello.java - Notepad. Para efetuar alterações no arquivo, edite-o, e então salve-o novamente através das opções File Save.

Introdução à Programação I 10

Page 206: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 5: Para compilar o programa, utilizaremos a janela de console aberta no passo 2. Normalmente, esta janela é iniciada no que chamamos de home folder (pasta do usuário). Para ver uma lista do conteúdo desta pasta, digite DIR e pressione Enter. Será mostrada uma lista de arquivos e pastas que estão dentro desta.

Existe uma pasta chamada "My Documents" onde criamos a pasta MYJAVAPROGRAMS. Iremos para este diretório. Para entrar em um diretório, digite o comando: cd [nome do diretório]. O comando "cd" significa "Change Directory". Neste caso, já que o nome de nosso diretório é My Documents, digite: cd My Documents e pressione Enter.

Introdução à Programação I 11

Figura 7: Lista de arquivos e pastas mostrados depois de executar o comando DIR.

Page 207: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Estamos dentro da pasta "My Documents", digite o comando "dir" novamente.

Execute os mesmos passos descritos para entrar na pasta MYJAVAPROGRAMS.

Um vez nesta pasta onde seus programas estão localizados, iremos compilar o programa. Certifique-se de assegurar de que o arquivo está localizado nessa pasta. Para isso, execute o comando dir e verifique que realmente o arquivo se encontra nesta pasta. Para compilar um programa em Java, digitamos o comando: javac [nomedoarquivo]. Deste modo, digitamos: javac Hello.java.

Introdução à Programação I 12

Figura 8: Dentro da pasta My Documents

Figura 9: O contéudo de My Documents

Figura 10: Dentro da pasta MYJAVAPROGRAMS

Page 208: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Durante o processo de compilação, o compilador javac cria um arquivo chamado [nomedoarquivo].class, neste caso, Hello.class, sendo o arquivo em linguagem de bytecode.

Passo 6: Para executar o programa, considerando que não existam erros durante a compilação, digite o comando: java [nomedoarquivo], para nosso exemplo, digite: java Hello

Veja que na tela que executamos o programa em Java é mostrada a mensagem, "Hello world!".

Figura 12: Saída do programa

Introdução à Programação I 13

Figura 11: Compilar um programa utilizando comando javac

Page 209: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Configurando o caminho (Path)Ao tentar executar o comando javac ou java, é mostrada a mensagem: 'javac' is not recognized as an internal or external command, operable program or batch file. Isto significa que ou ainda não foi instalado o Java em seu sistema, ou é necessário configurar o caminho de pesquisa (path) onde os aplicativos de Java estão instalados. Dessa forma, seu sistema saberá aonde procurá-los.

Se o Java foi instalado corretamente em seu sistema, configure a variável PATH para apontar para a localização dos comandos Java. Para fazer isto, digite: set PATH=C:\Program Files\Java\jdk1.5.0_01\bin. Isto fará com que seu sistema procure pelos comandos na pasta C:\Program Files\Java\jdk1.5.0_01\bin, que é o padrão de localização dos arquivos Java quando de sua instalação. Depois de fazer isto, agora é possível utilizar os comandos Java.

Figura 14: Configurando o caminho(path) e executando java

Introdução à Programação I 14

Figura 13: Sistema não reconhece o comando javac

Page 210: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Utilizando NetBeansComo já aprendemos a construção de programas de uma forma mais complicada, veremos como realizar todos estes processos descritos utilizando uma única aplicação. O NetBeans, é um Ambiente Integrado de Desenvolvimento (Integrated Development Environment ou IDE). Um IDE é um ambiente de programação, que possui um construtor de interface gráfica (GUI builder), um editor de código-fonte ou texto, um compilador e um depurador de erros.

Passo 1: Para executar NetBeans, selecione Start All Programs NetBeans 5.5 NetBeans IDE

Depois de aberto o NetBeans, será mostrada uma janela similar a mostrada na Figura 15.

Figura 15: IDE NetBeans

Passo 2: Vamos criar um projeto para o NetBeans. Selecione File New Project.

Introdução à Programação I 15

Page 211: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Depois disto, uma caixa de diálogo New Project será mostrada.

Na opção Categories selecione General e em Projects selecione Java Application pressione o botão NEXT.

Introdução à Programação I 16

Page 212: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Uma caixa de diálogo de nova aplicação Java (New Java Application) será mostrada. Na caixa de texto do nome do projeto (Project Name), digite "HelloApplication".

Figura 16: Altere Project Name

Altere a localização da aplicação (Application Location), pressionando no botão Browse... Siga os passos descritos na seção anterior para ir para a pasta MYJAVAPROGRAMS.

Por fim, na caixa de texto Create Main Class, digite Hello como a classe principal, e então clique no botão FINISH.

Introdução à Programação I 17

Page 213: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Passo 3: Antes de escrever o programa, vamos primeiro descrever a janela principal depois de criado o projeto. Como mostrado abaixo, NetBeans cria automaticamente o código básico para seu programa Java. Você pode então adicionar suas próprias declarações para o código gerado. No lado esquerdo da janela, temos uma lista de pastas e arquivos que o NetBeans gerou depois de criar o projeto. Isto é tudo que será encontrado na pasta MYJAVAPROGRAMS, que é onde está configurada a localização do projeto.

Modifique o código gerado pelo NetBeans ignorando as outras partes do programa. Insira a seguinte instrução: System.out.println("Hello world!");

Passo 4: Para compilar o programa, clique em Build Build Main Project. Ou, utilize o botão de atalho para compilar a classe, conforme mostrado na Figura 17.

Figura 17: Botão de atalho para compilação do código

Se não houver nenhum erro em seu programa, você verá uma mensagem de “build successful”

Introdução à Programação I 18

Page 214: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

na janela de saída.

Passo 5: Para executar o programa, clique em Run Run Main Project. Ou utilize o botão de atalho.

Figura 19: Botão de atalho para execução do programa

A saída do seu programa é mostrada na janela de saída(output window).

Figura 20: Saída de Hello.java

Introdução à Programação I 19

Figura 18: Janela de saída que está localizada abaixo da janela onde você escreve o código-fonte

Page 215: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação 1

Apêndice C

Respostas dos exercícios

Versão 1.0 - Jan/2007

Page 216: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

AutorFlorence Tiu Balagtas

EquipeJoyce AvestroFlorence BalagtasRommel FeriaReginald HutchersonRebecca OngJohn Paul PetinesSang ShinRaghavan SrinivasMatthew Thompson

Necessidades para os ExercíciosSistemas Operacionais SuportadosNetBeans IDE 5.5 para os seguintes sistemas operacionais: 3. Microsoft Windows XP Profissional SP2 ou superior4. Mac OS X 10.4.5 ou superior5. Red Hat Fedora Core 3 6. Solaris™ 10 Operating System (SPARC® e x86/x64 Platform Edition) NetBeans Enterprise Pack, poderá ser executado nas seguintes plataformas:1. Microsoft Windows 2000 Profissional SP42. Solaris™ 8 OS (SPARC e x86/x64 Platform Edition) e Solaris 9 OS (SPARC e

x86/x64 Platform Edition) 3. Várias outras distribuições Linux

Configuração Mínima de HardwareNota: IDE NetBeans com resolução de tela em 1024x768 pixel

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 500 MHz Intel Pentium III workstation ou equivalente

512 MB 850 MB

Linux 500 MHz Intel Pentium III workstation ou equivalente

512 MB 450 MB

Solaris OS (SPARC) UltraSPARC II 450 MHz 512 MB 450 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Série 1.8 GHz 512 MB 450 MB

Mac OS X PowerPC G4 512 MB 450 MB

Configuração Recomendada de Hardware

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 1 GB

Linux 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 850 MB

Solaris OS (SPARC) UltraSPARC IIIi 1 GHz 1 GB 850 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Series 1.8 GHz 1 GB 850 MB

Mac OS X PowerPC G5 1 GB 850 MB

Requerimentos de SoftwareNetBeans Enterprise Pack 5.5 executando sobre Java 2 Platform Standard Edition Development Kit 5.0 ou superior (JDK 5.0, versão 1.5.0_01 ou superior), contemplando a Java Runtime Environment, ferramentas de desenvolvimento para compilar, depurar, e executar aplicações escritas em linguagem Java. Sun Java System Application Server Platform Edition 9.1. Para Solaris, Windows, e Linux, os arquivos da JDK podem ser obtidos para

sua plataforma em http://java.sun.com/j2se/1.5.0/download.html2. Para Mac OS X, Java 2 Plataform Standard Edition (J2SE) 5.0 Release 4, pode ser

obtida diretamente da Apple's Developer Connection, no endereço: http://developer.apple.com/java (é necessário registrar o download da JDK).

Para mais informações: http://www.netbeans.org/community/releases/55/relnotes.html

Introdução à Programação I 2

Page 217: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Colaboradores que auxiliaram no processo de tradução e revisãoAlexandre MoriAlexis da Rocha SilvaAline Sabbatini da Silva AlvesAllan Wojcik da SilvaAndré Luiz MoreiraAndro Márcio Correa LouredoAntoniele de Assis LimaAntonio Jose R. Alves RamosAurélio Soares NetoBruno da Silva BonfimBruno dos Santos MirandaBruno Ferreira RodriguesCarlos Alberto Vitorino de AlmeidaCarlos Alexandre de SeneCarlos André Noronha de SousaCarlos Eduardo Veras NevesCleber Ferreira de SousaCleyton Artur Soares UraniCristiano Borges FerreiraCristiano de Siqueira PiresDerlon Vandri AliendresFabiano Eduardo de OliveiraFábio BombonatoFernando Antonio Mota TrintaFlávio Alves GomesFrancisco das ChagasFrancisco Marcio da SilvaGilson Moreno CostaGivailson de Souza NevesGustavo Henrique CastellanoHebert Julio Gonçalves de PaulaHeraldo Conceição Domingues

Hugo Leonardo Malheiros FerreiraIvan Nascimento FonsecaJacqueline Susann BarbosaJader de Carvalho BelarminoJoão Aurélio Telles da RochaJoão Paulo Cirino Silva de NovaisJoão Vianney Barrozo CostaJosé Augusto Martins NieviadonskiJosé Leonardo Borges de MeloJosé Ricardo CarneiroKleberth Bezerra G. dos SantosLafaiete de Sá GuimarãesLeandro Silva de MoraisLeonardo Leopoldo do NascimentoLeonardo Pereira dos SantosLeonardo Rangel de Melo FilardiLucas Mauricio Castro e MartinsLuciana Rocha de OliveiraLuís Carlos AndréLuís Octávio Jorge V. LimaLuiz Fernandes de Oliveira Junior Luiz Victor de Andrade LimaManoel Cotts de QueirozMarcello Sandi PinheiroMarcelo Ortolan PazzettoMarco Aurélio Martins BessaMarcos Vinicius de ToledoMaria Carolina Ferreira da SilvaMassimiliano GiroldiMauricio Azevedo GamarraMauricio da Silva MarinhoMauro Cardoso Mortoni

Mauro Regis de Sousa LimaNamor de Sá e SilvaNéres Chaves RebouçasNolyanne Peixoto Brasil VieiraPaulo Afonso CorrêaPaulo José Lemos CostaPaulo Oliveira Sampaio ReisPedro Antonio Pereira MirandaPedro Henrique Pereira de AndradeRenato Alves FélixRenato Barbosa da SilvaReyderson Magela dos ReisRicardo Ferreira RodriguesRicardo Ulrich BomfimRobson de Oliveira CunhaRodrigo Pereira MachadoRodrigo Rosa Miranda CorrêaRodrigo Vaez Ronie DotzlawRosely Moreira de JesusSeire ParejaSergio PomerancblumSilvio SzniferSuzana da Costa OliveiraTásio Vasconcelos da SilveiraThiago Magela Rodrigues DiasTiago Gimenez RibeiroVanderlei Carvalho Rodrigues PintoVanessa dos Santos AlmeidaVastí Mendes da Silva RochaWagner Eliezer Roncoletta

Auxiliadores especiais

Revisão Geral do texto para os seguintes Países:

• Brasil – Tiago Flach• Guiné Bissau – Alfredo Cá, Bunene Sisse e Buon Olossato Quebi – ONG Asas de Socorro

Coordenação do DFJUG

• Daniel deOliveira – JUGLeader responsável pelos acordos de parcerias• Luci Campos - Idealizadora do DFJUG responsável pelo apoio social• Fernando Anselmo - Coordenador responsável pelo processo de tradução e revisão,

disponibilização dos materiais e inserção de novos módulos• Regina Mariani - Coordenadora responsável pela parte jurídica• Rodrigo Nunes - Coordenador responsável pela parte multimídia• Sérgio Gomes Veloso - Coordenador responsável pelo ambiente JEDITM (Moodle)

Agradecimento Especial

John Paul Petines – Criador da Iniciativa JEDITM

Rommel Feria – Criador da Iniciativa JEDITM

Introdução à Programação I 3

Page 218: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 1 – Introdução à programação de computadores

Exercício 1. Escrevendo Algoritmos

1. Assar Pão

Pseudo código:

Preparar todos os ingredientesColocar os ingredientes na batedeiraEnquanto a mistura não estiver homogênea Bater ingredientesColocar a mistura em uma forma de pãoInserir a forma no fornoEnquanto pão não estiver pronto EsperarRetirar a forma do forno

Fluxograma:

Introdução à Programação I 4

Page 219: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Acessar o computador

Pseudo código:

Fazer power = botão ligar do computadorFazer in = status do usuário (inicialmente falso)Se power == off Pressione o botão ligarAguardar o procedimento inicialEnquanto in == falso Entrar com o nome do usuário Entrar com a senha Se senha e nome do usuário são corretos in = verdadeiro

Fluxograma:

Introdução à Programação I 5

Page 220: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Obter a média de três números

Pseudo código:

Fazer count = 0Fazer sum = 0Fazer average = 0Enquanto count < 3 Obter number Fazer sum = sum + number Fazer count = count + 1Fazer average = sum / 3Mostrar average

Fluxograma:

Exercício 2. Conversões Numéricas

1. 198010 para binário, hexadecimal e octal

Para Binário:1980/2 = 990 0990/2 = 495 0495/2 = 247 1

Introdução à Programação I 6

Page 221: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1980/2 = 990 0247/2 = 123 1123/2 = 61 161/2 = 30 130/2 = 15 015/2 = 7 17/2 = 3 13/2 = 1 11/2 = 0 1

Binário = 11110111100

Para Hexadecimal:0111, 1011, 1100,

7 B CHexadecimal = 7BC

Para Octal:011, 110, 111, 1003 6 7 4

Octal = 3674

2. 10010011012 para decimal, hexadecimal e octal

Para Decimal:1 * 1 = 10 * 2 = 01 * 4 = 41 * 8 = 80 * 16 = 00 * 32 = 01 * 64 = 640 * 128 = 00 * 256 = 01 * 512 = 512TOTAL = 589

Decimal = 589

Para Hexadecimal:0010, 0100, 11012 4 D

Hexadecimal = 24D

Para Octal:001, 001, 001, 1011 1 1 5

Octal = 1115

3. 768 para binário, hexadecimal e decimal

Para Binário:111, 110,7 6

Introdução à Programação I 7

Page 222: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Binário = 111110

Para Hexadecimal:0011, 1110,3 E

Hexadecimal = 3E

Para Decimal:6 * 1 = 67 * 8 = 56

TOTAL = 62Decimal = 62

4. 43F16 para binário, decimal e octal

Para Binário:4 3 F

0100, 0011, 1111Binário = 010000111111

Para Decimal:F * 1 = 15 3 * 16 = 484 * 256 = 1024TOTAL = 1087

Decimal = 1087

Para Octal:010, 000 , 111 , 1112 0 7 7

Octal = 2077

Introdução à Programação I 8

Page 223: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 2 – Histórico de Java

Não houve exercícios nesta lição

Introdução à Programação I 9

Page 224: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 3 – Primeiros passos no ambiente de programação

Exercício 1. Melhorando o Hello World

/** * Esta classe mostra "Welcome to Java Programming [SeuNome]!!!" */public class HelloWorld { public static void main(String[] args){ System.out.println("Welcome to Java Programming [YourName]!!!"); }}

Exercício 2. A árvore

/** * O programa mostra o poema "The Tree" */public class TheTree { public static void main(String[] args){ System.out.println("I think I shall never see,"); System.out.println("[Eu acho que nunca verei,]"); System.out.println("a poem as lovely as a tree."); System.out.println("[um poema tão adorável quanto uma árvore.]"); System.out.println("A tree whose hungry mouth is pressed"); System.out.println("[Uma árvore cuja boca faminta é pressionada]"); System.out.println("Against the Earth's flowing breast."); System.out.println("[Contra a Terra fluindo em seu seio docemente.]"); }}

Introdução à Programação I 10

Page 225: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 4 – Fundamentos da programação

Exercício 1. Declarar e mostrar variáveis/** * Um programa que declara diferentes variáveis * e mostra os valores dessas variáveis */public class VariableSample { public static void main(String[] args){ // Declarar variável number do tipo integer // com valor inicial igual a 10 int number = 10;

// Declarar variável letter do tipo character // com valor inicial igual a 'a' char letter = 'a';

// Declara variável result do tipo boolean // com valor inicial igual a true boolean result = true;

// Declarar variável str do tipo String // com valor inicial igual a "hello" String str = "hello";

// Mostrar os valores das variáveis System.out.println("Number = " + number); System.out.println("letter = " + letter); System.out.println("result = " + result); System.out.println("str = " + str); }}

Exercício 2. Obter a média de três números/** * Um programa que calcula a média de três * números: 10,20, e 45 * e imprime o resultado na tela */public class AverageNumber { public static void main(String[] args){ // Declarar três números int num1 = 10; int num2 = 20; int num3 = 45; // Obter a média dos números e guardar na variável ave int ave = (num1+num2+num3)/3; // Mostrar System.out.println("number 1 = " + num1); System.out.println("number 2 = " + num2); System.out.println("number 3 = " + num3); System.out.println("Average is = " + ave); }}

Exercício 3. Exibir o maior valor/** * Um programa que imprime o número com * maior valor dados três números */public class GreatestValue { public static void main(String[] args){

Introdução à Programação I 11

Page 226: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

// Declarar os números int num1 = 10; int num2 = 23; int num3 = 5; int max = 0; // Determinar qual é o maior max = (num1>num2)?num1:num2; max = (max>num3)?max:num3; // Mostrar System.out.println("número 1 = " + num1); System.out.println("número 2 = " + num2); System.out.println("número 3 = " + num3); System.out.println("O maior número é = " + max); }}

Exercício 4. Precedência de Operadores1. (((a/b)^c)^((d-e+f-(g*h))+i))2. ((((((3*10)*2)/15)-2+4)^2)^2)3. ((r^((((s*t)/u)-v)+w))^(x-(y++)))

Introdução à Programação I 12

Page 227: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 5 – Capturando entrada de dados através do teclado

Exercício 1. As 3 palavras (versão Console - BufferedReader)import java.io.*;/** * Um programa que solicita três palavras ao usuário * e então as imprime na tela como uma frase */public class LastThreeWords { public static void main(String[] args){ // Declarar a variável reader como BufferedReader reader = new BufferedReader( new InputStreamReader(System.in)); // Declarar variáveis String para as 3 palavras String firstWord = ""; String secondWord = ""; String thirdWord = ""; try{ System.out.print("Palavra 1: "); // Obter a primeira palavra firstWord = reader.readLine(); // Obter a segunda palavra System.out.print("Palavra 2: "); secondWord = reader.readLine(); // Obter a terceira palavra System.out.print("Palavra 3: "); thirdWord = reader.readLine(); } catch(IOException e) { System.out.println("Erro na obtenção dos dados"); } // Mostrar a frase System.out.println(firstWord + " " + secondWord + " " + thirdWord);

}}

Exercício 1. As 3 palavras (versão Console - Scanner)

import java.util.Scanner;

/** * Um programa que solicita três palavras ao usuário * e então as imprime na tela como uma frase */public class LastThreeWords { public static void main(String[] args){ // Declarar a variável Scanner Scanner sc = new Scanner(System.in)); // Declarar variáveis String para as 3 palavras String firstWord = ""; String secondWord = ""; String thirdWord = ""; System.out.print("Palavra 1: "); // Obter a primeira palavra firstWord = sc.nextLine(); // Obter a segunda palavra System.out.print("Palavra 2: "); secondWord = sc.nextLine(); // Obter a terceira palavra System.out.print("Palavra 3: "); thirdWord = sc.nextLine(); // Mostrar a frase System.out.println(

Introdução à Programação I 13

Page 228: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

firstWord + " " + secondWord + " " + thirdWord); }

}

Exercício 2. Últimas 3 palavras (versão Gráfica)import javax.swing.JOptionPane;/** * Um programa que solicita do usuário três palavras usando * o JOptionPane e mostra na tela essas três palavras como * uma frase */public class LastThreeWords { public static void main(String[] args){ // Obter a primeira palavra do usuário String firstWord = JOptionPane.showInputDialog("Palavra 1"); // Obter a segunda palavra do usuário String secondWord = JOptionPane.showInputDialog("Palavra 2"); // Obter a terceira palavra do usuário String thirdWord = JOptionPane.showInputDialog("Palavra 3"); // mostra a mensagem JOptionPane.showMessageDialog(null, firstWord + " " + secondWord + " " + thirdWord); }}

Introdução à Programação I 14

Page 229: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 6 – Estruturas de controle

Exercício 1. Notas

1. Utilizando BufferedReader:

import java.io.*;/** * Obtém três entradas numéricas do usuário * e mostra a média na tela */public class Grades { public static void main(String[] args) { // Declarar a variável reader como entrada BufferedReader reader = new BufferedReader (new InputStreamReader(System.in)); int firstGrade = 0; int secondGrade = 0; int thirdGrade = 0; double average = 0; try { System.out.print("Primeira nota: "); firstGrade = Integer.parseInt(reader.readLine()); System.out.print("Segunda nota: "); secondGrade = Integer.parseInt(reader.readLine()); System.out.print("Terceira nota: "); thirdGrade = Integer.parseInt(reader.readLine()); } catch(Exception e) { System.out.println("Entrada inválida"); System.exit(0); } // Calcular a média average = (firstGrade+secondGrade+thirdGrade)/3; // Mostrar a média dos três exames System.out.print("Média: "+average); if (average >= 60) System.out.print(" :-)"); else System.out.print(" :-("); }}

2. Utilizando JOptionPane:

import javax.swing.JOptionPane;/** * Obtém três entradas numéricas do usuário * e mostra a média na tela */public class Grades { public static void main(String[] args) { double firstGrade = 0; double secondGrade = 0; double thirdGrade = 0; double average = 0; try { firstGrade = Double.parseDouble(JOptionPane.showInputDialog ("Primeira nota")); secondGrade = Double.parseDouble(JOptionPane.showInputDialog ("Segunda nota")); thirdGrade = Double.parseDouble(JOptionPane.showInputDialog ("Terceira nota")); } catch( Exception e) { JOptionPane.showMessageDialog(null, "Entrada inválida"); System.exit(0);

Introdução à Programação I 15

Page 230: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} // Calcular a média average = (firstGrade+secondGrade+thirdGrade)/3; if (average>=60) JOptionPane.showMessageDialog(null,"Média :"+average+" :-)"); else JOptionPane.showMessageDialog(null,"Média :"+average+" :-("); }}

Exercício 2. Números por Extenso

Classe Básica

import javax.swing.JOptionPane;/** * Transforma uma entrada numérica entre 1-10 para palavras * utilizando if-else */public class NumWords { public static void main(String[] args) { String msg = ""; int input = 0; // Obter a entrada input = Integer.parseInt(JOptionPane.showInputDialog("Digite número")); // ------------------------------------ // Substitua aqui as declarações // ------------------------------------ // Mostrar o número em palavras se dentro da faixa JOptionPane.showMessageDialog(null,msg); }}

1. Declaração if-else:

// Declaração if para atribuir em msg o extenso do número digitado if (input == 1) msg = "um"; else if(input == 2) msg = "dois"; else if(input == 3) msg = "três"; else if(input == 4) msg = "quatro"; else if(input == 5) msg = "cinco"; else if(input == 6) msg = "seis"; else if(input == 7) msg = "sete"; else if(input == 8) msg = "oito"; else if(input == 9) msg = "nove"; else if(input == 10) msg = "dez"; else msg = "número inválido";

2. Declaração switch:

// Declaração switch para atribuir em msg o extenso do número digitado switch (input) { case 1: msg = "um"; break; case 2: msg = "dois"; break; case 3: msg = "três"; break; case 4: msg = "quatro"; break; case 5: msg = "cinco"; break; case 6: msg = "seis"; break; case 7: msg = "sete"; break; case 8: msg = "oito"; break; case 9: msg = "nove"; break; case 10: msg = "dez"; break; default: msg = "número inválido"; }

Introdução à Programação I 16

Page 231: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Exercício 3. Cem Vezes

Classe Básica

import java.io.*;/** * Um programa que imprime 100 vezes um número digitado */public class HundredNames{ public static void main(String[] args){ BufferedReader reader = new BufferedReader( new InputStreamReader(System.in)); String name = ""; // Obter o nome do usuário try { System.out.print("Digite o nome: "); name = reader.readLine(); } catch(Exception e) { System.out.println("entrada inválida"); System.exit(0); } // ------------------------------------ // Substitua aqui as declarações // ------------------------------------ }}

1. Declaração while:

// Declaração while para exibir 100 vezes o nome digitado int counter = 0; while (counter < 100) { System.out.println(name); counter++; }

2. Declaração do-while:

// Declaração do-while para exibir 100 vezes o nome digitado int counter = 0; do { System.out.println(name); counter++; } while(counter < 100);

3. Declaração for:

// Declaração for para exibir 100 vezes o nome digitado for (int counter = 0; counter < 100; counter++) { System.out.println(name); }

Exercício 4. Potências

Classe Básica

import javax.swing.JOptionPane;/** * Calcula a potência de um número dados a base e expoente. * O expoente está limitado a números positivos. */public class Powers { public static void main(String[] args){ int base = 0; int exp = 0; int power = 1;

Introdução à Programação I 17

Page 232: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

// Obter entrada do usuário para base e expoente base = Integer.parseInt(JOptionPane.showInputDialog("Base")); exp = Integer.parseInt(JOptionPane.showInputDialog("Expoente")); // Limitar variável exp a somente número positivos e maiores que 0 if (exp <= 0) { JOptionPane.showMessageDialog(null, "Somente números positivos e maiores que 0, por favor"); System.exit(0); } // ------------------------------------ // Substitua aqui as declarações // ------------------------------------ // Mostrar o resultado JOptionPane.showMessageDialog(null, base + " elevado a " + exp + " é igual a " + power);

}}

1. Declaração while:

// Declaração while para calcular a potência int counter = 0; while (counter++ < exp) power = power*base;

2. Declaração do-while:

// Declaração do-while para calcular a potência int counter = 0; do power = power*base; while(++counter < exp);

3. Declaração for:

// Declaração for para calcular a potência for (int counter = 0; counter < exp; counter++) power = power*base;

Introdução à Programação I 18

Page 233: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 7 – Array em Java

Exercício 1. Dias da Semana/** * Utilizar um array de string para salvar os dias da semana * e imprime na tela. */public class DaysOfTheWeek { public static void main(String[] args){ // Declarar o array de String dos dias da semana String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; // ------------------------------------ // Substitua aqui as declarações // ------------------------------------ }}

1. Declaração while:

// Declaração while para mostrar os dias da semana int counter = 0; while (counter++ < days.length) System.out.println(days[counter]);

2. Declaração do-while:

// Declaração do-while para mostrar os dias da semana int counter = 0; do System.out.println(days[counter++]); while(counter < days.length);

3. Declaração for:

// Declaração for para mostrar os dias da semana for (int counter = 0; counter < days.length; counter++) System.out.println(days[counter]);

Exercício 2. Maior númeroimport javax.swing.JOptionPane;/** * Um programa que utiliza JOptionPane para obter dez números do usuário * e exibir o maior número. */public class GreatestNumber { public static void main(String[] args){ int[] num = new int[10]; int counter; int max = 0; // Declaração for para obter 10 números do usuário for (counter = 0; counter < 10; counter++) { num[counter] = Integer.parseInt( JOptionPane.showInputDialog("Digite o número "+(counter+1))); // Obter o número máximo if ((counter == 0)||(num[counter] > max)) max = num[counter]; } // Mostrar o maior número JOptionPane.showMessageDialog(null, "O número com o maior valor é " + max); }}

Introdução à Programação I 19

Page 234: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Exercício 3. Entradas de Agenda Telefônicaimport javax.swing.JOptionPane;/** * Um programa que mostra os dados de um array multidimensional. */public class GreatestNumber { public static void main(String[] args){ String entry [][] = { {"Florence", "735-1234", "Manila"}, {"Joyce", "983-3333", "Quezon City"}, {"Becca", "456-3322", "Manila"}}; // Declaração for para percorrer nas linhas for (int line = 0; line < entry.length; line++) { System.out.println("Name : " + entry[line][0]); System.out.println("Tel. # : " + entry[line][1]); System.out.println("Address: " + entry[line][2]); System.out.println(); } }}

Introdução à Programação I 20

Page 235: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 8 – Argumentos de linha de comando

Exercício 1. Argumentos de Exibição/** * Um programa que imprime a string da linha de comando, se * houver. */public class CommandLineSample { public static void main(String[] args){ // Declaração for para exibir os argumentos da linha de comando for (int counter=0; counter < args.length; counter++) System.out.println(args[counter]); }}

Exercício 2. Operações Aritméticas/** * */public class ArithmeticOperation { public static void main(String[] args){ // Obter os argumentos em int int num1 = Integer.parseInt(args[0]); int num2 = Integer.parseInt(args[1]); // Mostrando valores System.out.println("sum = " + (num1 + num2)); System.out.println("subtraction = " + (num1 - num2)); System.out.println("multiplication = " + (num1 * num2)); System.out.println("division = " + (num1 / num2)); }}

Introdução à Programação I 21

Page 236: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 9 – Trabalhando com bibliotecas de classes

Exercício 1. Argumentos de ExibiçãoNão existe uma única resposta.

Exercício 2. Java Scavenger Hunt

Nota: Esses são apenas alguns exemplos de métodos na API Java que é possível utilizar. Verifique a API Java para mais respostas.

public class Homework1 { public static void main(String []args) { // 1. endsWith String str = "Hello"; System.out.println( str.endsWith( "slo" ) ); //2. forDigit System.out.println( Character.forDigit(13, 16) ); //3. floor System.out.println( Math.floor(3.14)); //4. isDigit System.out.println( "0=" + Character.isDigit('0')); System.out.println( "A=" +Character.isDigit('A'));

//5. exit System.exit(1); System.out.println("if this is executed, exit was not called"); }}

Declaração de Classe e Método:

1. Classe: StringMétodo: public boolean endsWith(String suffix)

2. Classe: CharacterMétodo: public static char forDigit(int digit, int radix)

3. Classe: MathMétodo: public static double floor(double a)

4. Classe: MathMétodo: public static boolean isDigit(char ch)

5. Classe: SystemMétodo: public static void exit(int status)

Introdução à Programação I 22

Page 237: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 10 – Criando nossas classes

Exercício 1. Registro de agenda/** * Uma classe de registro de agenda que armazena o nome da * pessoa, endereço, número de telefone e endereço de email */ public class AddressBookEntry { private String name; private String address; private String tel; private String email; /** * construtor padrão */ public AddressBookEntry(){ this.setName(""); this.setAddress(""); this.setTel(""); this.setEmail(""); } /** * Cria um objeto AddressBookEntry com o nome, endereço, * número de telefone e endereço de email fornecidos. */ public AddressBookEntry(String name, String address, String tel, String email) { this.setName(name); this.setAddress(address); this.setTel(tel); this.setEmail(email); } /** * retorna a variável name */ public String getName(){ return name; } /** * altera a variável name */ public void setName(String name){ this.name = name; } /** * retorna a variável address */ public String getAddress(){ return address; } /** * altera a variável address */ public void setAddress(String address){ this.address = address; } /** * retorna a variável tel */ public String getTel(){ return tel; } /** * altera a variável tel

Introdução à Programação I 23

Page 238: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

*/ public void setTel(String tel){ this.tel = tel; } /** * retorna a variável email */ public String getEmail(){ return email; } /** * altera a variável email */ public void setEmail(String email){ this.email = email; }}

Exercício 2. Agendaimport java.io.*;/** * Cria uma agenda com 100 registros AddressBookEntries */public class AddressBook { // Índice do último registro private int top = 0; // Número constante que indica o número máximo de registros da agenda private static final int MAXENTRIES = 100; // Array de registros da agenda private AddressBookEntry[] list; /** * Método principal */ public static void main(String[] args) { BufferedReader keyIn = new BufferedReader (new InputStreamReader(System.in)); AddressBook addBook = new AddressBook(); String act = ""; while(true) { // Mostrar as opções System.out.println("\n[A] Adicionar registro"); System.out.println("[E] Excluir registro"); System.out.println("[V] Visualizar registros"); System.out.println("[U] atUalizar registro"); System.out.println("[S] Sair do projeto"); System.out.print("Digite a ação desejada: "); try { // Obter a escolha act = keyIn.readLine(); } catch(Exception e) { System.out.println("Erro"); } // Verificar a ação apropiada para a escolha do usuário switch (act.charAt(0)) { case 'A': case 'a': addBook.addEntry(); break; case 'E': case 'e': addBook.delEntry(); break; case 'V': case 'v': addBook.viewEntries(); break; case 'U': case 'u': addBook.updateEntry(); break; case 'S': case 's': System.exit(0); default: System.out.println("Comando Desconhecido"); } } } /**

Introdução à Programação I 24

Page 239: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

* cria a agenda */ public AddressBook(){ list = new AddressBookEntry[MAXENTRIES]; } /** * método para adicionar um registro AdressBookEntry * na agenda */ public void addEntry(){ BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in)); String name = ""; String add = ""; String tel = ""; String email = ""; if (top == MAXENTRIES) { System.out.println("Agenda está cheia"); return; } //Pede ao usuário a digitação dos dados try { System.out.print("Nome: "); name = keyIn.readLine(); System.out.print("Endereço: "); add = keyIn.readLine(); System.out.print("Telefone: "); tel = keyIn.readLine(); System.out.print("Email: "); email = keyIn.readLine(); } catch(Exception e) { System.out.println(e); System.exit(0); } AddressBookEntry entry = new AddressBookEntry(name, add, tel, email); list[top] = entry; top++; } /** * método que deleta um registro AddressBookEntry * da agenda com o índice */ public void delEntry(){ BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in)); int index = 0; // Verificar se a agenda está vazia if (top == 0) { System.out.println("Agenda está vazia"); return; } // Solicitar o registro a ser deletado try { // Exibir os registros existentes na agenda viewEntries(); System.out.print("\nDigite número do registro: "); index = Integer.parseInt(keyIn.readLine())-1; }catch(Exception e){ } //verifica se o índice está dentro do limites if (index < 0 || index >= top) { System.out.println("Índice fora dos limites"); return; } else { for (int i=index; i<top; i++) list[i] = list[i+1]; list[top] = null; top--;

Introdução à Programação I 25

Page 240: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} } /** * método que imprime todos os registros da agenda */ public void viewEntries(){ for (int index = 0; index < top; index++) { System.out.println((index+1)+" Nome:"+list[index].getName()); System.out.println("Endereço:"+list[index].getAddress()); System.out.println("Telefone:"+list[index].getTel()); System.out.println("Email:"+list[index].getEmail()); } } /** * método que atualiza um registro */ public void updateEntry(){ BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in)); int index = 0; String name = ""; String add = ""; String tel = ""; String email = ""; // Solicitar a digitação dos dados try { System.out.print("Número do registro: "); index =Integer.parseInt(keyIn.readLine())-1; System.out.print("Nome: "); name = keyIn.readLine(); System.out.print("Endereço: "); add = keyIn.readLine(); System.out.print("Telefone: "); tel = keyIn.readLine(); System.out.print("Email: "); email = keyIn.readLine(); } catch(Exception e) { System.out.println(e); System.exit(0); } // Atualizar o registro AddressBookEntry entry = new AddressBookEntry(name, add, tel, email); list[index] = entry; }}

Introdução à Programação I 26

Page 241: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 11 – Herança, polimorfismo e interfaces

Exercício 1. Estendendo StudentRecord

/** * Um objeto que armazena os dados de um estudante */public class StudentRecord { private String name; private String address; private int age; private double mathGrade; private double englishGrade; private double scienceGrade; protected static int studentCount; /** * Retorna o nome do estudante */ public String getName() { return name; } /** * Altera o nome do estudante */ public void setName(String temp) { name = temp; } /** * Retorna o endereço do estudante */ public String getAddress() { return address; } /** * Altera o endereço do estudante */ public void setAddress(String temp) { address = temp; } /** * Retorna a idade do estudante */ public int getAge() { return age; } /** * Altera a idade do estudante */ public void setAge(int temp) { age = temp; } /** * Retorna a nota de inglês do estudante */ public double getEnglishGrade() { return englishGrade; } /** * Altera a nota de inglês do estudante */ public void setEnglishGrade(double temp) { englishGrade = temp;

Introdução à Programação I 27

Page 242: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} /** * Retorna a nota de matemática do estudante */ public double getMathGrade() { return mathGrade; } /** * Altera a nota de matemática do estudante */ public void setMathGrade(double temp) { mathGrade = temp; } /** * Retorna a nota de ciências do estudante */ public double getScienceGrade() { return scienceGrade; } /** * Altera a nota de ciências do estudante */ public void setScienceGrade(double temp) { scienceGrade = temp; } /** * Calcula a média das notas de inglês, matemática e * ciências do estudante */ public double getAverage() { return (mathGrade+englishGrade+scienceGrade)/3; } /** * Retorna o número de instâncias de StudentRecords */ public static int getStudentCount() { return studentCount; }}

/** * Um registro de estudante de um estudante de Ciência de * Computação */public class ComputerScienceStudentRecord extends StudentRecord { private String studentNumber; private double comSciGrade; /** * Retorna a matrícula do estudante */ public String getStudentNumber() { return studentNumber; } /** * Altera a matrícula do estudante */ public void setStudentNumber(String temp) { studentNumber = temp; } /** * Retorna a nota de ciência de computação do estudante */ public double getComSciGrade() { return comSciGrade; }

Introdução à Programação I 28

Page 243: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

/** * Altera a nota de ciência de computação do estudante */ public void setComSciGrade(double temp) { comSciGrade = temp; }}

Exercício 2. Classes Abstratas/** * Definição da classe abstrata forma */public abstract class Shape { /** * retorna a área de determinada forma */ public abstract double getArea(); /** * retorna o nome da forma */ public abstract String getName();}

/** * Definição de Classe para objeto círculo */public class Circle extends Shape { private static final double pi = 3.1416; private double radius = 0; /** * Construtor */ public Circle(double r) { setRadius(r); } /** * retorna area */ public double getArea() { return pi*radius*radius; } /** * retorna o nome da forma */ public String getName() { return "circle"; } /** * Atribui raio */ public void setRadius(double r) { radius = r; } /** * retorna raio */ public double getRadius() { return radius; }}/** * Definição de Classe para objeto quadrado */public class Square extends Shape {

Introdução à Programação I 29

Page 244: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

private double side = 0; /** * Construtor */ public Square(double s) { setSide( s ); } /** * retorna area */ public double getArea() { return side*side; } /** * retorna o nome da forma */ public String getName() { return "square"; } /** * atribui tamanho do lado */ public void setSide(double s) { side = s; } /** * retorna o tamanho de um lado */ public double getSide(){ return side; }}

Introdução à Programação I 30

Page 245: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Lição 12 – Tratamento básico de exceções

Exercício 1. Capturando exceções 1public class TestExceptions { public static void main(String[] args) { try { for (int i=0; true; i++) System.out.println("args["+i+"]="+args[i]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Exception caught: " + e); } System.out.println("Quiting..."); }}

Exercício 2. Capturando exceções 2Não existe uma única resposta.

Introdução à Programação I 31

Page 246: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 1Introdução à Programação 1

Apêndice D

Testes de programação

Versão 1.0 - Jan/2007

Page 247: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Neste apêndice, veremos apenas idéias de projetos para que o estudante possa se aprofundar cada vez mais com Java. Não existem soluções únicas para cada projeto e cabe ao estudante implementá-lo da maneira como melhor lhe agradar.

Nota:

VOCÊ tem alguma idéia interessante para um projeto? Envie-a para o email do Fernando Anselmo ([email protected]) e ajude a iniciativa JEDI a crescer. No assunto do email escreva: "Projeto para JEDI" e no corpo do email:

Título do Projeto:Descrição do Projeto:Nome completo do autor:

Estes projetos devem ser idéias originais e inéditas. Colabore.

Introdução à Programação I 4

Page 248: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Agenda Telefônica

Escrever um programa que cria uma agenda telefônica na qual seja possível acrescentar, excluir, visualizar e pesquisar os registros. O usuário deve ter a possibilidade de visualizar todos registros por ordem alfabética ou por ordem crescente de números de telefone. Na pesquisa por registros, o usuário deve ter a opção de pesquisar por nome ou por número de telefone. Na pesquisa pelo nome, o usuário deve ter uma opção em que possa selecionar se a pesquisa será efetuada com base no primeiro ou último nome.

MENU PRINCIPAL 1 – Adicionar registro na agenda telefônica 2 – Excluir registro da agenda telefônica 3 – Visualizar todos os registros a – ordem alfabética b – ordem numérica crescente de número de telefone 4 – Pesquisa de registros a – por nome 1 – pelo primeiro nome 2 – pelo último nome b – por número de telefone 5 – Sair

Esse é um exemplo da aplicação rodando:

Adicionar registro na agenda telefônica Digite o Nome: Digite o número do Telefone: (* Se o registro já existir, avise o operador da existência do registro)

Visualizar todos os registros Mostra todos os registros em ordem alfabética Mostra todos os registros em ordem crescente de número de telefone

Pesquisa registros Pesquisa agenda telefônica por nome Pesquisa agenda telefônica pelo primeiro nome Pesquisa agenda telefônica pelo último nome Pesquisa agenda telefônica por número do telefone

Sair Fechar agenda telefônica

Introdução à Programação I 5

Page 249: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Caça-Minas

Este jogo é uma versão simplificada do popular jogo de computador Caça-minas (minesweeper). Inicialmente, é questionado se o usuário quer jogar numa grade de 5x5 ou numa grade de 10x10. Você tem 2 arrays bidimensionais que contém informações sobre a grade selecionada. Um registro desse array pode conter 0 ou 1. O valor 1 significa que existe uma bomba nessa localização e o valor 0 se não existir.

Por exemplo, dado o seguinte array:

int bombList5by5[][]={{0, 0, 1, 0, 0}, {0, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 0, 0, 1, 1}, {0, 1, 1, 0, 0}};

Dada a lista de bombas, temos 6 bombas nessa lista. As bombas estão localizadas nas células (linha,coluna), (0,2), (2,1), (3,3), (3,4), (4,1) e (4,2).

Se o usuário escolhe uma célula que contenha uma bomba, o jogo acaba e todas as bombas são mostradas. Se o usuário escolhe uma célula que não contenha uma bomba, um número é mostrado naquela posição indicando a quantidade de células vizinhas que contém bombas. O jogo deverá terminar quando todas as células que não contenham bombas tiverem sido marcadas (jogador vence) ou quando o usuário seleciona uma bomba (jogador perde).

Segue um exemplo de tela do jogo quando selecionada uma grade 5x5 que tenha o mesmo conteúdo do array bombList5by5 acima.

Benvindo ao Caça-Minas!Escolha o tamanho da grade(Digite 1 para 5x5, Digite 2 para 10x10): 1[ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ]Digite linha e coluna da célula que você quer abrir[linha coluna]: 1 1[ ] [ ] [ ] [ ] [ ][ ] [2] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ]Digite linha e coluna da célula que você quer abrir[linha coluna]: 3 2[ ] [ ] [ ] [ ] [ ][ ] [2] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [4] [ ] [ ][ ] [ ] [ ] [ ] [ ]Digite linha e coluna da célula que você quer abrir[linha coluna]: 0 2[ ] [ ] [X] [ ] [ ][ ] [2] [ ] [ ] [ ][ ] [ ] [ ] [ ] [ ][ ] [ ] [4] [ ] [ ][ ] [ ] [ ] [ ] [ ]Ooppps! Você pisou numa bomba. Sinto muito, o jogo acabou e você perdeu!

Introdução à Programação I 6

Page 250: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Conversão Numérica

Criar uma calculadora científica que converta os números digitados para as quatro representações numéricas: decimal, binário, octal e hexadecimal. O projeto deve gerar o seguinte menu na tela.

MENU PRINCIPAL: Por favor, selecione o tipo de conversão: 1 – Binário para Decimal 2 – Decimal para Octal 3 – Octal para Hexadecimal 4 – Hexadecimal para Binário 5 – Sair

A seguinte tela deve ser mostrada quando uma das opções do menu for escolhida.

Seleção 1: Digite um número binário: 11000 11000 base 2 = 24 base 10 (volta para o menu principal)

Seleção 2: Digite um número Decimal: 24 24 base 10 = 30 base 8 (volta para o menu principal)

Seleção 3: Digite um número Octal: 30 30 base 8 = 18 base 16 (volta para o menu principal)

Seleção 4: Digite um número Hexadecimal: 18 18 base 16 = 11000 base 2

Seleção 1: Digite um número Binário: 110A Número binário inválido! Digite um número binário: 1 1 base 2 = 1 base 10 (volta para o menu principal)

Usuário selecionou 5 Tchau! É possível ser mais criativo com a interface do usuário, contanto que o programa gere devidamente as conversões numéricas.

Introdução à Programação I 7

Page 251: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 1Revisão dos Conceitos Básicos em Java

Versão 1.01 - Jan/2008

Page 252: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

AutorRebecca Ong

EquipeJoyce AvestroFlorence BalagtasRommel FeriaRebecca OngJohn Paul PetinesSun MicrosystemsSun Philippines

Necessidades para os ExercíciosSistemas Operacionais SuportadosNetBeans IDE 5.5 para os seguintes sistemas operacionais:

• Microsoft Windows XP Profissional SP2 ou superior• Mac OS X 10.4.5 ou superior• Red Hat Fedora Core 3 • Solaris™ 10 Operating System (SPARC® e x86/x64 Platform Edition)

NetBeans Enterprise Pack, poderá ser executado nas seguintes plataformas:• Microsoft Windows 2000 Profissional SP4• Solaris™ 8 OS (SPARC e x86/x64 Platform Edition) e Solaris 9 OS (SPARC e

x86/x64 Platform Edition) • Várias outras distribuições Linux

Configuração Mínima de HardwareNota: IDE NetBeans com resolução de tela em 1024x768 pixel

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 500 MHz Intel Pentium III workstation ou equivalente

512 MB 850 MB

Linux 500 MHz Intel Pentium III workstation ou equivalente

512 MB 450 MB

Solaris OS (SPARC) UltraSPARC II 450 MHz 512 MB 450 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Série 1.8 GHz 512 MB 450 MB

Mac OS X PowerPC G4 512 MB 450 MB

Configuração Recomendada de Hardware

Sistema Operacional Processador Memória HD Livre

Microsoft Windows 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 1 GB

Linux 1.4 GHz Intel Pentium III workstation ou equivalente

1 GB 850 MB

Solaris OS (SPARC) UltraSPARC IIIi 1 GHz 1 GB 850 MB

Solaris OS (x86/x64 Platform Edition)

AMD Opteron 100 Series 1.8 GHz 1 GB 850 MB

Mac OS X PowerPC G5 1 GB 850 MB

Requerimentos de SoftwareNetBeans Enterprise Pack 5.5 executando sobre Java 2 Platform Standard Edition Development Kit 5.0 ou superior (JDK 5.0, versão 1.5.0_01 ou superior), contemplando a Java Runtime Environment, ferramentas de desenvolvimento para compilar, depurar, e executar aplicações escritas em linguagem Java. Sun Java System Application Server Platform Edition 9.

• Para Solaris, Windows, e Linux, os arquivos da JDK podem ser obtidos para sua plataforma em http://java.sun.com/j2se/1.5.0/download.html

• Para Mac OS X, Java 2 Plataform Standard Edition (J2SE) 5.0 Release 4, pode ser obtida diretamente da Apple's Developer Connection, no endereço: http://developer.apple.com/java (é necessário registrar o download da JDK).

Para mais informações: http://www.netbeans.org/community/releases/55/relnotes.html

Introdução à Programação II 2

Page 253: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Colaboradores que auxiliaram no processo de tradução e revisãoAlexandre MoriAlexis da Rocha SilvaAline Sabbatini da Silva AlvesAllan Wojcik da SilvaAndré Luiz MoreiraAndro Márcio Correa LouredoAntoniele de Assis LimaAntonio Jose R. Alves RamosAurélio Soares NetoBruno da Silva BonfimBruno dos Santos MirandaBruno Ferreira RodriguesCarlos Alberto Vitorino de AlmeidaCarlos Alexandre de SeneCarlos André Noronha de SousaCarlos Eduardo Veras NevesCleber Ferreira de SousaCleyton Artur Soares UraniCristiano Borges FerreiraCristiano de Siqueira PiresDerlon Vandri AliendresFabiano Eduardo de OliveiraFábio BombonatoFernando Antonio Mota TrintaFlávio Alves GomesFrancisco das ChagasFrancisco Marcio da SilvaGilson Moreno CostaGivailson de Souza NevesGustavo Henrique CastellanoHebert Julio Gonçalves de PaulaHeraldo Conceição Domingues

Hugo Leonardo Malheiros FerreiraIvan Nascimento FonsecaJacqueline Susann BarbosaJader de Carvalho BelarminoJoão Aurélio Telles da RochaJoão Paulo Cirino Silva de NovaisJoão Vianney Barrozo CostaJosé Augusto Martins NieviadonskiJosé Leonardo Borges de MeloJosé Ricardo CarneiroKleberth Bezerra G. dos SantosLafaiete de Sá GuimarãesLeandro Silva de MoraisLeonardo Leopoldo do NascimentoLeonardo Pereira dos SantosLeonardo Rangel de Melo FilardiLucas Mauricio Castro e MartinsLuciana Rocha de OliveiraLuís Carlos AndréLuís Octávio Jorge V. LimaLuiz Fernandes de Oliveira Junior Luiz Victor de Andrade LimaManoel Cotts de QueirozMarcello Sandi PinheiroMarcelo Ortolan PazzettoMarco Aurélio Martins BessaMarcos Vinicius de ToledoMaria Carolina Ferreira da SilvaMassimiliano GiroldiMauricio Azevedo GamarraMauricio da Silva MarinhoMauro Cardoso Mortoni

Mauro Regis de Sousa LimaNamor de Sá e SilvaNéres Chaves RebouçasNolyanne Peixoto Brasil VieiraPaulo Afonso CorrêaPaulo José Lemos CostaPaulo Oliveira Sampaio ReisPedro Antonio Pereira MirandaPedro Henrique Pereira de AndradeRenato Alves FélixRenato Barbosa da SilvaReyderson Magela dos ReisRicardo Ferreira RodriguesRicardo Ulrich BomfimRobson de Oliveira CunhaRodrigo Pereira MachadoRodrigo Rosa Miranda CorrêaRodrigo Vaez Ronie DotzlawRosely Moreira de JesusSeire ParejaSergio PomerancblumSilvio SzniferSuzana da Costa OliveiraTásio Vasconcelos da SilveiraThiago Magela Rodrigues DiasTiago Gimenez RibeiroVanderlei Carvalho Rodrigues PintoVanessa dos Santos AlmeidaVastí Mendes da Silva RochaWagner Eliezer Roncoletta

Auxiliadores especiaisRevisão Geral do texto para os seguintes Países:

• Brasil – Tiago Flach• Guiné Bissau – Alfredo Cá, Bunene Sisse e Buon Olossato Quebi – ONG Asas de Socorro

Coordenação do DFJUG• Daniel deOliveira – JUGLeader responsável pelos acordos de parcerias• Luci Campos - Idealizadora do DFJUG responsável pelo apoio social• Fernando Anselmo - Coordenador responsável pelo processo de tradução e revisão,

disponibilização dos materiais e inserção de novos módulos• Regina Mariani - Coordenadora responsável pela parte jurídica• Rodrigo Nunes - Coordenador responsável pela parte multimídia• Sérgio Gomes Veloso - Coordenador responsável pelo ambiente JEDITM (Moodle)

Agradecimento EspecialJohn Paul Petines – Criador da Iniciativa JEDITM

Rommel Feria – Criador da Iniciativa JEDITM

Introdução à Programação II 3

Page 254: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Antes de entrar em outras características do Java, inicialmente iremos revisar alguns assuntos que vimos no primeiro módulo do curso. Esta lição fornece uma discussão breve sobre os diferentes conceitos de Orientação a Objetos em Java.

Ao final desta lição, o estudante será capaz de:

• Explicar e usar os conceitos básicos de orientação a objetos em seus códigos

• classes, objetos, atributos, métodos e construtores

• Descrever conceitos avançados de orientação a objetos e aplicá-los na codificação

• pacote, encapsulamento, abstração, herança, polimorfismo e interface

• Descrever e utilizar as palavras-chaves: this, super, final e static

• Diferenciar entre polimorfismo por overloading e override

Introdução à Programação II 4

Page 255: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Conceitos de orientação a objetos

2.1. Modelagem Orientada a ObjetosModelagem Orientada a Objetos é uma técnica que possui foco na modelagem de objetos e classes baseados no cenário do mundo real. Ela dá enfase ao estado, comportamento e interação dos objetos. Possibilita o benefício do desenvolvimento rápido, aumenta a qualidade, fácil manutenção, a facilidade de alterações e a reutilização de software.

2.2. ClassePermite definir novos tipos de dados. Serve como um referencial, a qual é um modelo para os objetos que é possível criar utilizando este novo tipo de dado.

O modelo de um estudante seria um exemplo de uma classe. Podemos definir que cada aluno terá uma série de qualidades tais como nome, número do estudante e nível escolar.

2.3. ObjetoÉ uma entidade que possui um estado, um comportamento e uma identidade com um papel bem definido no escopo do problema. É uma instância real de uma classe. Sendo assim, é chamado de instância da classe. Criado toda vez que for utilizado a palavra-chave new. Em um projeto de registro de estudantes, um exemplo de objeto pode ser uma entidade estudante, como Ana. Ana é um objeto da classe Estudante. Desta forma, as qualidades e habilidades definidas no modelo da classe Estudante são todos aplicáveis a Ana, já que Ana é uma instância de Estudante.

Para simplificar, pensamos em uma classe como um termo mais geral se comparado a um objeto.

2.4. AtributoRefere-se ao elemento dos dados de um objeto. Ele armazena informações sobre o objeto. É também conhecido como dado do objeto, atributo do objeto, propriedade ou campo. No projeto de registro do aluno, alguns atributos da entidade aluno incluem o nome, número do estudante e nível de escolaridade.

2.5. MétodoDescreve o comportamento de um objeto. Em linguagens relacionais seria comparado a uma função ou procedimento. Métodos disponíveis para a entidade estudante são genéricos e atendem a escola.

2.6. ConstrutorÉ um tipo especial de método que é utilizado para a construção ou criação de um novo objeto. Lembre-se que construtores não são elementos (atributos, métodos e classes internas de um objeto).

2.7. Pacote Refere ao agrupamento de classes e sub-classes. Sua estrutura é análoga a de um diretório.

2.8. EncapsulamentoPrincípio de ocultar a modelagem ou as informações de implementação que não são referentes ao objeto atual.

2.9. AbstraçãoPrincípio de ignorar os aspectos subjetivos que não são relevantes para o real propósito em prol de se concentrar mais diretamente naqueles que são.

Introdução à Programação II 5

Page 256: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2.10. HerançaPrincípio que surge com a relação entre classes. Uma classe é a superclasse ou a classe pai de outra. É relativo às propriedades e aos comportamentos recebidos pelo antecessor. É também conhecida como uma relação "é-um" (is-a). Considere a seguinte hierarquia:

SuperHero

FlyingSuperHero UnderwaterSuperHeroFigura 1: Exemplo de herança

SuperHero é a superclasse das classes FlyingSuperHero e UnderwaterSuperHero. Note que FlyingSuperHero "é-um" SuperHero e UnderwaterSuperHero "é-um" SuperHero.

2.11. PolimorfismoHabilidade de um método poder assumir diferentes formas. Literalmente, "poli" significa muitas enquanto "morph" significa forma. Referenciando o exemplo anterior para herança, supomos um método displayPower na classe SuperHero que retorna o poder que o super-herói possui, na classe FlyingSuperHero este mesmo método poderia retornar "voar" enquanto que na classe UnderwaterSuperHero este mesmo método retornaria "respirar embaixo d'água".

2.12. InterfaceÉ um contrato na forma de uma coleção de declarações de métodos e constantes. Quando uma classe implementa uma interface, ela se compromete a implementar todos os métodos declarados nesta.

Introdução à Programação II 6

Page 257: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Estrutura de codificação JavaEsta seção resume a sintaxe básica usada para a criação de aplicações em Java.

3.1. Declarando classes em Java

<declaraçãoClasse> ::= <modificador> class <nomeClasse> { <declaraçãoAtributo>* <declaraçãoConstrutor>* <declaraçãoMétodo>*}

onde:

<modificador> é um modificador de acesso, o qual deve ser combinado com outros tipos de modificadores.

Guia de código:

* Poderá existir nenhuma ou diversas ocorrências da linha onde este símbolo foi aplicado.

<descrição> Indica a descrição de um valor para esta parte.

Lembre-se que para uma classe de alto nível, os únicos modificadores de acesso são public e default (neste caso, nenhum modificador de acesso precede a palavra-chave class).

O seguinte exemplo declara a classe SuperHero:

class SuperHero { String superPowers[]; void setSuperPowers(String superPowers[]) { this.superPowers = superPowers; } void printSuperPowers() { for (int i = 0; i < superPowers.length; i++) { System.out.println(superPowers[i]); } }}

3.2. Declarando Atributos<declaraçãoAtributo> ::= <modificador> <tipo> <nome> [= <valorPadrão>];<tipo> ::= byte | short | int | long | char | float | double | boolean | <classeQualquer>

Guia de código:

[] Indica que esta parte é opcional.

Aqui está um exemplo.

public class AttributeDemo { private String studNum; public boolean graduating = false; protected float unitsTaken = 0.0f; String college;

Introdução à Programação II 7

Page 258: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}

3.3. Declarando métodos<declaraçãoMétodo> ::= <modificador> <tipoRetorno> <nome>(<argumento>*) { <instrução>* }<argumento> ::= <tipoArgumento> <nomeArgumento>[,]

Por exemplo:class MethodDemo { int data; int getData() { return data; } void setData(int data) { this.data = data; } void setMaxData(int data1, int data2) { data = (data1>data2)? data1 : data2; }}

3.4. Declarando um construtor<declaraçãoConstrutor> ::= <modificador> <nome da classe> (<argumento>*) { <instrução;>* }

Se um construtor não é explicitamente fornecido, um construtor padrão é automaticamente criado. O construtor padrão não possui argumentos e o seu corpo não possui instruções.

Dicas de programação:

1. O nome do construtor deve ser o mesmo nome da classe.2. O único <modificador> válido para construtores são public, protected, e

private.3. Construtores não possuem valor de retorno.

Considere a seguinte classe:

class ConstructorDemo { private int data; public ConstructorDemo() { data = 100; } ConstructorDemo(int data) { this.data = data; }}

3.5. Construir um objetoPara construir um objeto a partir de uma classe, utilizamos a palavra-chave new seguida por uma chamada ao construtor.

class ConstructObj { int data;

Introdução à Programação II 8

Page 259: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

ConstructObj() { /* Inicialização dos dados */ } public static void main(String args[]) { ConstructObj obj = new ConstructObj(); }}

3.6. Acessando elementos dos objetosPara acessar os elementos de um objeto, utilizamos a notação do "ponto". É usada da seguinte forma:

<objeto>.<elemento>

O exemplo seguinte, feito com base no anterior com instruções adicionais para acessar os elementos.

class ConstructObj { int data; ConstructObj() { /* Dados de inicialização */ } void setData(int data) { this.data = data; } public static void main(String args[]) { ConstructObj obj = new ConstructObj(); //instanciamento obj.setData(10); //acesso a setData() System.out.println(obj.data); //acesso a data }}

A execução desta classe mostrará o seguinte resultado:

10

3.7. PacotesPara indicar que uma determinada classe pertence a um pacote em particular, utilizamos a seguinte sintaxe:

<declaraçãoPacote> ::= package <nomePacote>;

Para importar outros pacotes, use a seguinte sintaxe:

<declaraçãoImportação> ::= import <nomePacote.elementoAcessado>;

Com isso, seu código fonte deve ter o seguinte formato:

[<declaraçãoPacote>]<declaraçãoImportação>*<declaraçãoClasse>+

Guia de código:

+ que pode ter 1 ou mais ocorrências da linha onde isso foi aplicado.

Vejamos o seguinte exemplo:

// Classe pertence ao pacote registration.reports

Introdução à Programação II 9

Page 260: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

package registration.reports;

// Importa todas as classes do pacote registration.processingimport registration.processing.*;// Importa a classe List do pacote java.utilimport java.util.List;

// Cria a classe myClassclass MyClass { /* detalhes da classe MyClass */}

3.8. Os modificadores de acessoA tabela seguinte resume os modificadores de acesso em Java.

private default protected public

Mesma classe sim sim sim sim

Mesmo pacote não sim sim sim

Pacotes diferentes (sendo subclasse) não não sim sim

Pacotes diferentes (não sendo subclasse) não não não sim

Tabela 1: Modificadores de acesso

3.9. EncapsulamentoProtege os elementos da implementação de uma classe por ser realizado utilizando o modificador de acesso particular na declaração dos atributos.

O exemplo seguinte protege o atributo secret. Note que este atributo é indiretamente acessado por outras classes utilizando os métodos get e set.

class Encapsulation { private int secret; //Campo oculto public boolean setSecret(int secret) { if (secret < 1 || secret > 100) { return false; } this.secret = secret; return true; } public int getSecret() { return secret; }}

Caso não se deseje que outras classes modifiquem o atributo secret, é possível configurar o modificador de acesso do método setSecret() como particular (private).

3.10. HerançaPara se criar uma classe filha ou uma subclasse com base em uma classe existente, utilizamos a palavra-chave extends na declaração da classe. Uma classe pode estender qualquer classe desde que ela não possua o modificador final.

Por exemplo. A classe Point é a super-classe da classe ColoredPoint:

import java.awt.*;class Point { int x;

Introdução à Programação II 10

Page 261: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

int y;}

class ColoredPoint extends Point { Color color;}

3.11. Realizando override em métodosUm método de uma subclasse pode modificar um método de uma super-classe quando a subclasse define um método cuja assinatura é idêntica ao método da super-classe. A assinatura de um método e a informação encontrada no cabeçalho de definição deste. A assinatura inclui o tipo de retorno, o nome e a lista de argumentos do método. Os modificadores de acesso e outras palavras-chaves, tais como final e static, não estão incluídos.

class Superclass { void display(int n) { System.out.println("super: " + n); }}class Subclass extends Superclass { void display(int k) { // método overriding System.out.println("sub: " + k); }}class OverrideDemo { public static void main(String args[]) { Subclass SubObj = new Subclass(); Superclass SuperObj = SubObj; SubObj.display(3); ((Superclass)SubObj).display(4); }}

A execução desta classe mostrará o seguinte resultado:

sub: 3sub: 4

O método chamado é determinado pelo tipo de dado do objeto que invoca o método.Os modificadores de acesso dos métodos não precisam ser os mesmos. Contudo, os métodos polimórficos devem ter modificadores de acesso igual ou menos restritivos que os métodos originais.

Considere o seguinte exemplo. Vejamos qual dos seguintes métodos com polimorfismo por override pode causar um erro no momento de compilação.

class Superclass { void overriddenMethod() { }}

class Subclass1 extends Superclass { public void overriddenMethod() { }}

class Subclass2 extends Superclass { void overriddenMethod() { }}

Introdução à Programação II 11

Page 262: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

class Subclass3 extends Superclass { protected void overriddenMethod() { }}

class Subclass4 extends Superclass { private void overriddenMethod() { }}

O método overriddenMethod() da Superclass possui o modificador de acesso default. O único modificador mais restrito que esse é o private. Sendo assim, Subclass4 provoca um erro de compilação porque ele tenta modificar o método overriddenMethod() na Superclass com um modificar private que é mais restritivo.

3.12. Classes e métodos abstratosA forma genérica para um método abstrato é a seguinte:

abstract <modificador> <tipoRetorno> <nome>(<argumento>*);

Uma classe contendo um método abstrato deve ser declarada como uma classe abstrata.

abstract class <Nome> { /* construtores, campos e métodos */}

A palavra-chave abstract não pode ser aplicada para construtores ou métodos estáticos. É importante lembrar também que classes abstratas não podem servir para a construção de objetos (desde que seus métodos sejam implementados).

Classes que estendem uma classe abstrata são obrigadas a implementar todos os métodos abstratos. Caso contrário a subclasse deverá ser declarada também como abstract.

Dicas de programação:

1. Note que declarar um método abstract é muito similar à declaração de uma classe normal exceto que um método abstrato não possui corpo. Sua assinatura é imediatamente finalizada por um ponto e vírgula (;). Por exemplo:

abstract class SuperHero { abstract void displayPower();}class Superman extends SuperHero { void displayPower() { System.out.println("Fly..."); }}

class SpiderMan extends SuperHero { void displayPower() { System.out.println("Fast..."); }}

3.13. InterfaceDeclarar uma interface é basicamente como declarar uma classe, entretanto, ao invés de utilizar a palavra-chave class, utilizamos a palavra-chave interface. Eis a sintaxe:

Introdução à Programação II 12

Page 263: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

<declaraçãoInterface> ::= <modificador> interface <Nome> { <declaraçãoAtributo>* [<modificador> <tipoRetorno> <nome>(<argumento>*);]* }

Os métodos e atributos são obrigatoriamente public.

Dicas de programação:

1. Atributos são implicitamente static e final e são obrigados a serem inicializados com um valor constante.

2. Como na declaração de uma classe de alto nível, o único modificador de acesso válido são public e package (caso nenhum modificador de acesso preceder a palavra-chave class).

Uma classe pode implementar uma interface existente utilizando a palavra-chave implements. Esta classe é obrigada a implementar todos os métodos da interface. Uma classe pode implementar mais de uma interface.

O exemplo a seguir demonstra com declarar e utilizar uma interface:

interface MyInterface { void iMethod();}class MyClass1 implements MyInterface { public void iMethod() { System.out.println("Interface method."); }

void myMethod() { System.out.println("Another method."); }}

class MyClass2 implements MyInterface { public void iMethod() { System.out.println("Another implementation."); }}

class InterfaceDemo { public static void main(String args[]) { MyClass1 mc1 = new MyClass1(); MyClass2 mc2 = new MyClass2();

mc1.iMethod(); mc1.myMethod(); mc2.iMethod(); }}

A execução desta classe mostrará o seguinte resultado:

Interface method.Another method.Another implementation.

Introdução à Programação II 13

Page 264: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.14. A palavra-chave thisA palavra-chave this pode ser utilizada pela seguintes razões:

1. Diferenciar atributos locais dos atributos de classe.

2. Referenciar objetos que invocam métodos não estáticos.

3. Referenciar outros construtores.

Como exemplo, considere a seguinte classe onde data funciona como um atributo e um argumento ao mesmo tempo:

class ThisDemo1 { int data; void method(int data) { this.data = data; /* this.data refere-se ao atributo enquanto data refere-se ao argumento */ }}

O exemplo seguinte demonstra como este objeto é implicitamente referenciado quando os seus elementos não estáticos são invocados.

class ThisDemo2 { int data; void method() { System.out.println(data); //this.data } void method2() { method(); //this.method(); }}

Vamos rever o significado de polimorfismo por overloading. Um construtor, assim como um método, pode ser modificado. Métodos diferentes numa mesma classe podem compartilhar o mesmo nome desde que a lista de seus argumentos sejam diferentes. Métodos overloading precisam diferir no número ou no tipo de seus argumentos. Este próximo exemplo possui dois construtores e a referência this é utilizada para se referenciar a outras versões do construtor.

class ThisDemo3 { int data; ThisDemo3() { this(100); } ThisDemo3(int data) { this.data = data; }}

Dicas de programação:

1. A chamada para this() deve ser a primeira instrução no construtor.

3.15. A palavra-chave superO uso da palavra-chave super está relacionado com herança. É utilizada para chamar construtores da super-classe. Também pode ser utilizada como a palavra-chave this para referenciar elementos da super-classe.

Introdução à Programação II 14

Page 265: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A classe a seguir demonstra como a referência super é utilizada para chamar o construtor da super-classe.

class Person { String firstName; String lastName; Person(String fname, String lname) { firstName = fname; lastName = lname; }}

class Student extends Person { String studNum; Student(String fname, String lname, String sNum) { super(fname, lname); studNum = sNum; }}

Dicas de programação:

1. super() refere-se a super-classe imediata. Ela deve ser a primeira instrução do contrutor da subclasse.

Está palavra-chave também pode ser utilizada para referenciar os elementos da super-classe como mostrado no exemplo seguinte.

class Superclass{ int a; void display_a(){ System.out.println("a = " + a); }}

class Subclass extends Superclass { int a; void display_a(){ System.out.println("a = " + a); } void set_super_a(int n){ super.a = n; } void display_super_a(){ super.display_a(); }}

class SuperDemo { public static void main(String args[]){ Superclass SuperObj = new Superclass(); Subclass SubObj = new Subclass(); SuperObj.a = 1; SubObj.a = 2; SubObj.set_super_a(3); SuperObj.display_a(); SubObj.display_a(); SubObj.display_super_a(); System.out.println(SubObj.a); }

Introdução à Programação II 15

Page 266: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}

A execução desta classe mostrará o seguinte resultado:

a = 1a = 2a = 32

3.16. A palavra-chave staticA palavra-chave static pode ser aplicada a elementos de uma classe. Permite que atributos ou métodos das classes sejam acessados antes que qualquer instância da classe seja criada.

Um atributo de classe possui o acesso global para a classe. Isto significa que o atributo pode ser acessado por todas as instâncias da classe.

Métodos estáticos podem ser invocados sem necessitar criar uma instância da classe. Todavia, eles só acessam os elementos estáticos da classe. Além disso, eles não podem fazer referencia aos objetos this ou super.

A palavra-chave static pode também ser aplicada aos free-blocks. Estes são chamados de blocos estáticos. Estes blocos são executados somente uma vez quando a classe é carregada. Eles são usualmente utilizados para inicializar atributos estáticos da classe.

class Demo { static int a = 0; static void staticMethod(int i) { System.out.println(i); } static { //static block System.out.println("This is a static block."); a += 1; }}

class StaticDemo { public static void main(String args[]) { System.out.println(Demo.a); Demo.staticMethod(5); Demo d = new Demo(); System.out.println(d.a); d.staticMethod(0); Demo e = new Demo(); System.out.println(e.a); d.a += 3; System.out.println(Demo.a+", " +d.a +", " +e.a); }}

A execução desta classe mostrará o seguinte resultado:

This is a static block.151014, 4, 4

3.17. A palavra-chave finalA palavra-chave final pode ser utilizada para atributos, métodos e classes. Para lembrar da

Introdução à Programação II 16

Page 267: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

função da palavra-chave final, simplesmente lembre-se que ela restringe a modificação de atributos, métodos e classes.

O valor de um atributo final não pode ser modificado uma vez que esse valor foi determinado. Por exemplo:

final int data = 10;

A instrução seguinte irá causar um erro de compilação:

data++;

Um método final não pode ser modificado na classe filha:

final void myMethod() { //em uma classe pai}

myMethod não poderá mais ser realizado o polimorfismo por override na classe filha.

Uma classe final não poderá mais ser herdada ao contrário das classes comuns.

final public class MyClass {}

Dicas de programação:

1. A ordem de digitação das palavras-chaves final e public podem ser trocadas.2. Essa instrução irá provocar um erro de compilação, pois MyClass não pode ser

extendida.

public WrongClass extends MyClass {}

3.18. Classes internasUma classe interna é uma classe declarada dentro de outra classe.

class OuterClass { int data = 5; class InnerClass { int data2 = 10; void method() { System.out.println(data); System.out.println(data2); } } public static void main(String args[]) { OuterClass oc = new OuterClass(); InnerClass ic = oc.new InnerClass(); System.out.println(oc.data); System.out.println(ic.data2); ic.method(); }}

A execução desta classe mostrará o seguinte resultado:

510

Introdução à Programação II 17

Page 268: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Para acessarmos os elementos da classe interna, precisamos de uma instância da classe interna. Métodos de uma classe interna podem acessar diretamente os elementos da classe externa.

Introdução à Programação II 18

Page 269: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 2Exceções e Assertivas

Versão 1.0 - Mar/2007

Page 270: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

O conceito básico sobre tratamento de exceções foi mostrado no Módulo 1 – Introdução a Programação I. Esta lição fornecerá um entendimento aprofundado sobre exceções e também sobre assertivas.

Ao final desta lição, o estudante será capaz de:

• Tratar exceções pelo uso de try, catch e finally• Diferenciar entre o uso de throw e throws• Utilizar as classes de exceções existentes• Diferenciar entre exceções verificadas e não verificadas• Definir suas próprias classes de exceção• Explicar os benefícios do uso de assertivas• Utilizar declarações assertivas

Introdução à Programação II 4

Page 271: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. O que são exceções?

2.1. Introdução

Bugs ou erros ocorrem freqüentemente na execução dos projetos, mesmo quando estes são escritos por programadores hábeis e experientes. Para evitar perder mais tempo na verificação do erro do que na resolução do problema em si, Java nos fornece um mecanismo para o tratamento de exceções.

As exceções são, resumidamente, eventos excepcionais. São erros que ocorrem durante a execução de um determinado trecho de instrução, alterando o seu fluxo normal. Os erros podem ocorrer por diferentes motivos, por exemplo: erros de divisão por zero, acessar elementos em um array além de seu próprio tamanho, entrada inválida, erro de acesso ao disco rígido, abertura de arquivo inexistente e estouro de memória.

2.2. As classes Error e Exception

Todas as exceções são sub-classes, direta ou indiretamente, da classe Throwable. Imediatamente abaixo desta classe encontram-se as duas categorias gerais de exceções: as classes Error e Exception.

A classe Exception lida com as condições que os usuários podem tratar. Em geral, estas condições são o resultado de algumas falhas no código. Exemplo de exceções são: erro de divisão por zero e erro de índice em um array.

Por outro lado, a classe Error é utilizada pela JVM para manipular os erros ocorridos no ambiente de execução. Geralmente, estes erros estão além do controle do programador, desde que sejam causados dentro do ambiente de execução. Por exemplo: erro de falta de memória e erro de acesso ao disco rígido.

2.3. Exemplo de Exceção

Considere a seguinte classe:

class DivByZero { public static void main(String args[]) { System.out.println(3/0); System.out.println(“Pls. print me.”); }}

Executando o código, a seguinte mensagem de erro será apresentada:

Exception in thread "main" java.lang.ArithmeticException: / by zero at DivByZero.main(DivByZero.java:3)

A mensagem fornece a informação do tipo de exceção que ocorreu e a linha do código que a originou. Esta é a forma como o manipulador padrão trata as exceções não capturadas. Quando não há código do usuário tratando as exceções, o manipulador padrão de exceções entra em ação. Primeiramente, a descrição da exceção que ocorreu é apresentada. Além disso, também é apresentado o caminho que indica a hierarquia dos métodos até onde a exceção aconteceu. Por fim, o manipulador padrão de exceções faz com que o código termine sua execução.

Ao necessitar tratar as exceções de uma maneira diferente? Felizmente, a linguagem Java possui três importantes palavras-chaves para o tratamento de exceções try, catch e finally.

Introdução à Programação II 5

Page 272: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Capturando Exceções

3.1. As instruções try-catch

Como mencionado na seção anterior, as palavras-chaves try, catch e finally são usadas para tratar diferentes tipos de exceções. Estas três palavras-chaves são usadas juntas mas o bloco finally é opcional. Primeiramente, focaremos no bloco try-catch e mais tarde voltaremos ao bloco finally.

Encontra-se abaixo a sintaxe geral de uma instrução try-catch.

try { <código a ser monitorado para exceções>} catch (<ClasseExceção1> <nomeObj>) { <tratar se ClasseExceção1 ocorrer>}...} catch (<ClasseExceçãoN> <NomeObj>) { <tratar se ClasseExceçãoN ocorrer>}

Dicas de programação:

1. O bloco catch começa depois do fechamento do bloco precedente, seja este try ou catch.

2. Instruções dentro do bloco devem ser recuadas de modo a conseguir uma melhor visualização.

Aplicando isto a classe DivByZero teremos:

class DivByZero { public static void main(String args[]) { try { System.out.println(3/0); System.out.println(“Please print me.”); } catch (ArithmeticException exc) { //reação ao evento System.out.println(exc); } System.out.println(“After exception.”); }}

O erro de divisão por zero é um exemplo de um tipo de exceção encontrado na classe ArithmeticException. O código trata o erro simplesmente apresentando uma descrição do problema.

Como saída para esta classe, teremos:

java.lang.ArithmeticException: / by zeroAfter exception.

Um código específico monitorado no bloco try pode causar a ocorrência de mais de um tipo de exceção. Neste caso, os diferentes tipos de erro podem ser tratados pelo uso de diversos blocos catch. Observe que o código no bloco try pode acionar apenas uma exceção por vez, mas pode provocar a ocorrência de diferentes tipos de exceção em momentos diferentes.

Aqui temos um exemplo de uma classe que trata mais de um tipo de exceção:

Introdução à Programação II 6

Page 273: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

class MultipleCatch { public static void main(String args[]) { try { int den = Integer.parseInt(args[0]); //linha 4 System.out.println(3/den); //linha 5 } catch (ArithmeticException exc) { System.out.println(“Divisor was 0.”); } catch (ArrayIndexOutOfBoundsException exc2) { System.out.println(“Missing argument.”); } System.out.println(“After exception.”); }}

Neste exemplo, a linha 4 pode retornar uma ArrayIndexOutOfBoundsException quando o usuário se esquecer de entrar com um argumento enquanto a linha 5 retorna uma ArithmeticException se o usuário entrar 0 como argumento.

Veja o que acontece ao executar a classe quando os seguintes argumentos abaixo são informados pelo usuário:

1. Se nenhum argumento for passado, a seguinte saída será apresentada:

Missing argument.After exception.

2. Passando o valor 1 como argumento, a seguinte saída será apresentada:

3After exception.

3. Passando o valor 0, a seguinte saída será apresentada:

Divisor was 0.After exception.

Também é possível aninhar blocos try em Java.

class NestedTryDemo { public static void main(String args[]){ try { int a = Integer.parseInt(args[0]); try { int b = Integer.parseInt(args[1]); System.out.println(a/b); } catch (ArithmeticException e) { System.out.println(“Divide by zero error!"); } } catch (ArrayIndexOutOfBoundsException exc) { System.out.println(“2 parameters are required!"); } }}

Vejamos o que acontece a classe quando os seguintes argumentos são informado:

a) Nenhum argumento

2 parameters are required!

Introdução à Programação II 7

Page 274: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

b) Valor 15

2 parameters are required!

c) Valor 15 3

5

d) Valor 15 0

Divide by zero error!

O código abaixo possui um try aninhado mascarado com o uso de métodos:

class NestedTryDemo2 { static void nestedTry(String args[]) { try { int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); System.out.println(a/b); } catch (ArithmeticException e) { System.out.println("Divide by zero error!"); } } public static void main(String args[]){ try { nestedTry(args); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("2 parameters are required!"); } }}

Qual é a saída dessa classe quando testado com os seguintes argumentos?

a) Nenhum argumentob) 15c) 15 3d) 15 0

A saída esperada para a classe NestedTryDemo2 é similar a classe NestedTryDemo.

3.2. A palavra-chave finally

Iremos agora incorporar a palavra-chave finally à instrução try-catch. Observe como as palavras reservadas são organizadas no bloco:

try { <código a ser monitorado para exceções>} catch (<ClasseExceção1> <nomeObj>) { <tratar se ClasseExceção1 ocorrer>} ...} finally { <código a ser executado antes do bloco try ser finalizado>}

Introdução à Programação II 8

Page 275: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Dicas de programação:

1. A mesma convenção de codificação se aplica ao bloco finally como no bloco catch. O bloco finally começa depois do fechamento do bloco catch precedente.

2. Instruções dentro desse bloco devem ser também adiantadas de forma a conseguir melhor clareza no código.

O bloco finally contém o código para a finalização após um try ou catch. Este bloco de código é sempre executado independentemente de uma exceção acontecer ou não no bloco try. Isto permanece verdadeiro mesmo que instruções return, continue ou break sejam executadas.

Vejamos um exemplo completo com o bloco try-catch-finally:

class FinallyDemo { public static void main(String args[]) { for (int i = 1; i > -1; i--) { try { System.out.println(2/i); } catch (ArithmeticException e) { System.out.println("Divide by zero error!"); } finally { System.out.println("Finally forever!"); } } }}

A saída esperada para esta classe, será:

2Finally forever!Divide by zero error!Finally forever!

Introdução à Programação II 9

Page 276: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Lançamento de Exceções

4.1. A palavra-chave throw

Além de capturar exceções, Java também permite que os métodos lancem exceções (por exemplo, faz com que um evento excepcional ocorra). A sintaxe para o lançamento de exceções é:

throw <objetoExceção>;

Considere este exemplo:

class ThrowDemo { public static void main(String args[]){ try { throw new RuntimeException("throw demo"); } catch (RuntimeException e) { System.out.println("Exception caught here."); System.out.println(e); } }}

Esta classe mostrará a seguinte saída:

Exception caught here.java.lang.RuntimeException: throw demo

4.2. A palavra-chave throws

No caso de um método causar uma exceção mas não capturá-la, deve-se utilizar a palavra-chave throws para repassar esta para quem o chamou. Esta regra se aplica apenas para exceções verificadas. Veremos mais sobre exceções verificadas e não-verificadas mais a frente.

Esta é a sintaxe para o uso da palavra-chave throws:

<tipo>* <nomeMetodo> (<argumento>*) throws <listaExcecao> { <instrução>*}

É necessário um método para cada catch ou lista de exceções que podem ser lançadas, contudo podem ser omitidas aquelas do tipo Error ou RuntimeException, bem como suas sub-classes.

Este exemplo indica que myMethod não trata ClassNotFoundException.

class ThrowingDemo { public static void myMethod() throws ClassNotFoundException { throw new ClassNotFoundException("just a demo"); } public static void main(String args[]) { try { myMethod(); } catch (ClassNotFoundException e) { System.out.println(e); } }}

A classe apresentará a seguinte saída:

Introdução à Programação II 10

Page 277: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

java.lang.ClassNotFoundException: just a demo

Existem quatro cenários diferentes num bloco try-catch-finally:

1. Uma saída forçada ocorre quando o fluxo de controle é forçado a sair do bloco try por uma instrução return, continue ou break.

2. As instruções dentro do bloco try-catch-finally executam normalmente sem que erro algum ocorra.

3. O código pode ter um bloco catch específico para tratar a exceção que foi lançada.4. Temos o oposto do terceiro cenário, onde a exceção não é tratada. Nesse caso, a exceção

lançada não foi tratada por nenhum bloco catch.

Estes cenários são vistos na classe a seguir:

class FourDemo { static void myMethod(int n) throws Exception{ try { switch(n) { case 1: System.out.println("first case"); return; case 3: System.out.println("third case"); throw new RuntimeException("third case demo"); case 4: System.out.println("fourth case"); throw new Exception("fourth case demo"); case 2: System.out.println("second case"); } } catch (RuntimeException e) { System.out.print("RuntimeException caught: " + e.getMessage()); } finally { System.out.println("try-block is entered."); } } public static void main(String args[]){ for (int i=1; i<=4; i++) { try { FourDemo.myMethod(i); } catch (Exception e){ System.out.print("Exception caught: "); System.out.println(e.getMessage()); } System.out.println(); } }}

As seguintes linhas são esperadas como saída dessa classe:

first casetry-block is entered.

second casetry-block is entered.

third caseRuntimeException caught: third case demotry-block is entered.

fourth casetry-block is entered.Exception caught: fourth case demo

Introdução à Programação II 11

Page 278: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Categorias de Exceções

5.1. Hierarquia das Classes de Exceções

Conforme mencionado anteriormente, a classe de origem de todas as classes de exceção é Throwable. Abaixo encontra-se a hierarquia das classes de exceções. Todas essas exceções estão definidas no pacote java.lang.

Hierarquia das Classes de ExceçõesThrowable Error LinkageError, ...

VirtualMachineError, ...Exception ClassNotFoundException,

CloneNotSupportedException, IllegalAccessException,InstantiationException,InterruptedException,IOException, EOFException,

FileNotFoundException,...

RuntimeException, ArithmeticException, ArrayStoreException, ClassCastException, IllegalArgumentException, (IllegalThreadStateException e NumberFormatException como sub-classes)IllegalMonitorStateException, IndexOutOfBoundsException, NegativeArraySizeException, NullPointerException, SecurityException

...

Tabela 1: Hierarquia das Classes de Excessões

Agora que estamos familiarizados com diversas classes de exceção, devemos conhecer a seguinte regra: Múltiplos blocos catch devem ser ordenados da sub-classe para a super-classe.

class MultipleCatchError { public static void main(String args[]){ try { int a = Integer.parseInt(args [0]); int b = Integer.parseInt(args [1]); System.out.println(a/b); } catch (Exception e) { System.out.println(e); } catch (ArrayIndexOutOfBoundsException e2) { System.out.println(e2); } System.out.println("After try-catch-catch."); }}

A compilação desse código produzirá a mensagem de erro abaixo, já que a classe Exception é super-classe da classe ArrayIndexOutOfBoundsException.

MultipleCatchError.java:9: exception java.lang.ArrayIndexOutOfBoundsException has already been caught } catch (ArrayIndexOutOfBoundsException e2) {

Introdução à Programação II 12

Page 279: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5.2. Exceções Verificadas e Não-verificadas

Uma exceção pode ser verificada ou não-verificada.

Uma exceção verificada é aquela que é verificada pelo compilador Java. O compilador se certifica que cada catch ou lista de exceções encontram-se dentro da cláusula throws. Se a exceção verificada não for capturada nem listada, ocorre um erro de compilação.

Ao contrário das exceções verificadas, as exceções não-verificadas não são condicionadas à verificação para o tratamento de exceções no momento da compilação. As classes de exceção não-verificadas são: Error, RuntimeException, e suas sub-classes. Desse modo, estes tipos de exceção não são verificadas porque o tratamento de todas as exceções pode complicar o código o que causaria um enorme transtorno.

5.3. Exceções Definidas pelo Usuário

Apesar de muitas classes de exceção já existirem no pacote java.lang, as classes de exceção embutidas não são suficientes para cobrir todas possibilidades de exceções que podem ocorrer. Por essa razão, é provável criar nossas próprias exceções.

Para criar nossa própria exceção, teremos que criar uma classe que estenda a classe RuntimeException ou Exception. Deste modo, devemos customizar a classe de acordo com o problema a ser resolvido. Atributos de objeto e construtores podem ser adicionados na sua classe de exceção.

Segue um exemplo:

class ExplodeException extends RuntimeException{ public ExplodeException(String msg) { super(msg); }}class ExplodeDemo { public static void main(String args[]) { try { throw new ExplodeException("Explode Message"); } catch (ExplodeException e) { System.out.println("Message: " + e.getMessage()); } }}

Aqui está a saída esperada para a classe:

Message: Explode Message

Introdução à Programação II 13

Page 280: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Assertivas

6.1. O que são Assertivas?

Assertivas permitem ao programador descobrir se uma suposição foi encontrada. Por exemplo, uma data onde o mês não está no intervalo entre 1 e 12 deveria ser considerada inválida. O programador pode afirmar que o mês deve se encontrar neste intervalo. Contudo, é possível utilizar outros construtores para simular a funcionalidade das assertivas, mas seria difícil fazer isto de alguma maneira com o recurso da assertiva desabilitado. A boa notícia sobre assertivas é que o usuário tem a opção de habilitá-la ou não na execução. Assertivas podem ser consideradas como uma extensão de comentários em que a assertiva informa à pessoa que lê o código que uma condição específica deve ser sempre satisfeita. Com assertivas não há necessidade de ler cada comentário para descobrir suposições feitas no código. Em vez disso, ao executar a classe, a mesma informará se as assertivas feitas são verdadeiras ou não. No caso de uma assertiva ser falsa, um AssertionError será lançado.

6.2. Habilitando e Desabilitando Assertivas

Para utilizar as declarações assertivas não se faz necessário a importação do pacote java.util.assert. Declarações assertivas são utilizadas para verificar os argumentos de métodos não-públicos, pois métodos públicos podem ser acessados diretamente por quaisquer outras classes. É possível que os autores dessas outras classes não estejam atentos que eles terão assertivas habilitadas. Nesse caso, a classe poderá agir incorretamente. Já os métodos não públicos, geralmente, são chamados por meio de códigos escritos por pessoas que tem acesso aos métodos. Desse modo, eles devem estar cientes que ao executar seu código, as assertivas devem estar habilitadas.

Para compilar arquivos que usam assertivas, um parâmetro extra na linha de comando é necessário como mostrado abaixo:

javac –source 1.4 MyProgram.java

Para executar a classe sem o recurso da assertiva, basta executá-la normalmente:

java MyProgram

Todavia, para habilitar o recurso das assertivas, é necessário utilizar os argumentos –ea ou -enableassertions:

java –enableassertions MyProgram

Para habilitar a verificação de assertivas em tempo de execução no NetBeans IDE, siga os seguintes passos:

1. Procure o nome do projeto no painel Projects à esquerda. Pressione com o botão direito no nome do projeto

2. Selecione Properties3. À esquerda, no painel Categories, selecione run4. No campo VM Options insira -ea5. Clique no botão OK6. Compile e execute o projeto normalmente.

As telas abaixo irão ajudá-lo a entender cada passo:

Introdução à Programação II 14

Page 281: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 1: Habilitando assertivas no NetBeans – Passos 1 e 2

Figura 2: Habilitando assertivas no NetBeans – Passo 3

Introdução à Programação II 15

Page 282: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 3: Habilitando assertivas no NetBeans – Passo 4

6.3. Sintaxe das Assertivas

A sintaxe das assertivas pode ser feita de duas formas.

A forma mais simples tem a seguinte sintaxe:

assert <expressãoLógica>;

onde <expression1> é a condição que é afirmada para ser verdadeira.

A outra forma utiliza duas expressões como demostra a sintaxe abaixo:

assert <expressãoLógica> : <mensagem>;

onde <expression1> é a condição que é afirmada para ser verdadeira e <expression2> é alguma informação útil para diagnosticar o motivo da instrução ter falhado.

Aqui temos um exemplo da forma mais simples de utilizar assertivas:

class AssertDemo { public static void main(String args[]) { assert(args == null); int age = Integer.parseInt(args[0]); if (age >= 18) { System.out.println("Congrats! You're an adult! =)"); } }}

A execução desta classe lança um AssertionError quando não existe argumento passado para a classe. Nesse caso, a seguinte mensagem de erro é apresentada na execução.

Introdução à Programação II 16

Page 283: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Exception in thread "main" java.lang.AssertionError at AssertDemo.main(AssertDemo.java:4)Java Result: 1

Passando como argumento um valor maior que 0 e menor que 18, a classe não apresentará nenhuma saída.

Para um argumento com valor maior ou igual a 18, será mostrada a seguinte saída:

Congrats! You're an adult! =)

As instruções seguinte é similar ao exemplo anterior exceto por apresentar uma informação adicional sobre a exceção ocorrida. Dessa forma utiliza-se a segunda sintaxe das assertivas.

class AssertDemo { public static void main(String args[]) { int age = Integer.parseInt(args[0]); assert(age>0) : "age should at least be 1"; /* se a idade é válida (ex. age>0) */ if (age >= 18) { System.out.println("Congrats! You're an adult! =)"); } }}

Quando o usuário entra com um argumento menor do que 1, ocorre um AssertionError e são apresentadas informações adicionais da exceção. Nesse cenário, a seguinte saída é apresentada.

Exception in thread "main" java.lang.AssertionError: age should at least be 1 at AssertDemo.main(AssertDemo.java:4)Java Result: 1

Para os outros casos, esta classe nos apresenta uma saída similar ao exemplo anterior.

Introdução à Programação II 17

Page 284: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 3Técnicas Avançadas de Programação

Versão 1.0 - Mar/2007

Page 285: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Esta lição introduz algumas técnicas avançadas de programação. Veremos detalhes sobre recursão e tipos de dados abstratos.

Ao final desta lição, o estudante será capaz de:

• Definir e aplicar recursão na programação• Diferenciar entre pilhas e filas• Implementar pilhas e filas seqüenciais• Implementar pilhas e filas encadeadas• Usar as classes Collection existentes

Introdução à Programação II 4

Page 286: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Recursão

2.1. O que é recursão?

Recursão é uma técnica poderosa para resolução de problemas que pode ser aplicada quando a natureza do problema exigir repetição. Ainda que estes tipos de problemas sejam solucionáveis utilizando a iteração (ex. uso de instruções de repetição como for, while e do-while). De fato, a iteração é uma ferramenta mais eficiente se comparada à recursão, mas a recursão provê uma solução mais elegante para o problema. Na recursão, é permitido aos métodos chamarem a si mesmos. O dado passado no método como argumento é armazenado temporariamente em uma pilha antes que a chamada do método seja completada.

2.2. Recursão versus Iteração

Para uma boa compreensão da recursão, observe como a técnica de repetição pode variar.

Determinados problemas de natureza repetitiva requerem uso explícito de estruturas de controle de repetição. Por outro lado, para a recursão, a tarefa é repetida chamando um mesmo método sucessivas vezes. A idéia aqui é definir o problema em pedaços de instâncias menores de si mesmo. Considere o cálculo do fatorial de um determinado inteiro. Esta recursão pode ser descrita da seguinte maneira: fatorial(n) = fatorial(n-1) * n; fatorial(1) = 1. Por exemplo, o fatorial de 2 é igual ao fatorial(1)*2, o qual é igual a 2. O fatorial de 3 é 6, o qual é igual ao fatorial(2)*3.

Figura 1: Exemplo de fatorial

Com a iteração, o processo termina quando a condição do laço falha. No caso de se utilizar recursão, o processo é finalizado uma vez que for encontrada uma condição particular em que este seja satisfeito. Por exemplo, como observado na definição recursiva do fatorial, o caso mais simples é quando a entrada é o 1. O 1 para esse problema é o caso básico.

O uso da iteração e da recursão pode em ambos os casos levar a laços infinitos se eles não forem usados corretamente.

A vantagem da iteração sobre a recursão é o desempenho. A iteração é mais rápida se comparada à recursão. Na recursão ocorre a passagem de parâmetros para o método, e isto pode consumir algum tempo de CPU. Entretanto, a recursão encoraja as boas práticas da engenharia de software pois, usualmente, resulta em um código mais fácil de compreender e promove a reutilização de uma solução previamente implementada.

Escolher entre iteração e recursão é a melhor maneira de balancear um bom desempenho e uma boa engenharia de software.

Introdução à Programação II 5

Page 287: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2.3. Fatorial: Um exemplo

O código a seguir mostra como calcular fatorial utilizando a técnica da iteração.

class FatorialDemo { public int factorial(int n) { int result = 1; for (int i = n; i > 1; i--) { result *= i; } return result; } public static void main(String args[]) { FatorialDemo fatorialDemo = new FatorialDemo(); System.out.println(fatorialDemo.factorial(5)); }}

Aqui é a mesma classe entretanto o método utiliza a recursão:

class FatorialDemo { public int factorial(int n) { if (n == 1) { /* saída do método */ return 1; } /* Definição recursiva; Invoca a si mesmo */ return factorial(n-1)*n; } public static void main(String args[]) { FatorialDemo fatorialDemo = new FatorialDemo(); System.out.println(fatorialDemo.factorial(5)); }}

Considere a saída esperada de um determinado código de inteiros. Observe o que acontece no código para uma determinada entrada. Aqui estão umas amostras de inteiros com suas saídas correspondentes.

a) Entrada: 11

b) Entrada: 36

c) Entrada: 5120

2.4. Imprimindo n em alguma base: Outro exemplo

Agora considere o problema de imprimir um número decimal em uma base específica definida pelo usuário. Observe que a solução para isto é usar a divisão repetitiva e escrever o resto no inverso. O processo termina quando a divisão é menor que a base. Assuma que a entrada do número decimal é 10 e converteremos para a base 8. Aqui está a solução usando caneta e papel.

Introdução à Programação II 6

Page 288: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Na solução, 10 é equivalente a 12 base 8. Aqui está outro exemplo. A entrada decimal é 165 para ser convertida em base 16.

165 é equivalente ao valor A5 na base 16. Note: A=10.

Essa é a solução iterativa para esse problema.

class DecToOthers { public static void main(String args[]) { int num = Integer.parseInt(args[0]); int base = Integer.parseInt(args[1]); printBase(num, base); } static void printBase(int num, int base) { int rem = 1; String digits = "0123456789abcdef"; String result = ""; /* o passo iterativo */ while (num!=0) { rem = num%base; num = num/base; result = result.concat(digits.charAt(rem)+""); } /* Imprimindo o inverso do resultado */ for(int i = result.length()-1; i >= 0; i--) { System.out.print(result.charAt(i)); } }}

Agora, essa é a recursão equivalente da solução acima.

class DecToOthersRecur { static void printBase(int num, int base) { String digits = "0123456789abcdef"; /* Passo recursivo*/ if (num >= base) { printBase(num/base, base); } /* Caso básico: num < base */ System.out.print(digits.charAt(num%base)); } public static void main(String args[]) { int num = Integer.parseInt(args[0]); int base = Integer.parseInt(args[1]); printBase(num, base); }}

Para atingir uma melhor compreensão do código, observe o conjunto de entrada. Aqui estão alguns exemplos de entrada.

Introdução à Programação II 7

Page 289: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

a) Num: 10, base: 21010

b) Num: 100, base: 8144

c) Num: 200, base: 9242

Introdução à Programação II 8

Page 290: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Tipos de Dados Abstratos

3.1. O que é um Tipo de Dado Abstrato?

Um tipo de dado abstrato (TDA) é uma coleção de elementos de dados providos com um conjunto de operações que são definidas nos elementos de dados. Pilhas, filas e árvores binárias são alguns exemplos de TDA. Nessa lição, aprenderemos sobre pilhas (stacks) e filas (queues).

3.2. Pilhas

Uma pilha é um conjunto de elementos de dados onde à manipulação desse elemento é permitida somente no topo (top) da pilha. A pilha é uma coleção de dados ordenado o qual a disciplina “último a entrar é o primeiro a sair” (do inglês: “last in, first out” - LIFO) é imposta. Pilhas são usadas para uma variedade de aplicações como o reconhecimento de padrões e a conversão entre as notações infixa, pós-fixa e pré-fixa.

As duas operações associadas às pilhas são a de adicionar (push) e a de remover (pop). Push simplesmente insere o elemento no topo da pilha e, por outro lado, pop remove o elemento do topo da pilha. Para compreender como as pilhas trabalham, imagine adicionar ou remover um prato de uma pilha de pratos sua natureza, instintivamente, sugere que seja removido somente o que está no topo da pilha porque do contrário, existe um perigo de que todos os pratos caiam.

Aqui está um exemplo ilustrando como uma pilha funciona.

n-1...65 Jayz Top4 KC3 Jojo2 Toto1 Kyla0 DMX bottom

Tabela 1: Ilustração da pilha

A pilha está cheia se o topo alcança a célula n-1. Se o topo é igual a n-1, é o indício de que a pilha está cheia.

3.3. Filas

A fila é outro exemplo de TDA. Fila é uma coleção ordenada de elementos o qual prima pela disciplina “primeiro a entrar é o primeiro a sair” (do inglês: “first-in, first-out” - FIFO). As aplicações da fila incluem escalonamento de serviços do sistema operacional, sorteamento topológico e o grafo transversal.

Enfileirar (enqueue) e Desenfileirar (dequeue) são operações associadas com as filas. Enqueue se refere ao modo de inserir no final da fila e, por outro lado, dequeue, o de remover o elemento do início da fila. Para recordar como uma fila trabalha, pense no significado literal de uma fila – uma linha. Suponha uma fila de um banco e estamos esperando para ser atendido. Se uma pessoa chegar ela deverá ficar no final da fila. Caso contrário haveria, provavelmente, algum desentendimento. Essa é a maneira que funciona a inserção (enqueue). Dessa forma, é

Introdução à Programação II 9

Page 291: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

necessário que a primeira pessoa seja atendida para somente depois ser a vez da segunda pessoa da fila, e assim sucessivamente. Essa é a maneira que trabalha a remoção (dequeue).

Aqui está um exemplo de como a fila funciona.

0 1 2 3 4 5 6 7 8 9 ... n-1Eve Jayz KC Jojo Toto Kyla DMXfront end ← Insere

→ Deleta

Tabela 2: Ilustração da fila

A fila está vazia se o final é menor do que o início. Por outro lado, a fila está cheia quando o final é igual a n-1.

3.4. Representação seqüencial e encadeada

TDA podem ser representados usando uma representação seqüencial ou encadeada. É fácil criar uma representação seqüencial com o uso de arrays. Entretanto, o problema com o uso de arrays está no seu limite de tamanho, o qual é fixo. O espaço de memória ou é desperdiçado ou não é o bastante com uso dos arrays. Considere o seguinte cenário. Deve ser criado um array com uma capacidade de armazenar um máximo de 50 elementos. Se o usuário inserir somente 5 elementos, 45 espaços estariam desperdiçados. Por outro lado, se o usuário desejar inserir 51 elementos, o espaço provido pelo array não suportaria.

Comparativamente à representação seqüencial, uma representação encadeada poderia ser ligeiramente mais difícil de se implementar, mas seria muito mais flexível. O encadeamento se adapta à necessidade de memória requerida pelo usuário. Uma explanação mais detalhada da representação encadeada será discutida na sessão a seguir.

Representação seqüencial de uma pilha de inteiros:

public class StackDemo { int top = -1; /* inicialmente, a pilha está vazia */ int memSpace[]; /* armazenamento para inteiros */ int limit; /* tamanho do espaço de memória */

/* Recebe o tamanho inicial da pilha */ public StackDemo(int size) { memSpace = new int[size]; limit = size; } /* Adiciona um elemento */ public boolean push(int value) { top++; if (top < limit) { memSpace[top] = value; } else { top--; return false; } return true; } /* Remove um elemento retornando a quantidade de elementos restantes * public int pop() { int temp = -1; if (top >= 0) {

Introdução à Programação II 10

Page 292: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

temp = memSpace[top]; top--; } else { return -1; } return temp; } public static void main(String args[]) { StackDemo stackDemo = new StackDemo(3); stackDemo.push(1); stackDemo.push(2); stackDemo.push(3); stackDemo.push(4); System.out.println(stackDemo.pop()); System.out.println(stackDemo.pop()); System.out.println(stackDemo.pop()); System.out.println(stackDemo.pop()); }}

A figura a seguir mostra um trecho do método principal de uma pilha seqüencial.

Figura 2: Trecho de uma pilha seqüencial

Introdução à Programação II 11

Page 293: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.5. Lista encadeada

Antes de implementar a representação encadeada de uma pilha, vamos, primeiramente, estudar como criar uma representação encadeada. Em particular, nós devemos olhar para as listas encadeadas.

A lista encadeada é uma estrutura dinâmica, em oposição ao array, que é uma estrutura estática. A grande vantagem da lista encadeada é que a lista pode crescer ou diminuir de tamanho dependendo da necessidade do usuário. Uma lista encadeada é definida como uma coleção de nós, cada qual consiste de um elemento e um encadeamento ou ponteiro para o próximo nó na lista. A figura a seguir mostra como um nó aponta para outro.

Figura 3: Um nó

Aqui está um exemplo de uma lista encadeada não vazia com três nós.

Figura 4: Uma lista encadeada não vazia com três nós

Esta é uma classe que demonstra como implementar um nó. Pode ser usada para criar uma lista encadeada:

class Node { int data; /* dados inteiro contidos em um nó */ Node nextNode; /* o próximo nó da lista */}class NodeDemo { public static void main(String args[]) { Node emptyList = null; /* cria uma lista vazia */ /* Nó cabeça para o primeiro nó da lista */ Node head = new Node(); /* inicializa o primeiro nó da lista */ head.data = 5; head.nextNode = new Node(); head.nextNode.data = 10; /* marca nulo para o final de fila */ head.nextNode.nextNode = null; /* imprime elementos da lista */ Node currNode = head; while (currNode != null) { System.out.println(currNode.data); currNode = currNode.nextNode; } }}

Trecho da execução do método TestNode.

Introdução à Programação II 12

Page 294: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura5: Percurso do nó de teste

Introdução à Programação II 13

Page 295: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.6. Representação encadeada de uma pilha de inteiros

Agora que aprendemos sobre lista encadeada, estamos prontos para implementar uma representação encadeada de uma pilha.

public class DynamicIntStackDemo { private IntStackNode top; /* cabeça ou topo da pilha */ class IntStackNode { /* nó classe */ int data; IntStackNode next; IntStackNode(int n) { data = n; next = null; } } public void push(int n) { /* não há necessidade de verificar se está cheio */ IntStackNode node = new IntStackNode(n); node.next = top; top = node; } public int pop() { /* dispara uma exceção se a lista estiver vazia */ if (isEmpty()) return -1; int n = top.data; top = top.next; return n; } public boolean isEmpty() { return top == null; } public static void main(String args[]) { DynamicIntStackDemo myStack = new DynamicIntStackDemo(); myStack.push(5); myStack.push(10); /* Imprime os elementos da pilha */ IntStackNode currNode = myStack.top; while (currNode!=null) { System.out.println(currNode.data); currNode = currNode.next; } System.out.println(myStack.pop()); System.out.println(myStack.pop()); }}

Aqui está a saída esperada do código acima:

Figura 5: Saída esperada da pilha dinâmica

Introdução à Programação II 14

Page 296: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 6: Trecho da pilha dinâmica

3.7. Java Collections

Introdução à Programação II 15

Page 297: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Os fundamentos dos tipos de dados abstratos mostrados como o básico das listas encadeadas, pilhas e filas. Esses tipos de dados abstratos já estão implementados e incluídos no Java. As classes pilha e lista encadeada estão disponíveis para uso sem exigir um completo entendimento desses conceitos. Entretanto, como cientista da computação, é importante que compreendamos os tipos de dados abstratos. Na verdade, uma explanação detalhada foi dada na sessão anterior. Com a liberação da versão do J2SE 5.0, a interface de Filas (Queue) foi disponibilizada. Para mais detalhes dessas classes e interfaces, por favor, veja a documentação da Java API.

Java provê outras coleções de classes e interfaces, as quais estão disponíveis no pacote java.util. Exemplos de classes Collections incluem LinkedList, ArrayList, HashSet e TreeSet. Essas classes são implementações de diferentes coleções e interfaces. A hierarquia das coleções de interface inicia-se com a interface Collection. Uma Collection é apenas um grupo de objetos que são conhecidos e seus elementos. Coleções podem permitir duplicidades e não exigir uma ordem específica.

O SDK não provê nenhuma implementação dessas interfaces, mas sub-interfaces diretas, a interface Set e a interface List estão disponíveis. Agora, qual é a diferença entre essas duas interfaces? Um Set é uma coleção não ordenada que não contém duplicidade. Por outro lado, um List é uma coleção ordenada de elementos onde duplicidades são permitidas. HashSet, LinkedHashSet e TreeSet são algumas implementações de classes conhecidas da interface Set. ArrayList, LinkedList e Vector são algumas implementações de classes conhecidas da interface List.

<Interface Raiz>Collection

<interface>Set

<interface>List

<Implementada pelas classes> <Implementada pelas classes>HashSet LinkedHashSet TreeSet ArrayList LinkedList Vector

Tabela 3: Java collections

A seguir está uma lista dos métodos de uma coleção providas na API Collections do Java 2 Platform SE v1.4.1. Em Java 2 Platform SE v1.5.0, esses métodos foram modificados para acomodar tipos genéricos. Tipos genéricos não serão discutidos ainda. É aconselhável considerar esses métodos primeiramente. Recomendo que os novos métodos da coleção sejam consultados uma vez que compreenda os tipos genéricos, os quais são discutidos no próximo capítulo.

Métodos da Collection

public boolean add(Object o)Insere o objeto enviado como argumento na coleção. Retorna verdadeiro se o objeto foi adicionado com sucesso.

public void clear()Remove todos os elementos da coleção.

public boolean remove(Object o)Remove o objeto enviado como argumento na coleção. Retorna verdadeiro se o objeto se o objeto foi encontrado e removido com sucesso.

public boolean contains(Object o)Retorna verdadeiro se a coleção contém o objeto enviado no argumento.

public boolean isEmpty()Retorna verdadeiro se a coleção estiver vazia.

public int size()

Introdução à Programação II 16

Page 298: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Retorna o número de elementos na coleção.

public Iterator iterator()Retorna um objeto do tipo Iterator que permite percorrer os elementos da coleção.

Tabela 4: Métodos da classe Collection

Por favor, consulte a documentação da API para uma lista mais completa dos métodos encontrados nas interfaces Collection, List e Set.

Java SDK apresenta diversas formas de implementação de uma lista encadeada. A classe LinkedList contém métodos que permitem que listas encadeadas sejam usadas como pilhas, filas ou algum outro TDA. O código a seguir mostra como usar a classe LinkedList.

import java.util.*;

class LinkedListDemo { public static void main(String args[]) { LinkedList list = new LinkedList(); list.add(new Integer(1)); list.add(new Integer(2)); list.add(new Integer(3)); list.add(new Integer(1)); System.out.println(list + ", size = " + list.size()); list.addFirst(new Integer(0)); list.addLast(new Integer(4)); System.out.println(list); System.out.println(list.getFirst() + ", " + list.getLast()); System.out.println(list.get(2) + ", " + list.get(3)); list.removeFirst(); list.removeLast(); System.out.println(list); list.remove(new Integer(1)); System.out.println(list); list.remove(2); System.out.println(list); }}

O ArrayList é uma versão redimensionável de um array. Ela implementa a interface List. Analise o código a seguir.

import java.util.*;

class ArrayListDemo { public static void main(String args[]) { ArrayList al = new ArrayList(2); System.out.println(al + ", size = " + al.size()); al.add("R"); al.add("U"); al.add("O"); System.out.println(al + ", size = " + al.size()); al.remove("U"); System.out.println(al + ", size = " + al.size()); ListIterator li = al.listIterator(); while (li.hasNext()) System.out.println(li.next()); Object a[] = al.toArray(); for (int i=0; i<a.length; i++) System.out.println(a[i]); }

Introdução à Programação II 17

Page 299: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}

O HashSet é um tipo de implementação da interface Set que usa uma tabela hash. O uso de uma tabela hash permite buscar os elementos de forma fácil e rápida. A tabela usa uma fórmula que determina onde um objeto está armazenado. HashSet foi utilizado na seguinte classe:

import java.util.*;

class HashSetDemo { public static void main(String args[]) { HashSet hs = new HashSet(5); System.out.println(hs.add("one")); System.out.println(hs.add("two")); System.out.println(hs.add("one")); System.out.println(hs.add("three")); System.out.println(hs.add("four")); System.out.println(hs.add("five")); System.out.println(hs); }}

O TreeSet é uma implementação da interface Set que usa uma árvore. Esta classe assegura que o conjunto será organizado em uma ordem ascendente. Observe como a classe TreeSet foi usada no seguinte código fonte.

import java.util.*;

class TreeSetDemo { public static void main(String args[]) { TreeSet ts = new TreeSet(); ts.add("one"); ts.add("two"); ts.add("three"); ts.add("four"); System.out.println(ts); }}

Figura 7: Exemplo de um TreeSet

Introdução à Programação II 18

Page 300: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 4Passeio pelo pacote java.lang

Versão 1.0 - Mar/2007

Page 301: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Java possui muitas classes úteis para serem utilizadas. Nesta lição iremos explorá-las.

Ao final desta lição, o estudante será capaz de:

• Entender e utilizar as seguintes classes disponíveis:

• Classe Math

• Classe String

• Classe StringBuffer

• Classes Wrapper

• Classe Process

• Classe System

Introdução à Programação II 4

Page 302: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Classe MathJava possui constantes pré-definidas e métodos para executar diferentes operações matemáticas, como, por exemplo, funções trigonométricas e logarítmicas. Como estes métodos são todos static, podemos utilizá-los sem a necessidade de construir um objeto da classe Math. Pode-se obter uma lista completa destas constantes e métodos na documentação da API Java. Aqui estão descritos alguns dos métodos mais utilizados:

Métodos da classe Mathpublic static double abs(double a) Retorna o valor positivo do argumento a passado para o método. É um método overloaded. Pode receber como argumento um float, um integer ou um long integer, e nestes casos, o tipo de retorno será float, integer ou long integer, respectivamente.public static double random() Retorna um valor positivo randômico maior ou igual a 0.0 mas menor que 1.0.public static double max(double a, double b) Retorna o maior valor entre dois valores, a e b, do tipo double. É um método overloaded. Pode receber como argumento um float, integer ou long integer, e nestes casos, o tipo de retorno será float, integer ou um long integer, respectivamente.public static double min(double a, double b) Retorna o menor entre dois valores a e b, do tipo double. É um método overloaded. Pode receber também valores dos tipos float, integer ou long integer como argumentos, e nestes casos, o tipo de retorno será serão float, integer ou long integer, respectivamente.public static double ceil(double a) Retorna o menor inteiro maior ou igual ao argumento a passado para o método.public static double floor(double a) Retorna o maior inteiro menor ou igual ao argumento a passado para o método.public static double exp(double a) Retorna o número de Euler "e" elevado à potência informada no argumento a passado para o método.public static double log(double a) Retorna o logarítmico natural (base e) de a, o argumento do tipo double informado.public static double pow(double a, double b) Retorna o valor do tipo double de a elevado à potência b, do tipo double. a(base) e b(potência) são os argumentos para este método. public static long round(double a) Retorna o valor do tipo long mais próximo do argumento a, do tipo double, informado. É um método overloaded. Também pode receber um argumento do tipo float e neste caso, retorna o valor do tipo int mais próximo.public static double sqrt(double a) Retorna a raiz quadrada do argumento a informado.public static double sin(double a) Retorna o seno trigonométrico de um dado ângulo a, argumento deste método.public static double toDegrees(double angrad) Retorna o valor aproximado em graus, equivalente ao valor em radianos passado no argumento.public static double toRadians(double angdeg) Retorna o valor aproximado em radianos, equivalente ao valor em graus passado no argumento.

Tabela 1: Alguns métodos da classe Math

A seguinte classe demonstra como estes métodos são usados:

class MathDemo { public static void main(String args[]) { System.out.println("absolute value of -5: " + Math.abs(-5)); System.out.println("absolute value of 5: " +

Introdução à Programação II 5

Page 303: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Math.abs(-5)); System.out.println("random number(max value is 10): " + Math.random()*10); System.out.println("max of 3.5 and 1.2: " + Math.max(3.5, 1.2)); System.out.println("min of 3.5 and 1.2: " + Math.min(3.5, 1.2)); System.out.println("ceiling of 3.5: " + Math.ceil(3.5)); System.out.println("floor of 3.5: " + Math.floor(3.5)); System.out.println("e raised to 1: " + Math.exp(1)); System.out.println("log 10: " + Math.log(10)); System.out.println("10 raised to 3: " + Math.pow(10,3)); System.out.println("rounded off value of pi: " + Math.round(Math.PI)); System.out.println("square root of 5 = " + Math.sqrt(5)); System.out.println("10 radian = " + Math.toDegrees(10) + " degrees"); System.out.println("sin(90): " + Math.sin(Math.toRadians(90))); }}

Esta é a saída desta classe. Sinta-se livre para experimentar com novos argumentos.

absolute value of -5: 5absolute value of 5: 5random number(max value is 10): 4.0855332335477605max of 3.5 and 1.2: 3.5min of 3.5 and 1.2: 1.2ceiling of 3.5: 4.0floor of 3.5: 3.0e raised to 1: 2.7182818284590455log 10: 2.30258509299404610 raised to 3: 1000.0rounded off value of pi: 3square root of 5 = 2.2360679774997910 radian = 572.9577951308232 degreessin(90): 1.0

Introdução à Programação II 6

Page 304: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Classes String e StringBuffer

3.1. Classe String

A Classe String que encontramos no Java SDK representa combinações de caracteres literais. Diferente de outras linguagens de programação como C ou C++, strings podem ser representadas utilizando-se um array de caracteres ou simplesmente a Classe String. Tenha em mente que um objeto String é diferente de um array de caracteres.

3.2. Construtores de String

A Classe String possui 12 construtores com as seguintes assinaturas:

public String(byte [] bytes)public String(byte [] ascii, int hibyte)public String(byte [] bytes, int offset, int length)public String(byte [] ascii, int hibyte, int offset, int length)public String(byte [] byteslength, String charsetName)public String(byte [] bytes, String charsetName)public String(char [] value)public String(char [] value, int offset, int count)public String(int [] codePoints, int offset, int count)public String(String original)public String(StringBuffer buffer)public String(StringBuilder builder)

Para conhecermos alguns destes construtores, considere a classe abaixo:

class StringConstructorsDemo { public static void main(String args[]) { String s1 = new String(); // cria uma String vazia char chars[] = { 'h', 'e', 'l', 'l', 'o'}; String s2 = new String(chars); // s2 = "hello"; byte bytes[] = { 'w', 'o', 'r', 'l', 'd' }; String s3 = new String(bytes); // s3 = "world" String s4 = new String(chars, 1, 3); String s5 = new String(s2); String s6 = s2; System.out.println(s1); System.out.println(s2); System.out.println(s3); System.out.println(s4); System.out.println(s5); System.out.println(s6); }}

A execução desta classe mostrará o seguinte resultado:

helloworldellhellohello

Introdução à Programação II 7

Page 305: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.3. Métodos da Classe String

A seguir, uma lista de alguns métodos de String.

Métodos da classe String

public char charAt(int index)Retorna o caracter localizado na posição especificada pelo argumento index, que indica a posição do caracter no array de caracteres representado.

public int compareTo(String anotherString)Compara uma string com outra string especificada no argumento. Retorna um valor negativo se a string possuir um valor léxico menor que a string passada como argumento, 0 se ambas as strings tiverem o mesmo valor léxico e um valor positivo se a string tiver um valor léxico superior ao da string passada como argumento do método.

public int compareToIgnoreCase(String str)Funciona como o método compareTo ignorando o padrão case sensitive de Java, isto é, maiúsculas e minúsculas são indiferentes, apresentando o mesmo valor léxico.

public boolean equals(Object anObject)Retorna verdadeiro se a string possuir a mesma seqüência de caracteres do argumento Object passado para este método, argumento este que deve ser um objeto do tipo String. De outra maneira, se for passado um argumento que não seja do tipo String ou se não tiver a mesma sequência de símbolos da string, o método irá retornar false.

public boolean equalsIgnoreCase(String anotherString)Funciona como o método equals ignorando o padrão case sensitive de Java, isto é, maiúsculas e minúsculas são indiferentes, apresentando o mesmo valor léxico.

public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)Obtém os caracteres do array de caracteres da string compreendidos no intervalo definido pelos argumentos srcBegin (na posição do primeiro caracter no array) e srcEnd (na posição do último caracter no array) copiando estes caracteres para o array dst iniciando na posição dstBegin.

public int length()Retorna o comprimento da string.

public String replace(char oldChar, char newChar)Retorna a string substituindo todas as ocorrências de oldChar nesta string por newChar.

public String substring(int beginIndex, int endIndex)Retorna a substring da string iniciando na posição especificada no argumento beginIndex até a posição especificada no argumento endIndex.

public char[] toCharArray()Retorna o array de caracteres da string.

public String trim()Retorna a string suprimindo todos os seus espaços em branco.

public static String valueOf(-)Este método recebe um argumento de tipo simples como boolean, integer ou character, ou ainda um Object e retorna a String equivalente ao argumento passado para o método.

Tabela 2: Alguns métodos da classe String

Introdução à Programação II 8

Page 306: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Observe como estes métodos são utilizados na seguinte classe:

class StringDemo { public static void main(String args[]) { String name = "Jonathan"; System.out.println("name: " + name); System.out.println("3rd character of name: " + name.charAt(2)); System.out.println("Jonathan compared to Solomon: " + name.compareTo("Solomon")); System.out.println("Solomon compared to Jonathan: " + "Solomon".compareTo("Jonathan")); System.out.println("Jonathan compared to jonathan: " + name.compareTo("jonathan")); System.out.println("Jonathan compared to jonathan (ignore " + "case): " + name.compareToIgnoreCase("jonathan")); System.out.println("Is Jonathan equal to Jonathan? " + name.equals("Jonathan")); System.out.println("Is Jonathan equal to jonathan? " + name.equals("jonathan")); System.out.println("Is Jonathan equal to jonathan (ignore " + "case)? " + name.equalsIgnoreCase("jonathan")); char charArr[] = "Hi XX".toCharArray(); "Jonathan".getChars(0, 2, charArr, 3); System.out.print("content of charArr after getChars method: "); System.out.println(charArr); System.out.println("Length of name: " + name.length()); System.out.println("Replace a's with e's in name: " + name.replace('a', 'e')); System.out.println("A substring of name: " + name.substring(0, 2)); System.out.println("Trim \" a b c d e f \": \"" + " a b c d e f ".trim() + "\""); System.out.println("String representation of boolean " + "expression 10>10: " + String.valueOf(10>10)); System.out.println("String representation of boolean " + "expression 10<10: " + (10<10)); System.out.println("name: " + name); }}

A execução desta classe mostrará o seguinte resultado:

name: Jonathan3rd character of name: nJonathan compared to Solomon: -9Solomon compared to Jonathan: 9Jonathan compared to jonathan: -32Jonathan compared to jonathan (ignore case): 0Is Jonathan equal to Jonathan? trueIs Jonathan equal to jonathan? falseIs Jonathan equal to jonathan (ignore case)? truecontent of charArr after getChars method: Hi JoLength of name: 8Replace a's with e's in name: JonethenA substring of name: JoTrim " a b c d e f ": "a b c d e f"String representation of boolean expression 10>10: falseString representation of boolean expression 10<10: falsename: Jonathan

Introdução à Programação II 9

Page 307: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.4. Classe StringBuffer

Uma vez que um objeto do tipo String foi criado, não pode mais ser modificado. Um objeto StringBuffer é similar a um objeto String, exceto pelo fato que o objeto StringBuffer é mutável, ou seja, pode ser modificado. Reforçando: um objeto String é imutável, objetos StringBuffer são mutáveis. Seus comprimentos e conteúdos podem ser modificados por meio da chamada de alguns métodos. Aqui estão alguns dos métodos da Classe StringBuffer. Para maiores informações consulte a documentação da API Java.

Métodos da classe StringBuffer

public int capacity()Retorna a capacidade atual do objeto StringBuffer.

public StringBuffer append(-)Anexa a representação em string do argumento passado para o método ao objeto StringBuffer. O argumento passado para este método pode ser de um dos seguintes tipos: boolean, char, char [], double, float, int, long, Object, String and StringBuffer. Possui outras versões overloaded.

public char charAt(int index)Retorna o caracter localizado na posição especificada no argumento index.

public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)Obtém os caracteres do objeto compreendidos no intervalo definido entre a posição definida pelo argumento srcBegin e a posição definida pelo argumento srcEnd e copia estes caracteres para o array definido pelo argumento dst iniciando na posição dstBegin.

public StringBuffer delete(int start, int end) Exclui os caracteres dentro do intervalo especificado.

public StringBuffer insert(int offset, -) Insere a representação em string do segundo argumento na posição especificada pelo argumento offset. É um método overloaded. São tipos possíveis para o segundo argumento: boolean, char, char [], double, float, int, long, Object and String. Ainda possui outras versões overloaded.

public int length()Retorna o número de caracteres no objeto StringBuffer.

public StringBuffer replace(int start, int end, String str) Substitui os caracteres do objeto StringBuffer compeendidos no intervalo definido pelos dois primeiros argumentos (start e end) pelos caracteres do terceiro argumento (str).

public String substring(int start, int end)Retorna a substring do objeto iniciando na posição definida pelo argumento start e terminando na posição definida pelo argumento end.

public String toString()Converte o objeto StringBuffer para String.

Tabela 3: Alguns métodos da classe StringBuffer

A seguinte classe demonstra o uso destes métodos:

class StringBufferDemo { public static void main(String args[]) {

Introdução à Programação II 10

Page 308: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

StringBuffer sb = new StringBuffer("Jonathan"); System.out.println("sb = " + sb); System.out.println("capacity of sb: " + sb.capacity()); System.out.println("append \'O\' to sb: " + sb.append("O")); System.out.println("sb = " + sb); System.out.println("3rd character of sb: " + sb.charAt(2)); char charArr[] = "Hi XX".toCharArray(); sb.getChars(0, 2, charArr, 3); System.out.print("getChars method: "); System.out.println(charArr); System.out.println("Insert \'jo\' at the 3rd cell: " + sb.insert(2, "jo")); System.out.println("Delete \'jo\' at the 3rd cell: " + sb.delete(2,4)); System.out.println("length of sb: " + sb.length()); System.out.println("replace: " + sb.replace(3, 9, " Ong")); System.out.println("substring (1st three characters): " + sb.substring(0, 3)); System.out.println("implicit toString(): " + sb); }}

A execução desta classe mostrará o seguinte resultado:

sb = Jonathancapacity of sb: 24append 'O' to sb: JonathanOsb = JonathanO3rd character of sb: ngetChars method: Hi JoInsert 'jo' at the 3rd cell: JojonathanODelete 'jo' at the 3rd cell: JonathanOlength of sb: 9replace: Jon Ongsubstring (1st three characters): Jonimplicit toString(): Jon Ong

Sinta-se à vontade para experimentar esta classe modificando os argumentos, a melhor forma de aprender é através da prática.

3.5. Mutabilidade

Falamos de mutabilidade de objetos e foi dito que um objeto da classe String não pode ter o seu valor modificado, entretanto observaremos as seguintes instruções:

String objString = new String("Hello");objString = objString.concat(" World!!!");System.out.println(objString);

Teremos como resultado o texto Hello World!!!, então significa que o objeto da classe String foi modificado certo? Errado, ocorreu na segunda instrução a destruição e a recriação do objeto. Analisaremos a seguinte classe:

class MutabilityDemo { public static void main(String args[]) { String objString = new String("Hello"); System.out.println(objString + " : " + objString.hashCode());

Introdução à Programação II 11

Page 309: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

objString = objString.concat(" World!!"); System.out.println(objString + " : " + objString.hashCode()); StringBuffer objStringBuffer = new StringBuffer("Hello"); System.out.println(objStringBuffer + " : " + objStringBuffer.hashCode()); objStringBuffer = objStringBuffer.append(" World!!"); System.out.println(objStringBuffer + " : " + objStringBuffer.hashCode()); }}

E teremos como resultado da execução desta:

Hello : 69609650Hello World!! : 22678948Hello : 17523401Hello World!! : 17523401

O método hashCode() gera automaticamente um OID (ObjectID) único para cada objeto criado, observe que no caso do objeto da classe String este número mudou, ou seja, foi criado um novo objeto, e no caso do objeto da classe StringBuffer este número permanece o mesmo, demonstrando assim a imutabilidade deste.

Introdução à Programação II 12

Page 310: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Classes WrapperObviamente, os tipos primitivos como int, char e long não são objetos. Desta forma, variáveis destes tipos não podem acessar métodos da classe Object. Somente objetos reais, que são declarados para serem referenciados como tipos de dados, podem acessar métodos da classe Object. Todavia, existem casos em que você precisará de uma representação em objeto de variáveis de tipos primitivos para usar métodos internos de Java. Por exemplo, você pode querer adicionar variáveis de tipo primitivo em uma Collection de objetos. É aqui que a classe wrapper entra. Classes wrapper são, simplesmente, representações em objetos de variáveis que não são objetos, como as de tipos primitivos. Aqui está uma lista de classes wrapper:

Tipos Primitivos de Dados Classes Wrapper Correspondentes

boolean Boolean

char Character

byte Byte

short Short

int Integer

long Long

float Float

double Double

Tabela 4: Tipos de dados primitivos e suas classes wrapper correspondentes

Os nomes das diferentes classes wrapper são fáceis de lembrar, porque são muito similares aos tipos de dados primitivos que representam. Note também que as classes wrapper iniciam com letra maiúscula, comparando-as com os tipos primitivos.

Aqui está um exemplo do uso da classe wrapper para o tipo primitivo boolean.

class BooleanWrapperDemo { public static void main(String args[]) { boolean booleanVar = 1>2; Boolean booleanObj = new Boolean("TRue"); Boolean booleanObj2 = new Boolean(booleanVar); System.out.println("booleanVar = " + booleanVar); System.out.println("booleanObj = " + booleanObj); System.out.println("booleanObj2 = " + booleanObj2); System.out.println("compare 2 wrapper objects: " + booleanObj.equals(booleanObj2)); booleanVar = booleanObj.booleanValue(); System.out.println("booleanVar = " + booleanVar); }}

A execução desta classe mostrará o seguinte resultado:

booleanVar = falsebooleanObj = truebooleanObj2 = falsecompare 2 wrapper objects: falsebooleanVar = true

Introdução à Programação II 13

Page 311: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Classes Process e Runtime

5.1. Classe Process

A classe Process define métodos para manipulação de processos que podem, por exemplo, terminar a execução de um processo, iniciar a execução de processos e verificar o status de processos. Esta classe representa as instruções quando são executadas. Aqui estão alguns métodos desta classe:

Métodos da classe Process

public abstract void destroy() Finaliza os processos em execução.

public abstract int waitFor() throws InterruptedExceptionNão sai até que o processo termine.

Tabela 5: Alguns métodos da classe Process

5.2. Classe Runtime

Enquanto a classe Process representa os processos em execução, a classe Runtime representa o ambiente de execução. Dois métodos importantes desta classe são: getRuntime e exec.

Métodos da classe Runtime

public static Runtime getRuntime() Retorna o ambiente de execução associado a aplicação Java atual.

public Process exec(String command) throws IOExceptionExecuta o comando passado como argumento em command. Permite-lhe executar novos processos.

Tabela 6: Alguns métodos da classe RunTime

5.3. Abrindo o Editor de Registro

Esta classe abre o editor de registro sem que seja necessário, explicitamente, digitar o comando na linha de comando:

class RuntimeDemo { public static void main(String args[]) { Runtime rt = Runtime.getRuntime(); Process proc; try { proc = rt.exec("regedit"); proc.waitFor(); } catch (Exception e) { System.out.println("regedit is an unknown command."); } }}

A execução desta classe mostrará o seguinte resultado:

Introdução à Programação II 14

Page 312: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 1: O editor de registro aberto

Introdução à Programação II 15

Page 313: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Classe SystemA classe System oferece muitos atributos e métodos úteis como a entrada padrão (input), a saída padrão (output) e um método utilitário para copiar rapidamente partes de um array. Aqui estão alguns métodos interessantes desta classe. Note que todos os métodos dessa classe são static.

Métodos da classe System

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) Copia os ítens do array src, passado como argumento para o método, especificados no argumento length iniciando na posição especificada no argumento srcPos para o array dest, terminando na posição especificada no argumento destPos. É mais rápido do que utilizar um algoritmo próprio para realizar a cópia.

public static long currentTimeMillis() Retorna a diferença entre o tempo atual (data/hora) e 1º de Janeiro de 1970 (UTC). O valor de retorno se dá em milissegundos.

public static void exit(int status) Termina a execução da Máquina Virtual Java (JVM) atual. Um valor diferente de zero para o status, por convenção, indica uma saída anormal.

public static void gc() Executa o garbage collector, que irá liberar espaços em memória que não estão mais sendo utilizados.

public static void setIn(InputStream in) Troca o stream associado a System.in, que por padrão, refere-se ao teclado.

public static void setOut(PrintStream out) Troca o stream associado a System.out, que por padrão, refere-se ao console (tela).

Tabela 7: Alguns metodos da classe System

Aqui está uma demonstração do uso de alguns destes métodos:

import java.io.*;

class SystemDemo { public static void main(String args[]) throws IOException { long startTime, endTime; System.setOut(new PrintStream("C:/tempOut.txt")); int arr1[] = new int[5000000]; int arr2[] = new int[5000000]; for (int i = 0; i < arr1.length; i++) { arr1[i] = i + 1; } startTime = System.currentTimeMillis(); for (int i = 0; i < arr1.length; i++) { arr2[i] = arr1[i]; } endTime = System.currentTimeMillis(); System.out.println("Manual: " + (endTime-startTime) + " ms."); startTime = System.currentTimeMillis(); System.arraycopy(arr1, 0, arr2, 0, arr1.length); endTime = System.currentTimeMillis(); System.out.println("Automatic: " + (endTime-startTime) + " ms."); }}

Introdução à Programação II 16

Page 314: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A execução desta classe pode variar. O resultado contido no arquivo em C:\tempOut.txt, pode ser por exemplo:

Manual: 47 ms.Automatic: 31 ms.

Introdução à Programação II 17

Page 315: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 5Aplicações Textuais

Versão 1.0 - Mar/2007

Page 316: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Nesta lição, será mostrada uma revisão sobre como utilizar os argumentos de linha de comando. Além disso, serão mostradas mais informações sobre como utilizar fluxos de dados para obter entrada do usuário durante a execução da sua aplicação para manipular arquivos.

Ao final desta lição, o estudante será capaz de:

• Obter entrada através da linha de comando• Explicar como manipular propriedades do sistema• Ler através da entrada padrão• Ler e escrever em arquivos

Introdução à Programação II 4

Page 317: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Argumentos de Linha de Comando e Propriedades do Sistema

Como foi visto no módulo anterior, Java permite ao usuário enviar dados na linha de comando para a classe que está sendo executada. Por exemplo, passar os argumentos 1 e 2 para uma classe nomeada como Calculate, pode-se digitar a seguinte linha de comando:

java Calculate 1 2

Neste exemplo, o valor 1 é armazenado na posição args[0] do argumento args, enquanto que o valor 2 é armazenado na posição args[1] do argumento args. Deste modo, a finalidade de declarar "String args[]" como um argumento no método main fica clara.

Estes são os passos para passar argumentos na linha de comando no NetBeans:

1. Procurar o nome do projeto no painel dos projetos à esquerda2. Clicar com o botão direito do mouse sobre o nome ou o ícone do projeto3. Selecionar a opção Properties4. Clicar em Run no painel de Categories à esquerda5. Entrar os argumentos separados por espaço no campo texto do item Arguments:6. Clicar no botão OK7. Compilar e executar a classe.

Para compreender mais facilmente estas etapas, observe as imagens a seguir.

Figura 1: Passando Argumentos na Linha de Comando com o NetBeans – Passos 1 e 2

Introdução à Programação II 5

Page 318: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 2: Passando Argumentos na Linha de Comando com o NetBeans - Passo 3

Figura 3: Passando Argumentos na Linha de Comando com o NetBeans – Passo 4

Além de passar argumentos ao método main, também é possível manipular propriedades do sistema a partir da linha de comando.

Propriedades de sistema são bastante semelhantes às variáveis de ambiente. Porém, não são

Introdução à Programação II 6

Page 319: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

dependentes de plataforma. Uma propriedade é simplesmente um mapeamento entre o nome da propriedade e o seu valor correspondente. Isto é representado em Java com a classe Properties. A classe System provê alguns métodos para determinar as propriedades correntes do sistema, o método getProperties retorna um objeto do tipo Properties. O método getProperty possui duas formas:

public static String getProperty(String key) Esta versão retorna o valor de uma propriedade do sistema, indicada pela chave especificada. Retorna nulo se não houver nenhuma propriedade com a chave especificada.

public static String getProperty(String key, String def) Esta versão retorna também o valor de uma propriedade do sistema, indicada pela chave especificada. Retorna def, valor padrão, se não houver nenhuma propriedade com a chave especificada.

Tabela 1: método getProperty() da classe System

Não enfatizaremos os detalhes das propriedades do sistema. Iremos manipular diretamente as propriedades do sistema.

É possível utilizar a opção -D, como argumento da linha de comando Java, para incluir uma nova propriedade.

java -D<name>=value

Por exemplo, na propriedade de sistema user.home iremos inserir o valor philippines, vamos digitar o seguinte comando:

java -Duser.home=philippines

Para exibir a lista de propriedades do sistema disponíveis e seus valores correspondentes, deve-se utilizar o método getProperties, como segue:

System.getProperties().list(System.out);

Aqui temos uma amostra da lista de propriedades do sistema:

-- listing properties --java.runtime.name=Java(TM) 2 Runtime Environment, Stand...sun.boot.library.path=C:\Program Files\Java\jdk1.5.0_06\jre...java.vm.version=1.5.0_06-b05java.vm.vendor=Sun Microsystems Inc.java.vendor.url=http://java.sun.com/path.separator=;java.vm.name=Java HotSpot(TM) Client VMfile.encoding.pkg=sun.iouser.country=USsun.os.patch.level=Service Pack 2java.vm.specification.name=Java Virtual Machine Specificationuser.dir=C:\Documents and Settings\becca\Neste...java.runtime.version=1.5.0_06-b05java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironmentjava.endorsed.dirs=C:\Program Files\Java\jdk1.5.0_06\jre...os.arch=x86java.io.tmpdir=C:\DOCUME~1\becca\LOCALS~1\Temp\line.separator=java.vm.specification.vendor=Sun Microsystems Inc.user.variant=

Introdução à Programação II 7

Page 320: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

os.name=Windows XPsun.jnu.encoding=Cp1252java.library.path=C:\Program Files\Java\jdk1.5.0_06\jre...java.specification.name=Java Platform API Specificationjava.class.version=49.0sun.management.compiler=HotSpot Client Compileros.version=5.1user.home=C:\Documents and Settings\beccauser.timezone=java.awt.printerjob=sun.awt.windows.WPrinterJobfile.encoding=Cp1252java.specification.version=1.5user.name=beccajava.class.path=C:\Documents and Settings\becca\Neste...java.vm.specification.version=1.0sun.arch.data.model=32java.home=C:\Program Files\Java\jdk1.5.0_06\jrejava.specification.vendor=Sun Microsystems Inc.user.language=enawt.toolkit=sun.awt.windows.WToolkitjava.vm.info=mixed mode, sharingjava.version=1.5.0_06java.ext.dirs=C:\Program Files\Java\jdk1.5.0_06\jre...sun.boot.class.path=C:\Program Files\Java\jdk1.5.0_06\jre...java.vendor=Sun Microsystems Inc.file.separator=\java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...sun.cpu.endian=littlesun.io.unicode.encoding=UnicodeLittlesun.desktop=windowssun.cpu.isalist=

Introdução à Programação II 8

Page 321: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Lendo da Entrada Padrão

Ao invés de obter uma entrada do usuário através da linha de comando, a maioria dos usuários prefere entrar com os dados quando requisitados pela classe enquanto ela estiver em execução. Um modo de realizar isto é com o uso dos fluxos. Um fluxo é uma abstração de um arquivo ou de um dispositivo que permite ler ou escrever uma série de itens. Eles são conectados com dispositivos físicos, tais como: teclados, consoles e arquivos. Há dois tipos gerais de fluxo de dados: fluxo de bytes e fluxo de caracteres. Os fluxos de bytes são para os dados binários, enquanto os fluxos de caracteres são para os caracteres Unicode. System.in e System.out são dois exemplos de objetos de fluxos de bytes pré-definidos em Java. O primeiro, por padrão, refere-se ao teclado e o último, ao monitor.

Para ler caracteres do teclado, utilize o System.in, que é um fluxo de bytes traduzido em um objeto do tipo BufferedReader. A linha seguinte mostra como realizar isto:

BufferedReader br = new BufferedReader( new InputStreamReader(System.in));

O método read do objeto do tipo BufferedReader é utilizado para ler do dispositivo de entrada.

ch = (int)br.read(); // método read retorna um inteiro

Vejamos esta classe como exemplo:

import java.io.*;

class FavoriteCharacter { public static void main(String args[]) throws IOException { System.out.println("Hi, what's your favorite character?"); char favChar; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); favChar = (char) br.read(); System.out.println(favChar + " is a good choice!"); }}

Executando esta classe e informando o caractere "a" como entrada, obteremos a seguinte saída:

Hi, what's your favorite character?aa is a good choice!

Para ler uma linha inteira, em vez de um caractere de cada vez, é possível utilizar o método readLine.

str = br.readLine();

Vejamos uma classe similar ao exemplo anterior. Esta classe lê uma linha inteira em vez de um único caractere.

import java.io.*;

class GreetUser { public static void main(String args[]) throws IOException { System.out.println("Hi, what's your name?"); String name; BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

Introdução à Programação II 9

Page 322: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

name = br.readLine(); System.out.println("Nice to meet you, " + name + "! :)"); }}

A saída esperada da classe GreetUser, quando o usuário entrar com a palavra Rebecca é:

Hi, what's your name?RebeccaNice to meet you, Rebecca! :)

Ao utilizar fluxos, não esqueça de importar o pacote java.io como mostrado:

import java.io.*;

Ao ler fluxos é possível que ocorram exceções. Não se deve esquecer de tratar estas exceções usando o bloco try-catch ou de indicá-las na cláusula throws do método.

Introdução à Programação II 10

Page 323: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Manipulação de Arquivo

Em alguns casos, as entradas de dados são armazenadas nos arquivos. Além disso, há também situações na qual queremos armazenar a saída de uma determinada classe para um arquivo.

Em um sistema informatizado de matrícula, os dados do estudante que podem ser utilizados como uma entrada para o sistema são, provavelmente, armazenados em um arquivo. Então, uma possível saída do sistema é a informação sobre os assuntos registrados pelos estudantes. Outra vez, a saída, neste caso, pode ser armazenada em um arquivo. Como visto nesta aplicação, há necessidade de ler e escrever em um arquivo. Aprenderemos sobre entrada e saída de arquivo ainda nesta seção.

4.1. Lendo um Arquivo

Para ler um arquivo, pode-se utilizar a classe FileInputStream. Este é um dos construtores desta classe:

FileInputStream(String filename)

O construtor cria uma conexão para um arquivo real, cujo o nome será especificado como um argumento. Uma exceção do tipo FileNotFoundException é lançada quando o arquivo não existe ou não pode ser aberto para leitura.

Após ter criado um fluxo de entrada, é possível utilizá-lo para ler um arquivo associado através do método read que retorna um valor do tipo inteiro e o valor -1 quando o fim do arquivo for encontrado.

Aqui está um exemplo:

import java.io.*;

class ReadFile { public static void main(String args[]) throws IOException { System.out.println( "What is the name of the file to read from?"); String filename; BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); filename = br.readLine(); System.out.println( "Now reading from " + filename + "..."); FileInputStream fis = null; try { fis = new FileInputStream(filename); } catch (FileNotFoundException ex) { System.out.println("File not found."); } char data; int temp; do { temp = fis.read(); data = (char) temp; if (temp != -1) System.out.print(data); } while (temp != -1); System.out.println("Problem in reading from the file."); }}

Introdução à Programação II 11

Page 324: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Assumindo que temp.txt existe e seja o arquivo de texto, está é uma possível saída desta classe:

What is the name of the file to read from?temp.txtNow reading from temp.txt...temporary file

4.2. Escrevendo em um Arquivo

Para escrever em um arquivo, é possível utilizar a classe FileOutputStream. Este é um dos construtores desta classe:

FileOutputStream(String filename)

O construtor vincula um fluxo de saída a um arquivo real para escrita. Uma exceção do tipo FileNotFoundException é lançada quando o arquivo não puder ser aberto para escrita.

Uma vez que o fluxo de saída é criado, pode-se utilizá-lo para escrever no arquivo vinculado através do método write, que possui a seguinte assinatura:

void write(int b)

O argumento b refere-se ao dado a ser escrito para o arquivo real, associado ao fluxo de saída.

A classe seguinte demonstra a escrita em um arquivo:

import java.io.*;

class WriteFile { public static void main(String args[]) throws IOException { System.out.println( "What is the name of the file to be written to?"); String filename; BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); filename = br.readLine(); System.out.println( "Enter data to write to " + filename + "..."); System.out.println("Type q$ to end."); FileOutputStream fos = null; try { fos = new FileOutputStream(filename); } catch (FileNotFoundException ex) { System.out.println("File cannot be opened for writing."); } try { boolean done = false; int data; do { data = br.read(); if ((char)data == 'q') { data = br.read(); if ((char)data == '$') { done = true; } else { fos.write('q'); fos.write(data); } } else {

Introdução à Programação II 12

Page 325: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

fos.write(data); } } while (!done); } catch (IOException ex) { System.out.println("Problem in reading from the file."); } }}

Exemplo de execução da classe WriteFile:

What is the name of the file to be written to?temp.txtEnter data to write to temp.txt...Type q$ to end.what a wonderful world1, 2, stepq$

O arquivo temp.txt deverá conter os seguintes dados:

what a wonderful world1, 2, step

Introdução à Programação II 13

Page 326: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 6Algoritmos de Ordenação

Versão 1.0 - Mar/2007

Page 327: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Ordenação tem a tarefa de organizar elementos em uma ordem particular, e isto é implementado em uma variedade de aplicações. Considerando uma aplicação bancária, a qual exibe a lista de contas de clientes ativos, por exemplo. A maioria dos usuários deste sistema provavelmente preferem ter a lista em uma ordem crescente, por conveniência.

Nesta lição veremos vários algoritmos de ordenação foram inventados porque essa tarefa é fundamental e freqüentemente utilizada. Por estas razões, examinar os algoritmos existentes será muito benéfico.

Ao final desta lição, o estudante será capaz de:

• Explicar os algoritmos utilizados em ordenação por inserção, ordenação por seleção, Merge Sort e Quick Sort

• Implementar seu próprio algoritmo utilizando essas técnicas

Introdução à Programação II 4

Page 328: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Ordenação por inserção

Um dos mais simples algoritmos desenvolvidos é o de ordenação por inserção. A idéia de algoritmo é absolutamente intuitiva. A seguinte sinopse descreve como a ordenação por inserção funciona para ordenar uma série de cartas. Desejamos ordenar uma série de cartas do menor até o maior da categoria. Todas as cartas estão inicialmente colocadas em uma tabela e a chamaremos de 1ª tabela, seguindo estritamente a ordem da esquerda para a direita, do topo ao fundo. Nós temos outra tabela, chamada de 2ª tabela, onde as cartas serão posicionadas. Escolha a primeira carta disponível da esquerda na 1ª tabela, e que esteja no topo, e coloque esta carta no local adequado (ou seja, ordenado) posicionando na 2ª tabela. Escolha a próxima carta disponível da 1ª tabela e compare-a com as cartas da 2ª tabela e coloque-a na posição adequada. O processo continua até que todas as cartas sejam colocadas na 2ª tabela.

O algoritmo de ordenação por inserção basicamente divide os elementos a serem ordenados em dois grupos: os não ordenados (semelhante à 1ª tabela) e os ordenados (semelhante à 2ª tabela). O primeiro elemento disponível é selecionado dentre os não ordenados do array e este é corretamente posicionado na parte ordenada do array. Esse passo é repetido até que não hajam mais elementos à esquerda, na parte não ordenada do array.

2.1. O algoritmo

public void insertionSort(Object array[], int startIdx, int endIdx) { for (int i = startIdx; i < endIdx; i++) { int k = i; for (int j = i + 1; j < endIdx; j++) { if (((Comparable) array[k]).compareTo(array[j])>0) { k = j; } } swap(array[i], array[k]); }}

2.2. Um exemplo

Dados

Manga

Maçã

Pêssego

Laranja

Banana

1º passo

Manga

Maçã

Pêssego

Laranja

Banana

2º passo

Maçã

Manga

Pêssego

Laranja

Banana

3º passo

Laranja

Maçã

Manga

Pêssego

Banana

4º passo

Banana

Laranja

Maçã

Manga

Pêssego

Figura 1: Exemplo de ordenação por inserção

Introdução à Programação II 5

Page 329: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Ordenação por seleção

Ao se criar um primeiro algoritmo de ordenação, provavelmente foi criado algo parecido com o algoritmo de ordenação por inserção. Como o algoritmo de ordenação por inserção, esse algoritmo é muito intuitivo e fácil de implementar.

Novamente vamos observar como este algoritmo funciona em uma escala de maço de cartas. Considere que as cartas serão organizadas em ordem crescente. Inicialmente, as cartas estão organizadas linearmente na tabela da esquerda para a direita e do topo até embaixo. Confira o nível de cada carta e escolha a carta com o menor nível. Troque a posição dessa carta com a da primeira carta, a que está no topo da esquerda. Depois, localize a carta com o menor nível entre as cartas restantes, excluindo a primeira carta escolhida. Troque novamente a carta selecionada com a carta na segunda posição. Repita esse mesmo passo até que, da segunda à última posição na tabela sejam analisadas e possivelmente trocadas por cartas com o menor valor.

A idéia principal por trás do algoritmo de ordenação por seleção é selecionar o elemento com o menor valor e então trocar o elemento selecionado com o elemento na i posição. O valor de i inicia com 1 até n, onde n é o número total de elementos menos 1.

3.1. O algoritmo

public void selectionSort(Object array[], int startIdx, int endIdx) { int min; for (int i = startIdx; i < endIdx; i++) { min = i; for (int j = i + 1; j < endIdx; j++) { if (((Comparable) array[min]).compareTo(array[j])>0) { min = j; } } swap(array[min], array[i]); }}

3.2. Um exemplo

Dados

Maricar

Vanessa

Margaux

Hannah

Rowena

1º passo

Hannah

Vanessa

Margaux

Maricar

Rowena

2º passo

Hannah

Margaux

Vanessa

Maricar

Rowena

3º passo

Hannah

Margaux

Maricar

Vanessa

Rowena

4º passo

Hannah

Margaux

Maricar

Rowena

Vanessa

Figura 2: Exemplo de ordenação por seleção

Introdução à Programação II 6

Page 330: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Merge Sort

Antes de examinar o algoritmo Merge Sort, vamos primeiramente dar uma rápida olhada no paradigma do dividir-e-conquistar para que melhor se compreenda o Merge Sort.

4.1. Paradigma do dividir-e-conquistar

Vários algoritmos utilizam a repetição (recursividade) para solucionar um determinado problema. O problema original é dividido em subproblemas, então as soluções dos subproblemas conduzem a solução do poblema principal. Esse tipo de algoritmo tipicamente seguem o paradigma do dividir-e-conquistar.

Em cada nível de recursividade, o paradigma consiste de três passos.

1.DividirDividir o problema principal em subproblemas.

2.ConquistarConquistar os subproblemas resolvendo-os através da recursividade. No caso em que os subproblemas são simples e pequenos o suficiente, resolver de maneira direta.

3.CombinarUnir as soluções dos subproblemas, direcionando à solução do problema principal.

4.2. Entendendo Merge Sort

Como mencionado anteriormente, Merge Sort utiliza a técnica do dividir-e-conquistar. Dessa foma, a descrição deste algoritmo é seguida como exemplo depois dos três passos do paradigma do dividir-e-conquistar. Aqui está como o Merge Sort funciona.

1.DividirDividir a sequência dos elementos dados em duas partes.

2.ConquistarConquistar cada parte de modo repetitivo, chamando o método Merge Sort.

3.CombinarCombinar ou fundir as duas partes recursivamente para apresentar a seqüência ordenada.

A repetição acaba quando o objetivo básico é alcançado. Este é o caso onde a parte a ser ordenada possui exatamente um elemento. Já que apenas um elemento seja separado para ser ordenado, essa parte já está organizada na sua própria sequência.

4.3. O algoritmo

void mergeSort(Object array[], int startIdx, int endIdx) { if (array.length != 1) { mergeSort(leftArr, startIdx, midIdx); mergeSort(rightArr, midIdx+1, endIdx); combine(leftArr, rightArr); }}

Introdução à Programação II 7

Page 331: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.4. Um exemplo

Dados:

7 2 5 6

Dividir o array de dados em dois:

ArrayEsq ArrayDir

Dividir o ArrayEsq em dois:

ArrayEsq ArrayDir

Combinar

2 7

Dividir ArrDir em dois:

ArrayEsq ArrayDir

55 66

Combinar

5 6

Combinar

ArrayEsq e ArrayDir.

2 5 6 7Figura 3: Exemplo de Merge sort

Introdução à Programação II 8

27 27 65 65

77 22

Page 332: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Quick Sort

Quick Sort foi criado por C.A.R. Hoare. Como o Merge Sort, este algoritmo é baseado no paradigma do dividir-e-conquistar. Mas ao invés de possuir as três fases, ele envolve apenas as seguintes fases:

1.DividirSeparação dos arrays em dois subarrays A[p...q-1] e A[q+1...r] onde cada elemento em A[p...q-1] é menor ou igual a A[q] e cada elemento em A[q+1...r] é maior ou igual a A[q]. A[q] é chamado de eixo. Cálculo de q é parte do processo de separação.

2.ConquistarOrdenar os subarrays pela recursividade, chamado de método quickSort.

Não existe a fase de "Combinar" pois os subarrays são ordenados localmente.

5.1. O algoritmo

void quickSort(Object array[], int leftIdx, int rightIdx) { int pivotIdx; if (rightIdx > leftIdx) { pivotIdx = partition(array, leftIdx, rightIdx); quickSort(array, leftIdx, pivotIdx-1); quickSort(array, pivotIdx+1, rightIdx); }}

5.2. Um exemplo

Array dado:

3 1 4 1 5 9 2 6 5 3 5 8

Escolher o primeiro elemento para ser o eixo = 3.

3 1 4 1 5 9 2 6 5 3 5 8

Inicializar a esquerda com o ponteiro no segundo elemento, e a direita com o ponteiro no último elemento.

Esq. Dir.

3 1 4 1 5 9 2 6 5 3 5 8

Mover o ponteiro da esquerda na direção da direita até ser localizado um valor maior do que o do eixo. Mover o ponteiro direito na direção esquerda até ser localizado um valor menor do que o eixo.

Esq. Dir.

3 1 4 1 5 9 2 6 5 3 5 8

Trocar os elementos referidos com os ponteiros esquerdo e direito.

Introdução à Programação II 9

Page 333: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Esq. Dir.

3 1 3 1 5 9 2 6 5 4 5 8

Mover os ponteiros direito e esquerdo novamente.

Esq. Dir.

3 1 3 1 5 9 2 6 5 4 5 8

Trocar os elementos.

Esq. Dir.

3 1 3 1 2 9 5 6 5 4 5 8

Mover os ponteiros esquerdos e direitos novamente.

Dir. Esq.

3 1 3 1 2 9 5 6 5 4 5 8

Observe que os ponteiros da esquerda e direita se cruzaram e o direito < esquerdo. Neste caso, trocar o eixo pelo valor do ponteiro direito.

pivô

2 1 3 1 3 9 5 6 5 4 5 8

Figura 4: Exemplo de Quick Sort

A caminhada do eixo agora está completa. Ordenação de arrays por recursividade em cada lado, utilizando o eixo.

Introdução à Programação II 10

Page 334: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 7Abstract Window Toolkit e Swing

Versão 1.0 - Mar/2007

Page 335: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Mesmo sem conhecer interface gráfica com o usuário ou GUI (Graphical User Interface) é possível criar uma grande variedade de diferentes projetos. Entretanto, estas aplicações não teriam grandes chances de serem agradáveis aos usuários, tão acostumados aos ambientes gráficos como Windows, Solaris e Linux. Ter um projeto desenvolvido em GUI afeta o uso de sua aplicação pois resulta em facilidade de uso e melhor experiência para os usuários de seus aplicativos. Java fornece ferramentas como Abstract Window Toolkit (AWT) e Swing para desenvolver aplicações GUI interativas.

Ao final desta lição, o estudante será capaz de:

• Explicar similaridades e diferenças entre AWT e Swing• Diferenciar entre os containers e componentes• Criar aplicações GUI utilizando AWT• Criar aplicações GUI utilizando Swing• Descrever como os gerenciadores de layout, tais como FlowLayout, BorderLayout e

GridLayout, posicionam os componentes GUI• Criar layouts complexos ao elaborar aplicações GUI

Introdução à Programação II 4

Page 336: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. AWT (Abstract Window Toolkit) vs. SwingA JFC (Java Foundation Classes) é uma importante parte de Java SDK. Refere-se a uma coleção de APIs que simplificam o desenvolvimento de aplicações Java GUI. Consistem basicamente em cinco APIs incluindo AWT e Swing. As outras três APIs são Java2D, Accessibility, e Drag and Drop. Todas essas APIs dão suporte aos desenvolvedores na criação e implementação de aplicações visualmente destacadas.

Ambas AWT e Swing dispõem de componentes GUI que podem ser usadas na criação de aplicações Java e applets. Aprenderemos sobre applets mais tarde. Diferentemente de alguns componentes AWT que usam código nativo, Swing é escrito inteiramente usando a linguagem de programação Java. Em consequência, Swing fornece uma implementação independente de plataforma que assegura que aplicações desenvolvidas em diferentes plataformas tenham a mesma aparência. AWT, entretanto, assegura que o look and feel (a aparência) de uma aplicação executada em duas máquinas diferentes sejam compatíveis. A API Swing é construída sobre um número de APIs que implementa várias partes da AWT. Como resultado, componentes AWT ainda podem ser usados com componentes Swing.

Introdução à Programação II 5

Page 337: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Componentes GUI AWT

3.1. Fundamental Window Classes

No desenvolvimento de aplicações GUI, os componentes como os botões ou campos de texto são localizados em containers. Essa é uma lista de importantes classes containers fornecidas pela AWT.

Classe AWT Descrição

Component Uma classe abstrata para objetos que podem ser exibidos no console e interagir com o usuário. A raiz de todas as outras classes AWT.

Container Uma subclasse abstrata da classe Component. Um componente que pode conter outros componentes.

Panel Herda a classe Container. Uma área que pode ser colocada em um Frame, Dialog ou Window. Superclasse da classe Applet.

Window Também herda a classe Container. Uma janela top-level, que significa que ela não pode ser contida em nenhum outro objeto. Não tem bordas ou barra de menu.

Dialog Uma janela contendo a barra de título e o botão de fechar, utilizada para criar janelas para comunicação com o usuário.

Frame Uma janela completa com um título, barra de menu, borda, e cantos redimensionáveis. Possui quatro construtores, dois deles possuem as seguintes assinaturas:

Frame()Frame(String title)

Tabela 1: Classes Container AWT

Para configurar o tamanho da janela, podemos utilizar o método setSize, do seguinte modo:

void setSize(int width, int height)

Reconfigura o tamanho da janela para o width (largura) e height (altura) fornecidos como argumentos.

void setSize(Dimension d)

Reconfigura o tamanho da janela para os atributos d.width e d.height baseado em um objeto instanciado da classe Dimension especificado como argumento.

Por padrão uma janela não é visível a não ser que seja configurada a sua visibilidade para true. Esta é a sintaxe para o método setVisible:

void setVisible(boolean b)

Ao criar aplicações GUI, o objeto Frame é o mais comumente utilizado. Aqui está um exemplo de como criar uma aplicação dessas:

import java.awt.*;

public class FrameDemo extends Frame { public static void main(String args[]) { FrameDemo sf = new FrameDemo();

Introdução à Programação II 6

Page 338: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

sf.setSize(100, 100); //Tente removendo esta linha sf.setVisible(true); //Tente removendo esta linha }}

Este é o resultado esperado pela execução da classe SampleFrame:

Figura 1: Executando SampleFrame

Note que o botão de fechar ainda não funciona porque nenhum mecanismo de suporte a eventos foi adicionado a classe até o momento. Conheceremos sobre suporte a eventos no próximo módulo.

3.2. Graphics

Vários métodos gráficos são encontrados na classe Graphics. Aqui está a lista de alguns desses métodos.

drawLine() drawPolyline() setColor()fillRect() drawPolygon() getFont()drawRect() fillPolygon() setFont()clearRect() getColor() drawString()

Tabela 2: Alguns métodos da classe Graphics

Relacionada a essa classe está a classe Color, que tem três construtores.

Formato do Construtor DescriçãoColor(int r, int g, int b) Valor inteiro de 0 a 255.Color(float r, float g, float b) Valor decimal de 0.0 a 1.0.Color(int rgbValue) Valor variável de 0 a 224-1 (preto a branco).

Vermelho: bits 16-23

Verde: bits 8-15

Azul: bits 0-7

Tabela 3: Construtores Color

Aqui está uma classe demonstrando a utilização de alguns métodos da classe Graphics:

import java.awt.*;

public class PanelDemo extends Panel { PanelDemo() { setBackground(Color.black); //Constante na classe Color } public void paint(Graphics g) { g.setColor(new Color(0,255,0)); // verde g.setFont(new Font("Helvetica",Font.PLAIN,16)); g.drawString("Hello GUI World!", 30, 100); g.setColor(new Color(1.0f,0,0)); // vermelho g.fillRect(30, 100, 150, 10);

Introdução à Programação II 7

Page 339: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} public static void main(String args[]) { Frame f = new Frame("Testing Graphics Panel"); PanelDemo painel = new PanelDemo(); f.add(painel); f.setSize(600, 300); f.setVisible(true); }}

Para um panel se tornar visível, ele deve ser colocado em uma janela visível como um frame.

Executando o código apresentado temos o seguinte resultado esperado:

Figura 2: Executando GraphicsPanel

3.3. Mais Componentes AWT

Aqui está uma lista de controles AWT. Controles são componentes como botões ou campos textos que permitem ao usuário interagir com a aplicação GUI. Essas são todas as subclasses da classe Component.

Label Button Choice

TextField Checkbox List

TextArea CheckboxGroup Scrollbar

Tabela 4: Componentes AWT

Introdução à Programação II 8

Page 340: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

A seguinte classe cria um frame com alguns componentes:

import java.awt.*;

class ControlsDemo extends Frame { public static void main(String args[]) { ControlsDemo fwc = new ControlsDemo(); fwc.setLayout(new FlowLayout()); fwc.setSize(600, 100); fwc.add(new Button("Test Me!")); fwc.add(new Label("Labe")); fwc.add(new TextField()); CheckboxGroup cbg = new CheckboxGroup(); fwc.add(new Checkbox("chk1", cbg, true)); fwc.add(new Checkbox("chk2", cbg, false)); fwc.add(new Checkbox("chk3", cbg, false)); List list = new List(3, false); list.add("MTV"); list.add("V"); fwc.add(list); Choice chooser = new Choice(); chooser.add("Avril"); chooser.add("Monica"); chooser.add("Britney"); fwc.add(chooser); fwc.add(new Scrollbar()); fwc.setVisible(true); }}

Está e a janela que será mostrada na execução da classe ControlsDemo:

Figura 3: Executando ControlsDemo

Introdução à Programação II 9

Page 341: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Gerenciadores de LayoutA posição e o tamanho dos componentes em cada container é determinado pelo gerenciador de layout. O gerenciador de layout gerencia a disposição dos componentes no container. Esses são alguns dos gerenciadores de layout incluídos no Java.

• FlowLayout• BorderLayout• GridLayout• GridBagLayout• CardLayout• BoxLayout

O gerenciador de layout pode ser configurado usando o método setLayout da classe Container. O método possui a seguinte assinatura:

void setLayout(LayoutManager mgr)

Caso seja não seja necessário utilizar nenhum gerenciador de layout, é possível passar o layout do tipo nulo (NullLayout) como argumento para esse método, ao se fazer isso será necessário posicionar todos os elementos manualmente com a utilização do método setBounds da classe Component. Este método possui a seguinte assinatura:

public void setBounds(int x, int y, int width, int height)

O método controla a posição baseada nos argumentos x (esquerda) e y (topo), e o tamanho width (largura) e height (altura) especificados. Isso seria bastante difícil e tedioso de programar, principalmente ao se possuir um layout com diversos objetos Component e Container. Teríamos de chamar esse método para cada componente, além de conhecer sua determinada posição em pixels.

4.1. O Gerenciador FlowLayout

O FlowLayout é o gerenciador padrão para a classe Panel e suas subclasses, incluindo a classe Applet. Ele posiciona os componentes da esquerda para a direita e de cima para baixo, começando no canto superior esquerdo. Imagine como se utilizasse um editor de textos. É assim que o gerenciador FlowLayout funciona.

Ele possui três construtores que são como os listados abaixo:

Construtores FlowLayout FlowLayout() Cria um novo objeto FlowLayout com o alinhamento centralizado e 5 unidades de intervalo horizontal e vertical aplicado aos componentes por padrão.FlowLayout(int align) Cria um novo objeto FlowLayout com o alinhamento especificado e o intervalo padrão de 5 unidades horizontal e vertical aplicado aos componentes.FlowLayout(int align, int hgap, int vgap) Cria um novo objeto FlowLayout com o primeiro argumento como o alinhamento aplicado, o intervalo horizontal hgap e o itervalo vertical vgap aplicado aos componentes.

Tabela 5: Construtores FlowLayout

O intervalo se refere ao espaçamento entre os componentes e é medido em pixels. O argumento alinhamento deve ser um dos seguintes:

• FlowLayout.LEFT• FlowLayout.CENTER

Introdução à Programação II 10

Page 342: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

• FlowLayout.RIGHT

Observe a seguinte classe:

import java.awt.*;

class FlowLayoutDemo extends Frame { public static void main(String args[]) { FlowLayoutDemo fld = new FlowLayoutDemo(); fld.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 10)); fld.add(new Button("ONE")); fld.add(new Button("TWO")); fld.add(new Button("THREE")); fld.setSize(100, 100); fld.setVisible(true); }}

O resultado da execução sobre a plataforma Windows é apresentado abaixo.

Figura 4: Executando FlowLayoutDemo

4.2. O Gerenciador BorderLayout

O BorderLayout divide o Container em cinco partes – north (norte), south (sul), east (leste), west (oeste) e center (centro). Cada componente é adicionado a uma região específica. As regiões north e south espalham-se horizontalmente enquanto que as regiões east e west ajustam-se verticalmente. A região centro, por outro lado, ajusta-se em ambos horizontalmente e verticalmente. Esse layout é o padrão para objetos Window, incluindo as subclasses Frame e Dialog.

Construtores BorderLayoutBorderLayout() Cria um novo objeto BorderLayout sem nenhum espaçamento aplicado sobre os diferentes componentes.BorderLayout(int hgap, int vgap) Cria um novo objeto BorderLayout com espaçamento horizontal hgap e vertical vgap aplicado sobre os diferentes componentes.

Tabela 6: Construtores BorderLayout

Como no gerenciador FlowLayout, os parâmetros hgap e vgap aqui também se referem ao espaçamento entre os componentes no container.

Para adicionar um componente a uma região específica, use o método add e passe dois argumentos: o componente a ser adicionado e a região onde o componente deve ser posicionado. Note que apenas um componente pode ser colocado em uma região. Adicionar mais de um componente a um container resulta em exibir apenas o último componente adicionado. A lista a seguir apresenta as regiões válidas que são campos predefinidos na classe BorderLayout.

• BorderLayout.NORTH

Introdução à Programação II 11

Page 343: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

• BorderLayout.SOUTH• BorderLayout.EAST• BorderLayout.WEST• BorderLayout.CENTER

Aqui está uma classe demonstrando como a BorderLayout pode ser utilizada:

import java.awt.*;

class BorderLayoutDemo extends Frame { public static void main(String args[]) { BorderLayoutDemo bld = new BorderLayoutDemo(); bld.setLayout(new BorderLayout(10, 10)); //pode remover bld.add(new Button("NORTH"), BorderLayout.NORTH); bld.add(new Button("SOUTH"), BorderLayout.SOUTH); bld.add(new Button("EAST"), BorderLayout.EAST); bld.add(new Button("WEST"), BorderLayout.WEST); bld.add(new Button("CENTER"), BorderLayout.CENTER); bld.setSize(200, 200); bld.setVisible(true); }}

Aqui está o resultado desta classe. A segunda figura mostra o efeito do redimensionamento do frame.

Figura 5: Executando BorderLayoutDemo

4.3. O gerenciador GridLayout

Com o gerenciador GridLayout, os componentes também são posicionados da esquerda para a direita e de cima para baixo como no gerenciador FlowLayout. Além disso, o gerenciador GridLayout divide o container em um número de linhas e colunas. Todas essas regiões são do mesmo tamanho. Ele sempre ignora o tamanho preferido do componente.

A seguir, são apresentados os construtores disponíveis para a classe GridLayout.

Construtores GridLayoutGridLayout()Cria um novo objeto GridLayout com uma única linha e uma única coluna por padrão.GridLayout(int rows, int cols) Cria um novo objeto GridLayout com o número especificado de linhas e colunas.GridLayout(int rows, int cols, int hgap, int vgap)

Introdução à Programação II 12

Page 344: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Cria um novo objeto GridLayout com o número especificado de linhas e colunas. Os espaçamentos horizontal hgap e vertical vgap são aplicados aos componentes.

Tabela 7: Construtores GridLayout

Vejamos a seguinte classe:

import java.awt.*;

class GridLayoutDemo extends Frame { public static void main(String args[]) { GridLayoutDemo gld = new GridLayoutDemo(); gld.setLayout(new GridLayout(2, 3, 4, 4)); gld.add(new Button("ONE")); gld.add(new Button("TWO")); gld.add(new Button("THREE")); gld.add(new Button("FOUR")); gld.add(new Button("FIVE")); gld.setSize(200, 200); gld.setVisible(true); }}

Esse é o resultado da classe (observe o efeito do redimensionamento sobre o frame na segunda figura):

Figura 6: Executando GridLayoutDemo

4.4. Painéis e Layouts Complexos

Para criar layouts mais complexos, é possível combinar os diferentes gerenciadores de layout com o uso de objetos do tipo Panel. Lembre-se que Panel é um Container e um Component ao mesmo tempo. É possível inserir Components em um Panel e adicionar este a uma região específica do Container.

Observe a técnica utilizada na classe a seguir:

import java.awt.*;

class ComplexDemo extends Frame { public static void main(String args[]) {

Introdução à Programação II 13

Page 345: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

ComplexDemo cl = new ComplexDemo(); Panel panelNorth = new Panel(); Panel panelCenter = new Panel(); Panel panelSouth = new Panel(); /* Painel North */ //Painéis usam FlowLayout por padrão panelNorth.add(new Button("ONE")); panelNorth.add(new Button("TWO")); panelNorth.add(new Button("THREE")); /* Painel Center */ panelCenter.setLayout(new GridLayout(4,4)); panelCenter.add(new TextField("1st")); panelCenter.add(new TextField("2nd")); panelCenter.add(new TextField("3rd")); panelCenter.add(new TextField("4th")); /* Painel South */ panelSouth.setLayout(new BorderLayout()); panelSouth.add(new Checkbox("Choose me!"), BorderLayout.CENTER); panelSouth.add(new Checkbox("I'm here!"), BorderLayout.EAST); panelSouth.add(new Checkbox("Pick me!"), BorderLayout.WEST); /* Adicionando os Panels ao Frame container */ //Frames usam BorderLayout por padrão cl.add(panelNorth, BorderLayout.NORTH); cl.add(panelCenter, BorderLayout.CENTER); cl.add(panelSouth, BorderLayout.SOUTH); cl.setSize(300,300); cl.setVisible(true); }}

Este é o resultado da classe:

Figura 7: Executando Layout Complexo

Introdução à Programação II 14

Page 346: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Componentes GUI Swing

Como o pacote AWT, o pacote Swing fornece classes para criar aplicações GUI. O pacote é encontrado em javax.swing. A diferença principal entre esses dois é que o componente Swing é escrito inteiramente usando Java enquanto o outro não. Como resultado, Projetos GUI escritos utilizando classes do pacote Swing possuem a mesma aparência mesmo quando executado sobre plataformas completamente diferentes. Além disso, Swing fornece componentes mais interessantes como o que permite selecionar cores e a OptionPane (painel de opções).

Os nomes dos componentes de Swing são quase similares aos componentes AWT. Uma diferença óbvia é a convenção de nomes dos componentes. Basicamente, os nomes dos componentes Swing são os mesmos nomes dos componentes AWT mas com um prefixo em que é adicionado a letra "J". Por exemplo, um componente no AWT é a classe Button, o mesmo componente correspondente a este no pacote Swing é a classe JButton. Descrito abaixo, está uma lista de alguns dos componentes Swing:

Componente Descrição

JComponent A classe raiz para todos os componentes Swing, excluindo containers hierarquicamente superiores.

JButton Um botão do tipo "pressionar". Corresponde a classe Button no pacote AWT.

JCheckBox Um item que pode ser marcado ou desmarcado pelo usuário. Corresponde a classe Checkbox no pacote AWT.

JFileChooser Permite ao usuário que selecione um arquivo. Corresponde a classe FileChooser no pacote AWT.

JTextField Permite a edição de uma única linha de texto. Corresponde a classe TextField no pacote AWT.

JFrame Herda e corresponde a classe Frame no pacote AWT, mas as duas são ligeiramente incompatíveis em termos de adição de componentes a esse container. É preciso pegar o conteúdo do pane atual antes de adicionar um componente.

JPanel Herança de um JComponent. É uma classe container simples. Corresponde a classe Panel no pacote AWT.

JApplet Herança da classe Applet no pacote AWT. Também ligeiramente incompatível com a classe Applet em termos de adição de componentes a esse container.

JOptionPane Herda JComponent. Fornece uma maneira fácil de exibir caixas de diálogo pop-up.

JDialog Herança da classe Dialog no pacote AWT. Normalmente utilizado para informar o usuário de alguma coisa ou alertá-lo para uma entrada.

JColorChooser Herda JComponent. Permite ao usuário selecionar uma cor.

Tabela 8: Alguns componentes Swing

Para a lista completa de componentes Swing, por favor recorra à documentação API.

5.1. Configurando Containers JFrame e JApplet

Como mencionado, os containers top-level como o JFrame e o JApplet no pacote Swing são ligeiramente incompatíveis com seus correspondentes AWT. Isso em termos de adição de

Introdução à Programação II 15

Page 347: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

componentes ao container. Ao invés de adicionar diretamente um componente ao container como nos containers AWT, é necessário primeiro pegar o conteúdo do pane do container. Para fazer isso utiliza-se o método getContentPane do container:

import javax.swing.*;import java.awt.*;

class SwingDemo extends JFrame { public SwingDemo() { super("My First Swing Application"); this.setSize(300,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String args[]) { new SwingDemo(); }}

Note que o pacote java.awt ainda é importado porque os gerenciadores de layout em uso são definidos neste pacote. Além disso, dar um título ao frame e empacotar os componentes no frame também é aplicável para aos frames AWT.

Dicas de programação:

1. Compare o estilo de código aplicado neste exemplo para AWT. 2. Componentes são declarados como campos, um método launchFrame é

definido, e a inicialização e adição de componentes são todas feitas no método launchFrame.

3. Não herdamos a classe Frame, mas a classe JFrame.4. A vantagem de utilizar este estilo se tornará aparente quando chegarmos

ao suporte a evento no tópico sobre tratamento de eventos.

Aqui está um resultado demonstrativo:

Figura 8: Executando SwingDemo

Introdução à Programação II 16

Page 348: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 8Tratamento de Eventos em Interfaces Gráficas

Versão 1.0 - Mar/2007

Page 349: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Neste módulo, aprenderemos como tratar eventos disparados quando o usuário interage com a interface gráfica de sua aplicação (GUI). Após completar este módulo seremos capazes de desenvolver aplicações gráficas que responderão às interações do usuário.

Ao final desta lição, o estudante será capaz de:

• Enumerar os componentes do modelo de delegação de eventos• Explicar como o modelo de delegação de eventos funciona• Criar aplicações gráficas que interajam com o usuário• Discutir os benefícios das classes adapter• Discutir as vantagens de utilizar inner e anonymous inner class

Introdução à Programação II 4

Page 350: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Modelo de Delegação de Eventos

O modelo de Delegação de eventos descreve o modo como sua classe pode responder a uma interação do usuário. Para compreender o modelo, estudaremos primeiro três importantes componentes:

1. Event Source (Gerador de Evento)O event source refere-se ao componente da interface que origina o evento. Por exemplo, se o usuário pressiona um botão, o event source neste caso é o botão.

2. Event Listener/Handler (Monitor de Eventos/Manipulador)O event listener recebe informações de eventos e processa as interações do usuário. Quando um botão é pressionado, o event listener pode tratá-lo exibindo uma informação útil ao usuário.

3. Event Object (Objeto Evento)Quando um evento ocorre (por exemplo, quando o usuário interage com um componente da interface gráfica), um objeto Event é criado. Este objeto contém todas as informações necessárias sobre o evento gerado. As informações incluem o tipo de evento, digamos, "o mouse foi clicado". Há diversas classes de evento para diferentes categorias de ações do usuário. Um objeto event tem o tipo de dado de uma dessas classes.

Aqui está representado o modelo de delegação de eventos:

Figura 1: Modelo de Delegação de Eventos

Inicialmente, um listener deverá ser registrado pelo event source. Assim ele poderá receber informações sobre os eventos quando ocorrerem no event source. Somente um listener registrado poderá receber notificações dos eventos. Uma vez registrado, um listener simplesmente aguarda até que ocorra um evento.

Quando alguma coisa acontece no event source, um objeto event, que descreve o evento, é criado. O evento é então disparado pelo gerador para os listener registrados.

Quando o listener recebe um objeto event (ou seja, uma notificação) de um event source, ele executa sua função. Ele decifra a notificação e processa o evento ocorrido.

Introdução à Programação II 5

Page 351: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2.1. Registro de Listeners

O event source registra um listener através dos métodos add<Tipo>Listener.

void add<Tipo>Listener(<Tipo>Listener listenerObj)

<Tipo> depende do tipo de event source. Ele pode ser Key, Mouse, Focus, Component, Action e outros.

Diversos listener podem ser registrados para um event source para recepção de notificações de eventos.

Um listener registrado pode também ser removido através do método remove<Tipo>Listener.

void remove<Tipo>Listener(<Tipo>Listener listenerObj)

Introdução à Programação II 6

Page 352: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Classes Event

Um EventObject tem uma classe de evento que indica seu tipo. Na raiz da hierarquia das classes Event estão a classe EventObject, que é encontrada no pacote java.util. Uma subclasse imediata da classe EventObject é a classe AWTEvent. A classe AWTEvent está declarada no pacote java.awt. Ela é a raiz de todos os eventos baseados em AWT. A seguir temos algumas das classes de evento AWT:

Classes de Evento Descrição

ComponentEvent Estende a classe AWTEvent. Instanciada quando um componente é movido, redimensionado, tornado visível ou invisível.

InputEvent Estende a classe ComponentEvent. Classe abstrata de evento, raiz a partir da qual são implementadas todas as classes de componentes de entrada de dados.

ActionEvent Estende a classe AWTEvent. Instanciada quando um botão é pressionado, um item de uma lista recebe duplo-clique ou quando um item de menu é selecionado.

ItemEvent Estende a classe AWTEvent. Instanciada quando um item é selecionado ou desmarcado pelo usuário, seja numa lista ou caixa de seleção (checkbox).

KeyEvent Estende a classe InputEvent. Instanciado quando uma tecla é pressionada, liberada ou digitada (pressionada e liberada).

MouseEvent Estende a classe InputEvent. Instanciada quando um botão do mouse é pressionado, liberado, clicado (pressionado e liberado) ou quando o cursor do mouse entra ou sai de uma parte visível de um componente.

TextEvent Estende a classe AWTEvent. Instanciada quando o valor de um campo texto ou area de texto sofre alteração.

WindowEvent Estende a classe ComponentEvent. Instanciada quando um objeto Window é aberto, fechado, ativado, desativado, minimizado, restaurado ou quando o foco é transferido para dentro ou para fora da janela.

Tabela 1: Classes Event

Tome nota: todas as subclasses de AWTEvent seguem esta convenção de nomeação:

<Tipo>Event

Introdução à Programação II 7

Page 353: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Listeners de Evento

Listeners de evento são classes que implementam as interfaces <Tipo>Listener. A tabela a seguir algumas interfaces utilizadas com maior freqüência:

Listeners de Evento Descrição

ActionListener Recebe eventos de ação, estes podem ser um pressionamento do mouse ou da barra de espaço sobre o objeto.

MouseListener Recebe eventos do mouse.

MouseMotionListener Recebe eventos de movimento do mouse, que incluem arrastar e mover o mouse.

WindowListener Recebe eventos de janela (abrir, fechar, minimizar, entre outros).

Tabela 2: Event Listeners

4.1. Método de ActionListener

Este é o método da interface ActionListener que deve ser implementado:

Médoto de ActionListener

public void actionPerformed(ActionEvent e) Chamado quando o mouse é pressionado ou foi utilizada a barra de espaço sobre um botão por exemplo.

Tabela 3: Método de ActionListener

4.2. Métodos de MouseListener

Estes são os métodos da interface MouseListener que devem ser implementados:

Métodos de MouseListener

public void mouseClicked(MouseEvent e) Chamado quando o mouse é pressionado (pressionar e soltar).

public void mouseEntered(MouseEvent e) Chamado quando o cursor do mouse entra em um componente.

public void mouseExited(MouseEvent e) Chamado quando o cursor do mouse sai de um componente.

public void mousePressed(MouseEvent e) Chamado quando o botão do mouse é pressionado sobre um componente (pressionar).

public void mouseReleased(MouseEvent e) Chamado quando o botão do mouse é solto sobre um componente (soltar).

Tabela 4: Métodos de MouseListener

4.3. Métodos de MouseMotionListener

Estes são os métodos da interface MouseMotionListener que devem ser implementados:

Introdução à Programação II 8

Page 354: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Métodos MouseListener

public void mouseDragged(MouseEvent e) Chamado quando o mouse é pressionado sobre um componente e então arrastado (dragged). É chamado tantas vezes quanto o mouse for arrastado.

public void mouseMoved(MouseEvent e) Chamado quando o cursor do mouse é movido sobre um componente, sem que o mouse esteja pressionado. Será chamado múltiplas vezes, tantas quantas o mouse for movido.

Tabela 5: Métodos MouseMotionListener

4.4. Métodos WindowListener

Estes são os métodos da interface WindowListener que devem ser implementados:

Métodos WindowListener

public void windowOpened(WindowEvent e) Chamado quando uma janela é aberta (quando o objeto Window torna-se visível pela primeira vez)

public void windowClosing(WindowEvent e) Chamado quando uma janela é encerrada (objeto Window).

public void windowClosed(WindowEvent e) Chamado quando a janela foi fechada após a liberação de recursos utilizados pelo objeto (EventSource).

public void windowActivated(WindowEvent e) Chamado quando uma janela é ativada, ou seja, está em uso.

public void windowDeactivated(WindowEvent e) Chamado quando uma janela deixa de ser a janela ativa.

public void windowIconified(WindowEvent e) Chamado quando a janela é iconificada (Este evento é utilizado especialmente para o ambiente Macintosh).

public void windowDeiconified(WindowEvent e) Chamado quando a janela retorna do estado iconificado para o normal (Este evento é utilizado especialmente para o ambiente Macintosh).

Tabela 6: Métodos WindowListener

4.5. Guia para criação de Aplicações Gráficas com tratamento de eventos

Estes são os passos a serem lembrados ao criar uma aplicação gráfica com tratamento de eventos.

1. Criar uma classe que descreva e mostre a aparência da sua aplicação gráfica.2. Criar uma classe que implemente a interface listener apropriada. Esta classe poderá estar

inserida na classe do primeiro passo. 3. Na classe implementada, sobrepor TODOS os métodos da interface listener. Descrever em

cada método como o evento deve ser tratado. Podemos deixar vazio um método que não desejamos tratar.

4. Registrar o objeto listener (a instância da classe listener do passo 2) no EventSource utilizando o método add<Tipo>Listener.

Introdução à Programação II 9

Page 355: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.6. Exemplo do Evento Actionimport java.awt.*;import javax.swing.*;import java.awt.event.*;

public class ActionDemo extends JFrame implements ActionListener { private JTextField tf; private JButton bt; public ActionDemo(String title){ super(title); tf = new JTextField(); bt = new JButton("Clicked"); add(tf, BorderLayout.SOUTH); add(bt, BorderLayout.NORTH); setSize(300,300); bt.addActionListener(this); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void actionPerformed(ActionEvent actionEvent) { if (tf.getText().equals("Action")) tf.setText(""); else tf.setText("Action"); } public static void main(String args[]) { new ActionDemo("Action Demo"); }}

A seguir vemos algumas imagens da janela criada pela classe ActionDemo:

4.7. Anonymous inner class

Anonymous inner class são classes internas que não são declaradas. O uso de anonymous inner class simplifica a classe. A seguir temos o mesmo exemplo apresentado anteriormente modificado para utilizar este recurso.

Introdução à Programação II 10

Page 356: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.8. Exemplo do Evento Actionimport java.awt.*;import javax.swing.*;import java.awt.event.*;

public class ActionDemo extends JFrame { private JTextField tf; private JButton bt; public ActionDemo(String title){ super(title); tf = new JTextField(); bt = new JButton("Clicked"); add(tf, BorderLayout.SOUTH); add(bt, BorderLayout.NORTH); setSize(300,300); bt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { method(); } }); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void method() { if (tf.getText().equals("Action")) tf.setText(""); else tf.setText("Action"); } public static void main(String args[]) { new ActionDemo("Action Demo"); }}

Observe que a classe se encontra de forma mais organizada, criamos um objeto em tempo de execução para o evento, este fará a chamada um método, chamado method, que se encarregará de executar as instruções.

4.9. Exemplo de Eventos do Mouse

import java.awt.*;import javax.swing.*;import java.awt.event.*;

public class MouseEventsDemo extends JFrame { private TextField tf; public MouseEventsDemo(String title){ super(title); tf = new TextField(60); add(tf, BorderLayout.SOUTH); setSize(300,300); this.addMouseListener(new MouseListener() { public void mouseClicked(MouseEvent mouseEvent) { eventMouse1(mouseEvent); } public void mouseEntered(MouseEvent mouseEvent) { eventMouse2(mouseEvent); } public void mouseExited(MouseEvent mouseEvent) { eventMouse3(mouseEvent);

Introdução à Programação II 11

Page 357: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} public void mousePressed(MouseEvent mouseEvent) { eventMouse4(mouseEvent); } public void mouseReleased(MouseEvent mouseEvent) { eventMouse5(mouseEvent); } }); this.addMouseMotionListener(new MouseMotionListener() { public void mouseDragged(MouseEvent mouseEvent) { eventMouse6(mouseEvent); } public void mouseMoved(MouseEvent mouseEvent) { eventMouse7(mouseEvent); } }); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void eventMouse1(MouseEvent me) { tf.setText("Mouse clicked."); } public void eventMouse2(MouseEvent me) { tf.setText("Mouse entered component."); } public void eventMouse3(MouseEvent me) { tf.setText("Mouse exited component."); } public void eventMouse4(MouseEvent me) { tf.setText("Mouse pressed."); } public void eventMouse5(MouseEvent me) { tf.setText("Mouse released."); } public void eventMouse6(MouseEvent me) { tf.setText("Mouse dragged at " + me.getX() + "," + me.getY()); } public void eventMouse7(MouseEvent me) { tf.setText("Mouse moved at " + me.getX() + "," + me.getY()); } public static void main(String args[]) { new MouseEventsDemo("Mouse Events Demo"); }}

A seguir vemos algumas imagens da janela criada pela classe MouseEventsDemo:

Introdução à Programação II 12

Page 358: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 2: Executando MouseEventsDemo

Figura 3: Executando MouseEventsDemo: Mouse "entra" na janela

Figura 4: Executando MouseEventsDemo: Mouse sai da janela

Introdução à Programação II 13

Page 359: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4.10. Exemplo Close Window

import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class WindowDemo extends JFrame { public WindowDemo(String title) { super(title); this.setSize(300,300); this.addWindowListener(new WindowListener() { public void windowActivated(WindowEvent windowEvent) { } public void windowClosed(WindowEvent windowEvent) { } public void windowClosing(WindowEvent windowEvent) { closed(); } public void windowDeactivated(WindowEvent windowEvent) { } public void windowDeiconified(WindowEvent windowEvent) { } public void windowIconified(WindowEvent windowEvent) { } public void windowOpened(WindowEvent windowEvent) { } }); this.setVisible(true); } public void closed() { System.exit(0); } public static void main(String args[]) { new WindowDemo("Close Window Example"); }}

Executando esta classe, será exibida a janela abaixo:

Figura 5: Executando CloseFrame

Introdução à Programação II 14

Page 360: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Classes Adapter

Implementar todos os métodos de uma interface é muito trabalhoso. Freqüentemente necessitaremos implementar somente alguns métodos da interface. Felizmente, Java nos oferece as classes adapter que implementam todos os métodos das interfaces listener que possuem mais de um método. As implementações dos métodos são vazias.

5.1. Exemplo Close Window

import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class WindowDemo extends JFrame { private JLabel label; public WindowDemo(String title) { super(title); this.setSize(300,300); label = new JLabel("Close the frame."); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { closed(); } }); this.setVisible(true); } public void closed() { System.exit(0); } public static void main(String args[]) { new WindowDemo("Close Window Example"); }}

Comparando com o exemplo anterior, repare que não existe mais a necessidade de implementar os outros métodos do listener deixando-os em branco, implementamos apenas os métodos que realmente iremos utilizar.

Introdução à Programação II 15

Page 361: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Inner ClassNesta seção faremos uma revisão de conceitos que já foram abordados no primeiro módulo do curso. Inner class é muito útil no tratamento de eventos em interfaces gráficas.

6.1. Inner Class

Aqui está uma breve revisão sobre inner class. Uma inner class, como o nome já diz, é uma classe declarada dentro de outra classe. O uso de uma inner class pode auxiliar na simplificação de suas classes, especialmente quanto ao tratamento de eventos, como será mostrado no exemplo a seguir:

import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class WindowDemo extends JFrame { private JLabel label; public WindowDemo(String title) { super(title); this.setSize(300,300); label = new JLabel("Close the frame."); this.addWindowListener(new CFListener()); this.setVisible(true); } private class CFListener extends WindowAdapter { public void windowClosing(WindowEvent e) { closed(); } } public void closed() { System.exit(0); } public static void main(String args[]) { new WindowDemo("Close Window Example"); }}

Introdução à Programação II 16

Page 362: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 9Threads

Versão 1.0 - Mar/2007

Page 363: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Vimos diversas classes que são executadas sequencialmente. Uma classe seqüencial refere-se a uma classe que possui um fluxo de execução. Ela tem um ponto de início de execução, uma seqüência de execução e o final da execução. Possui um único processo sendo executado.

Contudo, numa situação do mundo real, existe a necessidade de capturar processos concorrentes. Sendo que estes processos são executados simultaneamente. Neste ponto entram as threads.

Ao final desta lição, o estudante será capaz de:

• Definir o que são threads• Enumerar os diferentes estados de uma thread• Explicar o conceito de prioridade na thread• Utilizar os métodos da classe Thread• Criar suas próprias threads• Utilizar sincronização para execução de threads concorrentes que sejam independentes

umas das outras• Permitir que as threads se comuniquem umas com as outras concorrentemente em sua

execução• Utilizar as utilidades da concorrência

Introdução à programação II 4

Page 364: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Definição e básico de threads

2.1. Definição de Thread

A thread refere-se a um fluxo seqüencial simples de controle em uma classe. Para simplificar, pense em threads como mais de um processo simultâneo que serão executados paralelamente a partir de um determinado ponto. Considere os modernos sistemas operacionais que permitem rodar vários softwares ao mesmo tempo. Enquanto escrevemos um documento no computador utilizando o editor de texto, podemos escutar uma música, navegar na rede e o relógio do computador continua sendo atualizado. O sistema operacional instalado no seu computador permite o que definiremos como multitarefa. Um aplicativo pode executar diversos processos simultaneamente. Um exemplo deste tipo de aplicação é a HotJava do navegador web, que permite a navegação através de páginas enquanto realizamos downloads de algumas imagens, assistimos animações e ouvimos musicas.

Figura 1: Threads

2.2. Estados da thread

Figura 2: Estados da thread

Uma thread poderá assumir um dos seguintes estados:

• ReadA thread pode ser executada, mas ainda não foi lhe dado à chance. Ou após ter sido bloqueada/suspensa, esta pronta para ser executada.

Introdução à programação II 5

Page 365: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

• RunningA thread esta sendo executada e esta sob controle da CPU.

• SleepingA thread é interrompida por determinado tempo.

• WaitingA thread é interrompida por indeterminado tempo.

• BlockedUma thread bloqueada não é capaz de rodar, pois esta esperando por um recurso disponível ou que algum evento aconteça.

• DeadA thread terminou tudo o que foi ordenada a fazer.

2.3. Prioridades

É possível informar ao controle da CPU que uma thread possui uma prioridade maior sobre outra. A prioridade é um valor inteiro entre 1 e 10. Quanto maior a prioridade da thread, maior a chance de ser executado executada primeiro.

Assumiremos a existência de duas threads e supomos que ambas estejam prontas para rodar. A primeira thread é atribuído atribuída a prioridade 5 (normal) enquanto que a segunda possui a prioridade 10 (máxima). Digamos que a primeira thread esteja executando enquanto que que a segunda esteja pronta para ser executada. Então, a segunda thread poderia receber o controle da CPU e tornar-se executável por possuir a maior prioridade comparada com a thread corrente. Este cenário é um exemplo de troca de contexto.

A troca de contexto ocorre quando uma thread perde o controle da CPU para outra thread. Existem várias formas na qual a troca de contexto pode ocorrer. Um cenário é quando uma thread está sendo executada e voluntariamente cede o controle da CPU para que outra thread tenha oportunidade de ser executada. Neste caso, a thread de maior prioridade que esteja pronta para executar recebe o controle da CPU. Outra forma para que a troca de contexto ocorra é quando uma thread perde seu lugar para outra thread de maior prioridade como visto no exemplo anterior.

É possível que exista mais de uma thread disponível de maior prioridade e prontas para serem executadas. Para decidir qual das threads com a mesma prioridade receberá o controle da CPU isso dependerá do sistema operacional. No Windows 95/98/NT utilizará fracionamento de tempo e revezamento para resolver este caso. Cada thread de mesma prioridade é dado tempo limite para ser executada antes da CPU passar o controle para outra thread de igual prioridade. Por outro lado, o Solaris permite que threads sejam executadas antes de completarem sua tarefa, ou antes, de voluntariamente ceder o controle à CPU.

Introdução à programação II 6

Page 366: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. A classe Thread

3.1. Construtor

A classe Thread possui oito construtores. Vejamos rapidamente alguns destes.

Construtores da Thread

Thread()Cria um novo objeto Thread.

Thread(String name) Cria um novo objeto Thread com um nome específico.

Thread(Runnable target) Cria um novo objeto Thread baseado no objeto Runnable. target refere-se ao objeto no qual o método executado será chamado.

Thread(Runnable target, String name) Cria um novo objeto Thread com um nome específico e baseado no objeto Runnable.

Tabela 1: Construtores Thread

3.2. Constantes

A classe Thread provê constantes para valores de prioridade. Segue a tabela que nos mostra um resumo dos campos da classe Thread.

Constantes Thread

public final static int MAX_PRIORITY O maior valor de uma prioridade, 10.

public final static int MIN_PRIORITY O menor valor de uma prioridade, 1.

public final static int NORM_PRIORITY O valor padrão de uma prioridade, 5.

Tabela 2: Constantes Thread

3.3. Métodos

Aqui estão alguns dos métodos encontrados na classe Thread.

Métodos Thread

public static Thread currentThread() Retorna a referência para a thread corrente que esteja sendo executada.

public final String getName() Retorna o nome da thread.

public final void setName(String name) Renomeia a thread para o argumento especificado name. Poderá lançar SecurityException.

public final int getPriority()

Introdução à programação II 7

Page 367: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Retorna a prioridade atribuída à thread.

public final boolean isAlive() Indica se a thread esta executando ou não.

public final void join([long millis, [int nanos]]) Um método sobrecarregado. A thread corrente que esta sendo executada poderá esperar até que esta thread morra (se nenhum parâmetro for especificado), ou até que tempo especificado transcorra.

public static void sleep(long millis) Suspende a thread por um tempo millis. Poderá lançar InterruptedException.

public void run() A execução da thread inicia com este método.

public void start()Ocasiona o início da execução da thread chamando o método run.

Tabela 3: Métodos Thread

3.4. Um Exemplo de Thread

Neste primeiro exemplo de uma thread, veremos como funciona um contador.

import javax.swing.*;import java.awt.*;

class ThreadDemo extends JFrame { JLabel label; public ThreadDemo(String title) { super(title); label = new JLabel("Start count!"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(label); this.setSize(300,300); this.setVisible(true); } private void startCount() { try { for (int i = 10; i > 0; i--) { Thread.sleep(500); label.setText(i + ""); } label.setText("Count down complete."); } catch (InterruptedException ie) { } label.setText(Thread.currentThread().toString()); } public static void main(String args[]) { new ThreadDemo("Count down GUI").startCount(); }}

A classe CountDownGui conta de 10 a 1 e depois mostra a informação sobre a thread que está sendo executado executada. Estas são algumas telas que foram retiradas enquanto a classe era executada:

Introdução à programação II 8

Page 368: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Figura 3: Telas da classe CountDownGui

Introdução à programação II 9

Page 369: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Criando Threads

Threads podem tanto ser criadas de duas formas, a primeira é herdando a classe Thread (sua classe é uma thread) e a segunda é implementando a interface Runnable (sua classe tem uma thread).

4.1. Herança (estendendo) da classe Thread

Neste próximo exemplo, veremos uma classe que mostra 100 vezes o nome do objeto thread.

class ThreadDemo extends Thread { public ThreadDemo(String name) { super(name); start(); } public void run() { for (int i = 0; i < 100; i++) System.out.print(getName()); } public static void main(String args[]) { ThreadDemo pnt1 = new ThreadDemo("A"); ThreadDemo pnt2 = new ThreadDemo("B"); ThreadDemo pnt3 = new ThreadDemo("C"); ThreadDemo pnt4 = new ThreadDemo("D"); }}

Observe que os objetos pnt1, pnt2, pnt3, e pnt4 são utilizadas uma única vez. Para esta aplicação, não há qualquer necessidade de se utilizar atributos para se referir a cada thread. É possível substituir o corpo do método principal pelas seguintes instruções:

new ThreadDemo("A"); new ThreadDemo("B"); new ThreadDemo("C"); new ThreadDemo("D");

A classe produzirá diferentes saídas em cada execução. Aqui temos um exemplo de uma possível saída:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCD

4.2. Implementando a interface Runnable

Outra forma do usuário para se criar uma thread é implementar a interface Runnable. O único método que a interface Runnable requer que seja implementado é o método "public void run()". Pense neste como o método que a thread executará.

O próximo exemplo é semelhante ao exemplo anterior mostrado:

class ThreadDemo implements Runnable { Thread thread;

Introdução à programação II 10

Page 370: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public ThreadDemo(String name) { thread = new Thread(this, name); thread.start(); } public void run() { String name = thread.getName(); for (int i = 0; i < 100; i++) { System.out.print(name); } } public static void main(String args[]) { new ThreadDemo("A"); new ThreadDemo("B"); new ThreadDemo("C"); new ThreadDemo("D"); }}

4.3. É uma (extends Thread) x Tem uma (implements Runnable)

Estas são as duas únicas formas de se obter threads, escolher entre elas é uma questão de gosto ou de necessidade. Implementar por exemplo a interface Runnable pode ser mais trabalhoso já que ainda teremos que declarar um objeto Thread e comunicar os métodos thread sobre este objeto. Herdar a classe Thread, no entanto, significaria que a classe não poderia mais estender qualquer outra classe, pois Java proíbe heranças múltiplas. Uma troca entre implementação fácil e possibilidade de estender a classe é feita de acordo com o estilo selecionado. Pese o que é mais necessário.

4.4. Utilizando o método join

Agora que já vimos como criar threads, iremos ver como o método join funciona. O exemplo abaixo utiliza o método join sem qualquer argumento. Este método (quando chamado sem argumento) causa a espera da execução da thread corrente até que a thread que chama este método termine a sua execução.

class ThreadDemo implements Runnable { Thread thread; public ThreadDemo(String name) { thread = new Thread(this, name); thread.start(); } public void run() { String name = thread.getName(); for (int i = 0; i < 100; i++) { System.out.print(name); } } public static void main(String args[]) { ThreadDemo t1 = new ThreadDemo("A"); ThreadDemo t2 = new ThreadDemo("B"); ThreadDemo t3 = new ThreadDemo("C"); ThreadDemo t4 = new ThreadDemo("D"); System.out.println("Running threads..."); try { t1.thread.join(); t2.thread.join(); t3.thread.join();

Introdução à programação II 11

Page 371: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

t4.thread.join(); } catch (InterruptedException ie) { } System.out.println("\nThreads killed."); //printed last! }}

Execute esta classe. O que notamos? Através da chamada do método join, temos a certeza que o último trecho foi executado até a última parte.

Aqui está um exemplo de saída da execução do código:

Running Threads…AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDBCDBCDBCDBCBCBCBCBCBCDBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCThreads killed.

Comente o bloco try-catch onde o método join foi executado. Existe alguma diferença na saída da classe?

Introdução à programação II 12

Page 372: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Sincronização

Até agora, temos visto exemplos de threads que estão sendo executadas concorrentemente, mas são independentes umas da outras. Ou seja, threads que são executadas no seu próprio ritmo sem a preocupação pelo status ou pelas atividades de outras threads que são executadas concorrentemente. Desta forma, cada thread não requer qualquer fonte ou método externo e, como resultado, não precisa se comunicar com outras threads.

Em muitas situações, executar threads concorrentemente pode requerer fontes e métodos externos. Assim, existe a necessidade de se comunicar com outras threads executadas concorrentemente para saber seus status e atividades. Um exemplo neste cenário é o problema produtor-consumidor. O problema envolve dois objetos principais, um que funcionará como um produtor gerando valores ou dados e outro como consumidor para receber ou consumir estes valores.

5.1. Um exemplo não sincronizado

Vejamos a seguinte classe que mostra uma seqüência de Strings em uma ordem específica:

class TwoStrings { static void print(String str1, String str2) { System.out.print(str1); try { Thread.sleep(500); } catch (InterruptedException ie) { } System.out.println(str2); }}class PrintStringsThread implements Runnable { Thread thread; String str1, str2; PrintStringsThread(String str1, String str2) { this.str1 = str1; this.str2 = str2; thread = new Thread(this); thread.start(); } public void run() { TwoStrings.print(str1, str2); }}class ThreadDemo { public static void main(String args[]) { new PrintStringsThread("Hello ", "there."); new PrintStringsThread("How are ", "you?"); new PrintStringsThread("Thank you ", "very much!"); }}

É esperado que a classe mostre dois argumentos dos objetos Runnable consecutivamente. O problema, no entanto, é que a invocação do método sleep acarreta a execução de outras threads quando alguma outra thread ainda não terminou com a execução do método print da classe TwoStrings. Aqui está um exemplo de saída:

Hello How are Thank you there.you?

Introdução à programação II 13

Page 373: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

very much!

Nesta execução, as três threads devem ter seus primeiros argumentos mostrados antes dos segundos argumentos. Isto resulta em uma saída oculta.

Na verdade, o este exemplo não coloca um problema muito sério, mas para outras aplicações, isto pode ocasionar algumas exceções ou problemas.

5.2. Travando um objeto

Para garantir que apenas uma thread tenha acesso a um método, Java permite travar um objeto incluindo seus métodos com o uso de monitores. O objeto entra com o monitor implícito quando a sincronização de métodos é invocada. Assim que um objeto estiver sendo monitorado, o monitor garante que nenhuma outra thread acesse o mesmo método. Como conseqüência, isso garante que apenas uma thread por vez irá executar o método do objeto.

Para sincronizar um método, utilizamos a palavra-chave synchronized na assinatura do método. Neste caso não podemos modificar o código fonte da definição do método, podemos sincronizar o objeto no qual o método pertence. A sintaxe para sincronizar um objeto é a seguinte:

synchronized (<object>) { //trecho de código a ser sincronizado}

Com isso, os métodos do objeto podem ser invocados uma vez por thread.

5.3. Primeiro Exemplo Sincronizado

Aqui esta o código modificado onde o método print da classe TwoString está sincronizado.

class TwoStrings { synchronized static void print(String str1, String str2) { System.out.print(str1); try { Thread.sleep(500); } catch (InterruptedException ie) { } System.out.println(str2); }}

class PrintStringsThread implements Runnable { Thread thread; String str1, str2; PrintStringsThread(String str1, String str2) { this.str1 = str1; this.str2 = str2; thread = new Thread(this); thread.start(); } public void run() { TwoStrings.print(str1, str2); }}

class ThreadDemo { public static void main(String args[]) { new PrintStringsThread("Hello ", "there."); new PrintStringsThread("How are ", "you?"); new PrintStringsThread("Thank you ", "very much!");

Introdução à programação II 14

Page 374: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

}}

A classe agora produz os trechos corretos:

Hello there.How are you?Thank you very much!

5.4. Segundo Exemplo Sincronizado

Esta é uma outra versão da classe anterior. O método print da classe TwoString está sincronizado. Porém, ao invés de utilizar a palavra reservada synchronized no método, está sendo aplicado no objeto.

class TwoStrings { static void print(String str1, String str2) { System.out.print(str1); try { Thread.sleep(500); } catch (InterruptedException ie) { } System.out.println(str2); }}

class PrintStringsThread implements Runnable { Thread thread; String str1, str2; TwoStrings ts; PrintStringsThread(String str1, String str2, TwoStrings ts) { this.str1 = str1; this.str2 = str2; this.ts = ts; thread = new Thread(this); thread.start(); } public void run() { synchronized (ts) { ts.print(str1, str2); } }}

class TestThread { public static void main(String args[]) { TwoStrings ts = new TwoStrings(); new PrintStringsThread("Hello ", "there.", ts); new PrintStringsThread("How are ", "you?", ts); new PrintStringsThread("Thank you ", "very much!", ts); }}

A classe também mostrará os trechos corretos.

Introdução à programação II 15

Page 375: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Comunicação entre threads

Nesta seção, iremos aprender sobre os métodos básicos utilizados para permitir a comunicação entre threads concorrentementes enquanto são executadas.

Métodos para Comunicação entre threads

public final void wait()Faz com que esta thread espere até que outra chame o método notify ou notifyAll neste objeto. Poderá lançar InterruptedException.

public final void notify()Torna executável a thread que teve o método wait chamado neste objeto.

public final void notifyAll()Torna executáveis as threads que tiveram o método wait chamado neste objeto.

Tabela 4: Método para Comunicação entre Threads

Para facilitar o entendimento destes métodos, vamos considerar o cenário garçom/cliente. No restaurante, o garçom espera (waits) que o cliente faça um pedido, ao invés de estar sempre perguntado se alguém deseja fazer um pedido. Quando o cliente entra, significa que o cliente está interessado na comida do restaurante. Desta forma, o cliente ao entrar no restaurante notifica (notifies) o garçom que irá necessitar dos seus serviços. Contudo, nem sempre o cliente está preparado para fazer um pedido. Seria chato se garçom ficasse continuamente perguntando ao cliente se o mesmo deseja fazer o pedido. Então, o garçom aguarda o cliente notificá-lo (notifies) que está pronto. Uma vez que o cliente entregou o pedido, seria um incomodo continuar importunando o garçom se o seu pedido já está entregue. Normalmente o cliente aguarda o garçom notificá-lo (notifies) servindo a comida.

Observe neste cenário que a parte que aguarda é executada assim que o cliente informa o garçom. O mesmo é verdade nas threads.

Figura 4: Cenário Cliente/Garçom

Introdução à programação II 16

Page 376: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6.1. Exemplo Produtor-Consumidor

O seguinte exemplo é uma implementação do problema Produtor-Consumidor. A classe que provê métodos para gerar e consumir um valor inteiro são separadas as classes threads Produtor e Consumidor

class SharedData { int data; synchronized void set(int value) { System.out.println("Generate " + value); data = value; } synchronized int get() { System.out.println("Get " + data); return data; }}

class Producer implements Runnable { SharedData sd; Producer(SharedData sd) { this.sd = sd; new Thread(this, "Producer").start(); } public void run() { for (int i = 0; i < 10; i++) { sd.set((int)(Math.random()*100)); } }}

class Consumer implements Runnable { SharedData sd; Consumer(SharedData sd) { this.sd = sd; new Thread(this, "Consumer").start(); } public void run() { for (int i = 0; i < 10 ; i++) { sd.get(); } }}class ProducerConsumerDemo { public static void main(String args[]) throws Exception { SharedData sd = new SharedData(); new Producer(sd); new Consumer(sd); }}

Este é um exemplo da saída desta classe:

Generate 8Generate 45Generate 52Generate 65Get 65Generate 23

Introdução à programação II 17

Page 377: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Get 23Generate 49Get 49Generate 35Get 35Generate 39Get 39Generate 85Get 85Get 85Get 85Generate 35Get 35Get 35

Isto não é o que gostaríamos que a classe produzisse. Para todos os valores produzidos pelo produtor, nós esperamos que o consumidor obtenha cada valor. Aqui está uma saída que seria desejável:

Generate 76Get 76Generate 25Get 25Generate 34Get 34Generate 84Get 84Generate 48Get 48Generate 29Get 29Generate 26Get 26Generate 86Get 86Generate 65Get 65Generate 38Get 38Generate 46Get 46

Para consertar o problema com este código, utilizamos os métodos de comunicação entre threads. A seguinte implementação do problema Produtor-Consumidor utiliza os métodos para comunicação entre as threads.

class SharedData { int data; boolean valueSet = false; synchronized void set(int value) { if (valueSet) { //has just produced a value try { wait(); } catch (InterruptedException ie) { } } System.out.println("Generate " + value); data = value; valueSet = true; notify(); }

Introdução à programação II 18

Page 378: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

synchronized int get() { if (!valueSet) { //producer hasn't set a value yet try { wait(); } catch (InterruptedException ie) { } } System.out.println("Get " + data); valueSet = false; notify(); return data; }}

/* A parte remanescente do código não muda. */class Producer implements Runnable { SharedData sd; Producer(SharedData sd) { this.sd = sd; new Thread(this, "Producer").start(); } public void run() { for (int i = 0; i < 10; i++) { sd.set((int)(Math.random()*100)); } }}

class Consumer implements Runnable { SharedData sd; Consumer(SharedData sd) { this.sd = sd; new Thread(this, "Consumer").start(); } public void run() { for (int i = 0; i < 10 ; i++) { sd.get(); } }}

class TestProducerConsumer { public static void main(String args[]) throws Exception { SharedData sd = new SharedData(); new Producer(sd); new Consumer(sd); }}

Introdução à programação II 19

Page 379: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Utilidades concorrentesCom a versão do J2SE 5.0, o novo controle de threads e das suas características concorrentes foram adicionados à Java. Estas novas características são encontradas no pacote java.util.concurrent. Nesta seção, duas destas características concorrentes serão vistas.

7.1. A Interface Executor

Uma das mais importantes características herdadas para desenvolver aplicações multi-thread é o framework Executor. A interface é incluída no pacote java.util.concurrent. Objetos deste tipo executam tarefas do tipo Runnable.

Sem o uso desta interface, executamos tarefas do tipo Runnable criando instâncias Thread e chamando o método start do objeto Thread. O seguinte código demonstra uma forma de fazer isso:

new Thread(<aRunnableObject>).start();

Com a disponibilidade desta nova interface, objetos Runnable submetidos são executados usando o método execute como a seguir:

<anExecutorObject>.execute(<aRunnableObject>);

O novo framework Executor é útil para aplicações multithread. Visto que a thread necessita da pilha de alocação dinâmica de memória, a criação de threads pode ser relativamente cara. Como resultado, a criação de várias threads pode causar um erro pela falta de memória. Uma forma de resolver este problema é com um pool de threads. No pool de threads, uma thread ao invés de morrer é enfileirada no pool após completar a sua tarefa designada. No entanto, implementar um esquema bem projetado de pool de thread não é simples. Outro problema é a dificuldade em cancelar e terminar as threads.

O framework Executor resolve estes problemas desacoplando à submissão de tarefas do mecanismo de como cada tarefa será executado executada, incluindo detalhes do uso de threads, agendamento e outros. Ao invés de criação e execução da thread através do métodos start para cada tarefa, ele é mais cauteloso, utilizar o seguinte fragmento de código:

Executor <executorName> = <anExecutorObject>;<executorName>.execute(new <RunnableTask1>());<executorName>.execute(new <RunnableTask2>());...

Visto Executor ser uma interface, esta não pode ser instanciada. Para criar um objeto de Executor, deve-se criar uma classe implementando esta interface ou utilizar um método de fábrica disponível na classe Executors. Esta classe também está disponível no mesmo pacote da interface. A classe Executors provê métodos para o gerenciamento do pool de threads. Aqui esta um resumo destes métodos de fábrica:

Métodos de Fábrica da classe Executorspublic static ExecutorService newCachedThreadPool()Cria um pool de thread que cria novas thread threads quando necessário, porém reutilizará threads previamente construídas quando disponíveis. Existe um método sobrescrito, que aceita com como parâmetro um objeto ThreadFactory.public static ExecutorService newFixedThreadPool(int nThreads)Cria um pool de thread que reutiliza uma lista fixa de threads operando em segundo plano de uma fila ilimitada. Um método sobrescrito, o qual recebe um objeto ThreadFactory como parâmetro adicional.

Introdução à programação II 20

Page 380: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)Cria um pool de thread que pode programar comando para serem executados após um período de tempo, ou periodicamente. Um método sobrescrito, o qual recebe um objeto ThreadFactory como parâmetro adicional. public static ExecutorService newSingleThreadExecutor()Cria um Executor que utiliza uma thread simples que trabalha operando em segundo plano de uma fila ilimitada. Um método sobrescrito, o qual recebe um objeto ThreadFactory como parâmetro adicional.public static ScheduledExecutorService newSingleThreadScheduledExecutor()Cria uma simples thread executora que pode programar comando a serem executados após um período de tempo, ou periodicamente. Um método sobrescrito, o qual recebe um objeto ThreadFactory como parâmetro adicional.

Tabela 5: Métodos de Fábrica da classe Executor

A tarefa Runnable é executada e finalizada sob o controle da interface Executor. Para parar threads, podemos invocar o método shutdown da interface como segue:

executor.shutdown();

7.2. A Interface Callable

Existem duas formas de se criar threads. Podemos tanto estender a classe Thread ou implementar a interface Runnable. Em qualquer técnica utilizada, customizamos as funcionalidades sobrescrevendo o método run. O método possui a seguinte assinatura:

public void run()

Os malefícios em se criar threads desde modo são:

1. O método run não permite retornar um resultado, pois seu tipo de retorno é void.2. Requer que seja capturado as exceções verificáveis, visto ser um método a ser implementado

e não possuir a cláusula throws.

A interface Callable é basicamente a mesma da interface Runnable sem estes problemas. Devemos utilizar outro mecanismo para obter o resultado de uma tarefa Runnable. Uma técnica seria utilizar uma variável de instância para armazenar o resultado. A classe a seguir mostra como isso pode ser feito.

public MyRunnable implements Runnable { private int result = 0; public void run() { ... result = someValue; } public int getResult() { return result; }}

Vejamos como obter o resultado com a utilização da interface Callable:

import java.util.concurrent.*;

public class MyCallable implements Callable { public Integer call() throws java.io.IOException { ...

Introdução à programação II 21

Page 381: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

return someValue; }}

O método call possui a seguinte assinatura:

<V> call() throws Exception

Onde <V> é um tipo genérico, que significa que o tipo de retorno do método call poderá ser uma referencia a qualquer tipo. Futuramente iremos aprender mais sobre tipos genéricos (generics).

Introdução à programação II 22

Page 382: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 10Redes

Versão 1.0 - Mar/2007

Page 383: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. ObjetivosA linguagem Java permite que facilmente sejam criadas aplicações que desempenham diversas tarefas através de uma rede. Esse é um dos principais benefícios de Java, uma vez que a linguagem foi criada tendo em vista seu uso para a Internet. Antes de aprender sobre o uso e a funcionalidade Java em redes, devemos ter conhecimento de alguns conceitos básicos de redes.

Ao final desta lição, o estudante será capaz de:

• Explicar os conceitos básicos de redes• Endereço IP• Protocolo• Portas• Paradigma Cliente/Servidor• Sockets

• Criar aplicações usando o pacote de Java para redes• As classes ServerSocket e Socket • As classes MulticastSocket e DatagramPacket

Introdução à Programação II 4

Page 384: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Conceitos Básicos sobre Redes

A Internet é uma rede mundial que reúne diferentes tipos de computadores que são interligados de diversas maneiras. Apesar da diversidade de hardware e software interconectados, é extraordinário como a Internet permanece interconectada (funcional). Isso é possível devido aos padrões de comunicação definidos e respeitados. Esses padrões asseguram a compatibilidade e a confiabilidade de comunicação entre uma ampla diversidade de sistemas na Internet. Vejamos alguns desses padrões.

2.1. Endereço IP

Cada um dos computadores conectados à Internet tem um único endereço IP. Do ponto de vista lógico, o endereço IP é similar ao tradicional endereço para correspondência enviada pelos correios, conhecido como CEP, no sentido de que um endereço identifica unicamente um determinado objeto. O endereçamento IP é um número de 32 bits usado para identificar exclusivamente cada computador conectado à Internet. O número 192.1.1.1 é um exemplo de um endereço IP. Esses endereços podem também ser expressos em formato símbólico, como por exemplo: docs.rinet.ru.

2.2. Protocolo

Uma vez que existem muitos tipos de comunicações que ocorrem ativamente na Internet, é necessário existir um número igual de mecanismos para dar conta deles. Cada tipo de comunicação exige um protocolo específico e único.

Um protocolo refere-se a um conjunto de regras e padrões que definem um certo tipo de comunicação via Internet. O protocolo descreve o formato dos dados enviados através da Internet, juntamente com as informações de como e quando está sendo enviado.

Na realidade, o conceito de protocolo não é novo. Considere quantas vezes estivemos envolvidos neste tipo de conversação:

"Alô""Alô. Eu poderia falar com Joana?""Aguarde um momento, por favor""Obrigado"

Esse é um protocolo social usado quando se trata de uma conversa telefônica. Esse tipo de protocolo nos proporciona confiança e familiaridade sobre como nos comportarmos em determinadas situações.

Examinemos agora alguns protocolos importantes usados na Internet. Sem dúvida, o Hypertext Transfer Protocol (HTTP, ou Protocolo de Transferência de Hipertexto) é um dos protocolos mais comumente usados. Ele é usado para transferir documentos HTML na Web. Existe também o File Transfer Protocol (FTP, ou Protocolo de Transferência de Arquivos), que geralmente é conhecido, em comparação com o HTTP; e permite que seja transferido arquivos binários pela Internet. Os dois protocolos têm seu próprio conjunto de regras e padrões de como os dados sobre transferência de dados. Java dá suporte a ambos os protocolos.

2.3. Portas

Note que os protocolos somente fazem sentido quando usados no contexto de um serviço. Por exemplo, o protocolo HTTP é usado quando se está disponibilizando conteúdo de Web através de um serviço HTTP. Cada computador na Internet pode disponibilizar uma diversidade de serviços

Introdução à Programação II 5

Page 385: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

por meio dos diversos protocolos suportados. O problema, porém, é que o tipo de serviço que precisa ser conhecido, antes que as informações possam ser transferidas. É nesse contexto que as portas são relevantes.

Uma porta é um número de 16 bits que identifica cada serviço oferecido por um servidor de rede. Para usar determinado serviço, e portanto estabelecer uma linha de comunicação e conexão por meio de um protocolo específico, é necessário conectar-se à porta apropriada. As portas são associadas a um número, e alguns desses números são especificamente associados a um determinado tipo de serviço. Essas portas às quais são alocados serviços específicos são denominadas portas padrão. Por exemplo, o serviço FTP está localizado na porta 21, o passo que, enquanto o serviço HTTP está localizado na porta 80. Ao necessitar executar uma transferência de arquivo via FTP, é imprescindível conectar-se à porta 21 do servidor. Todos os serviços alocados de forma padrão são atribuídos a valores de portas abaixo de 1024. Os valores de portas acima de 1024 são disponíveis para comunicações personalizadas. Caso um valor de porta acima de 1024 já esteja em uso por alguma comunicação personalizada, deve-se procurar outros valores ociosos.

2.4. O Paradigma Cliente/Servidor

O Paradigma Cliente/Servidor é à base das aplicações de redes em Java. Evidentemente, esse esquema compreende dois elementos principais, o cliente e o servidor. O termo cliente refere-se à máquina que necessita algum tipo de informação, ao passo que o servidor é a máquina onde essa informação está armazenada, aguardando para ser fornecida.

O paradigma descreve um cenário simples. Normalmente, um cliente conecta-se a um servidor para consultar determinada informação. O servidor então analisa a consulta e retorna a informação nele disponível para o cliente.

Figure 1: Client/Server model

2.5. Sockets

O último conceito geral de redes que iremos abordar antes de mergulhar em redes em Java relaciona-se com a classe sockets. A maior parte da programação em Java para redes é utilizado um determinado tipo de comunicação em rede denominada sockets.

Socket é uma abstração, na forma de software, para um meio de entrada ou saída de comunicação. É por meio do uso de sockets que a linguagem Java executa toda a sua comunicação de baixo nível em redes. Os sockets são canais de comunicação que permitem a transferência de dados através de uma determinada porta; em resumo, um socket refere-se a uma porta-fim (endpoint) para comunicação entre duas máquinas.

Introdução à Programação II 6

Page 386: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. O Pacote Java para RedesO java.net package oferece classes especificas para o desenvolvimento de aplicações para redes. Para obter uma lista completa de classes e interfaces relacionadas com redes, por favor, consulte a documentação da API de Java. Vamos nos concentrar nestas quatro classes: ServerSocket, Socket, MulticastSocket, e DatagramPacket.

3.1. As Classes ServerSocket e Socket

A Classe ServerSocket disponibiliza as funcionalidades básicas de um servidor. A tabela a seguir descreve dois dos quatro construtores da classe ServerSocket:

Construtores da classe ServerSocket

ServerSocket(int port) Instancia um servidor que é vinculado à porta especificada. Uma porta 0 aloca o servidor a qualquer porta ociosa. Por default, o comprimento máximo de fila para conexão (chegando) é fixado (como igual a) em 50.

ServerSocket(int port, int backlog) Parâmetro backlog (fila acumulada).

Table 1: ServerSocket constructors

Abaixo segue alguns dos métodos desta classe:

Métodos da classe ServerSocket

public Socket accept() Faz com que o servidor aguarde e escute conexões de clientes, e então as aceite.

public void close() Fecha o socket do servidor. Uma vez fechado o socket, os clientes não podem mais conectar-se ao servidor, a menos que o socket seja aberto novamente.

public int getLocalPort() Retorna a porta à qual o socket está vinculado.

public boolean isClosed() Indica se o socket está fechado ou não.

Table 2: ServerSocket methods

O exemplo a seguir é uma implementação de um servidor simples, que simplesmente ecoa a informação enviada pelo cliente.

import java.net.*;import java.io.*;

public class EchoingServer { public static void main(String[] args) { ServerSocket server = null; Socket client; try { server = new ServerSocket(1234); // 1234 é um número de porta não utilizado } catch (IOException ie) { System.out.println("O socket não pode ser aberto."); System.exit(1);

Introdução à Programação II 7

Page 387: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

} while(true) { try { client = server.accept(); OutputStream clientOut = client.getOutputStream(); PrintWriter pw = new PrintWriter(clientOut, true); InputStream clientIn = client.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(clientIn)); pw.println(br.readLine()); } catch (IOException ie) { } } }}

A classe ServerSocket implementa socket de servidor e a classe Socket implementa um socket de cliente. A classe Socket possui oito construtores, dos quais dois já foram descartados. Examinemos brevemente dois desses construtores.

Construtores da classe Socket

Socket(String host, int port)Cria um socket de cliente que se conecta ao número fornecido de porta no host especificado.

Socket(InetAddress address, int port) Cria um socket de cliente que se conecta ao número fornecido de porta, no endereço IP especificado.

Table 3: Socket constructors

Segue alguns métodos da classe:

Métodos da classe Socket

public void close() Fecha o socket cliente.

public InputStream getInputStream() Recupera o fluxo de entrada associado a esse socket.

public OutputStream getOutputStream() Recupera o fluxo de saída associado a esse socket.

public InetAddress getInetAddress() Retorna o endereço de IP ao qual o socket está conectado

public int getPort() (Returna) Retorna a porta remota à qual este socket está conectado.

public boolean isClosed() Indica se o socket está fechado ou não.

Table 4: Socket methods

O exemplo a seguir é uma implementação de um cliente simples, que apenas envia dados para um servidor.

Introdução à Programação II 8

Page 388: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

import java.io.*;import java.net.*;

public class MyClient { public static void main(String args[]) { try { Socket client = new Socket(InetAddress.getLocalHost(), 1234); InputStream clientIn = client.getInputStream(); OutputStream clientOut = client.getOutputStream(); PrintWriter pw = new PrintWriter(clientOut, true); BufferedReader br = new BufferedReader(new InputStreamReader(clientIn)); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Digite uma mensagem para o servidor: "); pw.println(stdIn.readLine()); System.out.println("Mensagem do Servidor: "); System.out.println(br.readLine()); pw.close(); br.close(); client.close(); } catch (ConnectException ce) { System.out.println("Não foi possível se conectar ao servidor."); } catch (IOException ie) { System.out.println("Erro de I/O."); } }}

A execução de EchoingServer deixa-o pronto para aceitar mensagens do cliente. Depois que um cliente, como MyClient, envia uma mensagem ao servidor, o servidor devolve a mensagem de volta para o cliente. Abaixo, um exemplo da execução de MyClient depois da inicialização de EchoingServer:

Digite uma mensagem para o servidor: Primeira mensagem para o servidorMensagem do Servidor: Primeira mensagem para o servidor

3.2. As Classes MulticastSocket e DatagramPacket

A classe MulticastSocket é útil para aplicações que implementam comunicações em grupos. Os endereços IP para um grupo multicast ficam na faixa de 224.0.0.0 a 239.255.255.255. Entretanto, o endereço 224.0.0.0 é reservado, e não deve ser usado. Essa classe tem três construtores, mas consideraremos, aqui, apenas um desses construtores.

Construtores da classe MulticastSocket

MulticastSocket(int port) Cria um multicast socket vinculado ao número de porta fornecido.

Tabela 1.5: Construtor de MulticastSocket

A tabela abaixo dá uma descrição de alguns métodos de MulticastSocket.

Métodos da classe MulticastSocket

public void joinGroup(InetAddress mcastaddr) Entrar em um grupo multicast no endereço especificado.

Introdução à Programação II 9

Page 389: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public void leaveGroup(InetAddress mcastaddr) Sair de um a grupo multicast no endereço especificado.

public void send(DatagramPacket p)Um método herdado da classe DatagramSocket. Envia um pacote a partir desse socket.

Tabela 5: Métodos de MulticastSocket

Antes que alguém possa enviar uma mensagem para um grupo, é preciso primeiro ser um membro do grupo multicast usando o método joinGroup. Um membro pode então enviar mensagens usando o método send. Depois que você tiver terminado de falar com o grupo, poderá usar o método leaveGroup para encerrar sua participação no grupo.

Antes de examinar um exemplo de uso da classe MulticastSocket, vamos antes dar uma olhada rápida na classe DatagramPacket. Observe que no método send da classe MulticastSocket, o parâmetro necessário é um objeto DatagramPacket. Assim, precisamos compreender esse tipo de (objetos) objeto, antes de usar o método send.

A classe DatagramPacket é usada para enviar dados por intermédio de um protocolo sem conexão, como um multicast. Um problema nisso é que o envio de pacotes não é garantido. Consideremos, agora, dois de seus seis construtores.

Construtores da classe DatagramPacket

DatagramPacket(byte[] buf, int length) Constrói um pacote datagrama para receber pacotes com um comprimento length. length precisa ser menor ou igual ao tamanho do buffer buf.

DatagramPacket(byte[] buf, int length, InetAddress address, int port) Constrói um pacote datagrama para enviar pacotes com um comprimento length para a porta de número especificado, no hospedeiro especificado.

Tavela 6: Construtores de datagramPacket

Segue alguns métodos interessantes da classe DatagramPacket.

Métodos da classe DatagramPacket

public byte[] getData() Retorna o buffer no qual dados foram armazenados.

public InetAddress getAddress() Retorna o endereço IP da máquina para onde o pacote está sendo enviado ou de onde foi recebido.

public int getLength() Retorna o comprimento dos dados que estejam sendo enviados ou recebidos.

public int getPort() Retorna o número da porta no hospedeiro remoto para onde os pacotes estão sendo enviados ou de onde foram recebidos.

Table 7: Métodos deDatagramPacket

Nosso exemplo de multicast também consiste em duas classes, uma servidora e uma cliente. A servidora recebe mensagens do cliente e imprime essas mensagens.

Aqui está a classe servidora.

Introdução à Programação II 10

Page 390: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

import java.net.*;

public class ChatServer { public static void main(String args[]) throws Exception { MulticastSocket server = new MulticastSocket(1234); InetAddress group = InetAddress.getByName("234.5.6.7"); //getByName - retorna o endereço IP dado para o host server.joinGroup(group); boolean infinite = true; /* O servidor recebe continuamente os dados e imprimindo-os */ while(infinite) { byte buf[] = new byte[1024]; DatagramPacket data = new DatagramPacket(buf, buf.length); server.receive(data); String msg = new String(data.getData()).trim(); System.out.println(msg); } server.close(); }}

Aqui está a classe cliente.

import java.net.*;import java.io.*;

public class ChatClient { public static void main(String args[]) throws Exception { MulticastSocket chat = new MulticastSocket(1234); InetAddress group = InetAddress.getByName("234.5.6.7"); chat.joinGroup(group); String msg = ""; System.out.println("Digite uma mensagem ao servidor:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); msg = br.readLine(); DatagramPacket data = new DatagramPacket(msg.getBytes(), 0, msg.length(), group, 1234); chat.send(data); chat.close(); }}

Aqui está uma amostra de execução das classes ChatServer e ChatClient, assumindo que ChatServer foi executada antes de rodarmos a classe cliente:

/* Executando a classe ChatServer para mostrar as mensagens aceitas do cliente */

/* Executando ChatClient – simplesmente passe as mensagens para o servidor */Digite a mensagem para o Servidor:Primeira mensagem para o Servidor

/* A classe ChatServer recebe e mostra as mensagens dos clientes */Primeira mensagem do Servidor

/* Executando ChatClient novamente */Digite a mensagem para o Servidor:Segunda mensagem para o Servidor

Introdução à Programação II 11

Page 391: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

/* A classe ChatServer recebe e mostra a mensagem do cliente */Segunda mensagem do Servidor

Introdução à Programação II 12

Page 392: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 11Applets

Versão 1.0 - Mar/2007

Page 393: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. ObjetivosApplets é uma das variedades mais interessantes de Java. Refere-se a aplicativos que são executados por meio de um navegador de Internet. Iremos conhecer mais sobre como criar applets nessa lição.

Ao final desta lição, o estudante será capaz de:

• Definir o que é uma applet

• Criar sua própria applet

• Explicar o ciclo de vida de uma applet

• Utilizar os métodos das applets

• Métodos para mostrar a applet

• Métodos para reproduzir clipes de áudio

• Utilizar a tag applet de HTML

Introdução à Programação II 4

Page 394: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Criando AppletsUma applet é um tipo especial de classe Java que é executado pela Internet. É normalmente executada por um navegador de Internet, tipo: Netscape Navigator, Mozilla ou Microsoft Internet Explorer. No entanto, comparada com outras aplicações Java, applets não tem acesso ao computador na qual está sendo executada por razões de segurança. Isso faz com que applets sejam bastante restritas se comparadas com outras aplicações Java.

2.1. Hello World Applet

A classe Applet é uma subclasse da classe Panel definida na AWT. A melhor forma de entender como criar uma applet, é através de exemplos. Então, aqui está uma simples applet que mostra a mensagem "Hello world!".

import java.awt.*;import java.applet.*;

public class AppletDemo extends Applet { public void paint(Graphics g) { g.drawString("Hello world!", 80, 25); }}

Depois da compilação, tente rodar esse exemplo usando o comando: java AppletDemo. O que acontece? Lembre-se que as applets são aplicações Java especiais. Elas não são executadas utilizando o comando java. Em vez disso, a applet é executada por um navegador de internet ou através de um aplicativo denominado appletviewer. Para executar a applet através de um navegador de Internet, crie uma página HTML utilizando a tag Applet da linguagem HTML. Para isso, crie uma arquivo com a extensão .html contendo o seguinte código:

<applet code="AppletDemo" width=300 height=100></applet>

A tag no exemplo dado, indica que uma applet seja criada com a largura de 300 pixels e altura de 100 pixels. Então, o método drawString desenha a frase "Hello world!" na posição em pixels (80,25) contando para baixo e depois à direita.

Figura 1: exemplo de Applet

Outra forma de executar uma applet é através do aplicativo appletviewer. Simplesmente siga essa sintaxe:

appletviewer <nome do arquivo java>

Introdução à Programação II 5

Page 395: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Por exemplo, para executar o exemplo da applet, digite em uma janela de console:

appletviewer AppletDemo.java

Ao se criar uma applet, é necessário extender a classe Applet. Como foi mencionado previamente, essa classe é encontrada no pacote java.applet. Portanto, é extremamente necessário importar o pacote java.applet. Além disso, foi mencionado anteriormente que a classe Applet é uma subclasse da classe Panel. Isso implica que alguns métodos da classe Applet são encontradas na classe Panel. Para acessar os métodos ou campos na classe Panel ou outras classes ancestrais, será necessário importar o pacote java.awt.

Introdução à Programação II 6

Page 396: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Métodos da AppletEsta secção demonstrará alguns métodos de Applets extremamente interessantes

3.1. O ciclo de vida de uma Applet

Em vez de começar a execução no método main como uma aplicação Java típica, o navegador ou o aplicativo appletviewer com a applet através dos seguintes métodos:

1.init()init é o primeiro metódo chamado. Ele é chamado assim que a applet for carregada.

2.start()Após chamar o método init, start é o próximo método chamado. Ele é chamado cada vez que a página HTML da applet é exibida. Quando a applet é reexibido, a execução começa com esse método.

3.stop()Quando o navegador de Internet sai da página HTML do applet, esse método é chamado para informar ao applet que ele deve interromper sua execução.

4.destroy()Esse método é chamado quando o applet precisa ser completamente removido da memória. O método stop é sempre chamado antes que esse método seja chamado.

Quando criamos applets, pelo menos alguns desses métodos devem ser overriden. O exemplo seguinte de applet realiza este processo:

import java.applet.*;import java.awt.*;

public class LifeCycleDemo extends Applet { String msg =""; public void init() { msg += "initializing... "; repaint(); } public void start() { msg += "starting... "; repaint(); } public void stop() { msg += "stopping... "; repaint(); } public void destroy() { msg += "preparing for unloading... "; repaint(); } public void paint(Graphics g) { g.drawString(msg, 15, 15); }}

A seguir temos um exemplo de um documento HTML embutido com um applet LifeCycleDemo.

<HTML><TITLE>Life Cycle Demo</TITLE>

Introdução à Programação II 7

Page 397: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

<applet code="LifeCycleDemo" width=300 height=100> </applet></HTML>

3.2. Método paint

Outro importante método é o paint, que a classe Applet herda de sua classe ancestral Component. Este método é chamado toda vez que a saída da applet precisa ser redesenhada. Um exemplo deste comportamento é quando a applet, escondido por outra janela e fica visível novamente. Esse método pode ser substituído quando for necessário customizar a aparência da applet. No exemplo para a classe AppletDemo, onde é mostrada a mensagem "Hello world!" no fundo depois de ter substituído o método paint.

3.3. Método showStatus

Applet tem uma janela de status, que informa o que ela está fazendo no momento. Se for necessário mostrar alguma mensagem na janela de status, chame o método showStatus. O exemplo a seguir é identico ao AppletDemo, entretanto com comandos adicinais que modificam o conteúdo da janela de status.

import java.awt.*;import java.applet.*;

public class AppletDemo extends Applet { public void paint(Graphics g) { g.drawString("Hello world!", 80, 25); showStatus("This is an important information."); }}

A seguir, o resultado do exemplo:

Figura 2: exempo showStatus()

3.4. Reproduzindo clipes de Áudio

Applets também são providas de métodos que permitem reproduzir arquivos de áudio. Reproduzir clipes de áudio em uma applet envolve as seguintes etapas:

1. Obter o clipe de áudio usando o método getAudioClip.2. Para reproduzir o clipe de áudio, use o método play ou o método loop no objeto do clipe

de áudio. 3. O método play permite a reprodução única do áudio, enquanto que o método loop

reproduz o áudio continuamente, parando apenas quando o método stop for chamado.

O próximo exemplo reproduz continuamente um áudio até que o método stop da applet seja

Introdução à Programação II 8

Page 398: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

acionado.

import java.awt.*;import java.applet.*;

public class AudioApplet extends Applet { AudioClip ac; public void init() { try { /* clipe de audio foi salvo no mesmo diretório do código java */ /* spaceMusic foi baixado de java.sun.com */ ac = getAudioClip(getCodeBase(), "spaceMusic.au"); ac.loop(); } catch (Exception e) { System.out.println(e); } } public void stop() { ac.stop(); } public void paint(Graphics g) { g.drawString("Playing space music!", 80, 25); }}

Introdução à Programação II 9

Page 399: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Applet HTML TagsNos exemplos anteriores, foi mostrado como a tag HTML de applet é utilizada nas páginas HTML ou no fonte Java. Agora, veremos à forma mais completa da tag HTML para applet.

<APPLET [CODEBASE = codebaseURL] CODE = appletFile [ATL = alternateText] [NAME = appletInstanceName] WIDTH = widthInPixels HEIGHT = heightInPixels [ALIGN = alignment] [VSPACE = vspaceInPixels] [HSPACE = hspaceInPixels]>[<PARAM NAME = parameterName1 VALUE = parameterValue1>][<PARAM NAME = parameterName2 VALUE = parameterValue2>]...[<PARAM NAME = parameterNamen VALUE = parameterValuen>][HTML que será mostrado na ausência do Java]</APPLET>

Palavras-chave de tags HTML para Applets

CODEBASEDiretório onde a classe applet está localizada. Por padrão, utiliza o mesmo diretório URL do documento HTML.

CODENome do arquivo que contém o código applet. Com ou sem as extensões .java ou .class.

ALTTexto mostrado quando o navegador conhece tags applet mas não consegue executá-la. Pode acontecer se o Java do navegador estiver desabilitado.

NAMENome da applet. Usado para permitir que outras applets se comuniquem com o applet usando esse nome.

WIDTH, HEIGHTLargura e altura da janela da applet. Especificado em pixels.

ALIGNAlinhamento ou posicionamento da applet. Pode receber diversos valores "left", "right", "top", "bottom", "middle", "baseline", "texttop", "absmiddle", ou "absbottom". O posicionamento padrão depende do ambiente.

VSPACE, HSPACEEspaço acima e abaixo (VSPACE) e o dos lados (HSPACE) do applet.

PARAM NAME, VALUEServe para especificar parâmetros que podem ser passados para o applet; applets podem chamar o método getParameter(String paramName).

Tabela 1: tags HTML para Applets

Observação:

• top – topo do applet alinhado com o item mais alto da mesma linha.

Introdução à Programação II 10

Page 400: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

• bottom, baseline – parte inferior do applet alinhado com a parte inferior de outros itens da mesma linha.

• middle – meio do applet alinhado com a parte inferior de outros componentes na mesma linha.

• texttop – topo do applet alinhado com o topo do texto mais alto da mesma linha .

• absmiddle – meio do applet alinhado com o meio vertical de outros componentes da mesma linha.

• absbottom – parte inferior do applet alinhado com a parte inferior de outros componentes da mesma linha.

O exemplo abaixo demonstra como acessar parâmetros especificados na tag HTML.

import java.awt.*;import java.applet.*;

public class ParamDemo extends Applet { public void paint(Graphics g) { g.drawString(getParameter("myParam"), 80, 25); }}

O resultado dessa classe é o mesmo da AppletDemo. Logo abaixo vemos a tela com o resultado esperado:

Figura 3: Exemplo de execução do ParamDemo

Introdução à Programação II 11

Page 401: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 12 Stream de Entrada e Saída de Dados (I/O)

Avançados

Versão 1.0 - Mar/2007

Page 402: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. Objetivos

Em lições anteriores, vimos como obter a entrada do usuário e manipular arquivos utilizando Stream (se refere a uma sequência de dados). Agora iremos aprender mais sobre Stream e outras classes relacionadas.

Ao final desta lição, o estudante será capaz de:

• Enumerar os tipos de Stream• Stream de caracteres e bytes• Stream de entrada e saída de dados• Node Stream e Filter Stream

• Usar a classe File e seus métodos• Usar as diferentes classes de Entrada e Saída

• Reader • Writer • InputStream • OutputStream

• Explicar o conceito de encadeamento de Stream• Definir serialização• Explicar o uso da palavra-chave transient • Escrever e ler a partir de um Stream

Introdução à programação II 4

Page 403: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Tipos Stream Gerais

2.1. Stream de caracteres e bytes

Geralmente existem dois tipos de Stream, de caracteres e de bytes. Vejamos a diferença básica entre estes dois tipos. Stream de bytes (ou Byte Stream) são abstrações de arquivos ou dispositivos para dados binários, enquanto Stream de caracteres (ou Character Stream) são para os caracteres Unicode.

A classe InputStream é uma classe abstrata raiz para todos os Stream de bytes utilizados como entrada, enquanto a classe OutputStream é a classe abstrata raiz para todos os Stream de bytes de saída. Para Stream de caracteres, a superclasse correspondente as classes de leitura e escrita, respectivamente as classes Reader e Writer.

2.2. Stream de entrada e saída de dados

Stream são também categorizados segundo o seu uso: se são utilizados para ler ou para escrever. É possível ler a partir de Stream de entrada, embora não seja possível escrever nos mesmos. Por outro lado, é possível escrever a um Stream de saída, embora não seja possível ler a partir deles.

A classe InputStream e a classe Reader são superclasses de todos os Stream de entrada de dados. A classe OutputStream e a classe Writer são as superclasses de todos os Stream de saída de dados.

Stream de entrada de dados (input Stream) são também conhecidos como Source Stream, já que obtemos informações a partir destes Stream. Enquanto isso, Stream de saída de dados (output Stream) são também chamados Sink Stream.

2.3. Node Stream e Filter Stream

O pacote java.io difere entre Node Stream e Filter Stream. Um Node Stream é um Stream com a funcionalidade básica de ler ou escrever a partir de um local específico como um disco ou a partir da rede. Tipos de Node Stream incluem arquivos, memória e pipes. Filter Stream, por outro lado, são postos sobre os Node Stream entre as tarefas ou os processos para prover funcionalidades adicionais não encontradas nos Node Stream. Agregar camadas a um Node Stream é chamado encadeamento de Stream ou Stream Chaining.

Introdução à programação II 5

Page 404: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Classe FileA classe File não é uma classe do tipo Stream, é uma representação abstrata de arquivos reais e de caminhos de diretórios.

Para construir um objeto da classe File, pode-se utilizar o seguinte construtor:

Construtor para a classe File

File(String pathname) Instancia um objeto File com o pathname especificado como seu nome de arquivo. O nome do arquivo pode tanto ser absoluto (ex., contém o caminho completo) ou pode consistir do próprio nome do arquivo e se assume que o mesmo está contido no mesmo diretório.

Tabela 1: Construtor para a classe File

A classe File provê diversos métodos para manipulação de arquivos e diretórios. Na tabela abaixo estão alguns destes métodos:

Métodos da classe File

public String getName()Retorna o nome do arquivo ou o nome do diretório deste objeto File.

public boolean exists()Testa se um arquivo ou diretório existe.

public long length()Retorna o tamanho do arquivo.

public long lastModified()Retorna a data em milissegundos quando o arquivo foi modificado pela última vez.

public boolean canRead()Retorna true se é permitido ler a partir do arquivo. De outro modo, retorna false.

public boolean canWrite()Retorna true se é permitido escrever ao arquivo. De outro modo, retorna false.

public boolean isFile()Testa se este objeto é um arquivo, ou seja, nossa normal percepção do que é um arquivo (não um diretório).

public boolean isDirectory()Testa se este objeto é um diretório.

public String[] list()Retorna a lista de arquivos e sub-diretórios contidos neste objeto. Este objeto deveria ser um diretório.

public void mkdir()Cria um diretório denotado por este caminho abstrato.

public void delete()Remove o arquivo ou diretório representado por este objeto File.

Tabela 2: Métodos da classe File

Introdução à programação II 6

Page 405: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Veremos como estes métodos trabalham, através da classe a seguir:

import java.io.*;

public class FileDemo { public static void main(String args[]) { String fileName = "temp.txt"; File fn = new File(fileName); System.out.println("Name: " + fn.getName()); if (!fn.exists()) { System.out.println(fileName + " does not exists."); /* Cria um diretório temporário. */ System.out.println("Creating temp directory..."); fileName = "temp"; fn = new File(fileName); fn.mkdir(); System.out.println(fileName + (fn.exists()? "exists": "does not exist")); System.out.println("Deleting temp directory..."); fn.delete(); System.out.println(fileName + (fn.exists()? "exists": "does not exist")); return; } System.out.println(fileName + " is a " + (fn.isFile()? "file." :"directory.")); if (fn.isDirectory()) { String content[] = fn.list(); System.out.println("The content of this directory:"); for (int i = 0; i < content.length; i++) { System.out.println(content[i]); } } if (!fn.canRead()) { System.out.println(fileName + " is not readable."); return; } System.out.println(fileName + " is " + fn.length() + " bytes long."); System.out.println(fileName + " was last modified on " + fn.lastModified() + "."); if (!fn.canWrite()) { System.out.println(fileName + " is not writable."); } }}

Este é o resultado da execução da classe FileDemo:

Name: temp.txttemp.txt is a file.temp.txt is 34 bytes long.temp.txt was last modified on 1149150489177.

temp.txt, deve ser colocado no diretório raiz do seu projeto e contém o seguinte texto:

what a wonderful world1, 2, step

Introdução à programação II 7

Page 406: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Classe ReaderEsta seção descreve Stream de caracteres que são utilizados para leitura.

4.1. Métodos de Reader

A classe Reader consiste de diversos métodos para leitura de caracteres. Aqui estão alguns dos métodos desta classe:

Métodos da Classe Reader

public int read(-) throws IOExceptionPossui três versões. Lê caractere(s), uma matriz inteira de caracteres, ou uma porção de uma matriz de caracteres.

public int read() - Lê um único caracter.

public int read(char[] cbuf)- Lê caracteres e os armazena na matriz de caracteres cbuf.

public abstract int read(char[] cbuf, int offset, int length)- Lê até length número de caracteres e os armazena na matriz de caracteres cbuf começando no offset especificado.

public abstract void close() throws IOExceptionFecha este Stream. Chamar os outros métodos Reader após fechar o Stream iria causar a ocorrência de uma exceção IOException.

public void mark(int readAheadLimit) throws IOExceptionMarca a posição atual no Stream. Após marcar, chamadas ao método reset() irão tentar reposicionar o Stream neste ponto. Nem todos os Stream de entrada de caracteres suportam esta operação.

public boolean markSupported()Indica se um Stream suporta a operação de marca ou não. Não é suportado por padrão. Não deveria ser sobrescrito por subclasses.

public void reset() throws IOExceptionReposiciona o Stream na última posição marcada.

Tabela 3: Métodos da classe Reader

4.2. Subclasses de Reader

A seguir temos algumas das subclasses de Reader:

Subclasses de Reader

FileReaderPara leitura a partir de arquivos de caracteres.

CharArrayReaderImplementa um buffer de caracteres a partir do qual pode-se ler.

StringReaderPara leitura a partir de uma String.

PipedReader

Introdução à programação II 8

Page 407: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Usado em pares (com um correspondente PipedWriter) por duas tarefas que queiram comunicar-se. Uma destas tarefas lê caracteres a partir desta fonte.

Tabela 4: Subclasses de Reader

4.3. Subclasses de FilterReader

Para adicionar funcionalidades às classes Reader básicas, é possível utilizar as subclasses FilterReader. Aqui estão algumas destas subclasses:

Subclasses de FilterReader

BufferedReaderPermite o armazenamento de caracteres em um buffer, de forma a prover uma eficiente leitura de caracteres, matrizes, e linhas.

FilterReaderPara ler Stream de caracteres filtrados.

InputStreamReaderConverte bytes lidos em caracteres.

LineNumberReaderUma subclasse da classe BufferedReader que é capaz de manter registro do número das linhas.

PushbackReaderUma subclasse da classe FilterReader que permite que caracteres sejam devolvidos ou não copiados ao Stream.

Tabela 5: Subclasses de FilterReader

Introdução à programação II 9

Page 408: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Classe WriterNesta seção descrevemos os Stream de caracteres que são utilizados para escrita.

5.1. Métodos de Writer

A classe Writer consiste de diversos métodos para escrita de caracteres. Aqui estão alguns dos métodos desta classe:

Métodos da classe Writer

public void write(-) throws IOExceptionPossue cinco versões:

public void write(int c) – Escreve um único caracter representado pelo valor inteiro dado.

public void write(char[] cbuf) – Escreve o conteúdo da matriz de caracteres cbuf.

public abstract void write(char[] cbuf, int offset, int length) – Escreve length número de caracteres a partir da matriz cbuf , começando no offset especificado.

public void write(String str) – Escreve a string string.

public void write(String str, int offset, int length) – Escreve length número de caracteres a partir da string str, começando no offset especificado.

public abstract void close() throws IOExceptionFecha este Stream após descarregar quaisquer caracteres que não tenham sido escritos. Invocação de outros métodos depois de fechar este Stream iriam causar a ocorrência de uma exceção IOException.

public abstract void flush()Descarrega o Stream (ex., caracteres salvos no buffer são imediatamente escritos à destinação pretendida).

Tabela 6: Métodos da classe Writer

5.2. Subclasses de Writer

A seguir temos algumas das subclasses de Writer:

Subclasses de Writer

FileWriterPara escrever caracteres a um arquivo.

CharArrayWriterImplementa um buffer de caracteres para o qual pode-se escrever.

StringWriterPara escrever em uma String.

PipedWriterUsado em pares (com um correspondente PipedReader) por duas tarefas que queiram comunicar-se. Uma destas tarefas escreve caracteres a este Stream.

Tabela 7: Subclasses de Writer

Introdução à programação II 10

Page 409: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5.3. Subclasses de FilterWriter

Para adicionar funcionalidades às classes Writer básicas, é possível utilizar as subclasses FilterWriter. Aqui estão algumas destas classes:

Subclasses de FilterWriter

BufferedWriterPermite o uso de buffers de caracteres de forma a prover eficiente escrita de caracteres, matrizes, e linhas.

FilterWriterPara escrever Stream de caracteres filtrados.

OutputStreamWriterCodifica caracteres escritos a ele em bytes.

PrintWriterImprime representações formatadas dos objetos a um Stream de saída de texto.

Tabela 8: Subclasses de Filter Writer

Introdução à programação II 11

Page 410: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Um Exemplo de Reader/WriterO exemplo a seguir utiliza as classes FileReader e FileWriter para ler a partir de um arquivo especificado pelo usuário e copiar o conteúdo deste para um outro arquivo:

import java.io.*;

class CopyDemo { private void copy(String input, String output) { FileReader reader; FileWriter writer; int data; try { reader = new FileReader(input); writer = new FileWriter(output); while ((data = reader.read()) != -1) { writer.write(data); } reader.close(); writer.close(); } catch (IOException ie) { ie.printStackTrace(); } } public static void main(String args[]) { CopyDemo cf = new CopyDemo(); cf.copy("temp.txt", "temp2.txt"); }}

Execute a classe e observe o que acontece com os arquivos manipulados.

Usando temp.txt a partir de nosso exemplo anterior, aqui está o resultado quando passamos temp.txt como o inputFile e temp2.txt como o outputFile:

Figura 1: Saída de dados para CopyFile

Introdução à programação II 12

Page 411: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

7. Exemplo Reader/Writer modificadoO exemplo a seguir é similar ao anterior, entretanto é mais eficiente. Ao invés de ler e escrever um Stream de cada vez, caracteres lidos são primeiramente armazenados em um buffer antes de que caracteres sejam escritos linha por linha. O programa usa a técnica de encadeamento de Stream desde que as classes FileReader e FileWriter sejam decoradas com as classes BufferedReader e BufferedWriter, respectivamente:

import java.io.*;

class CopyDemo { void copy(String input, String output) { BufferedReader reader; BufferedWriter writer; String data; try { reader = new BufferedReader(new FileReader(input)); writer = new BufferedWriter(new FileWriter(output)); while ((data = reader.readLine()) != null) { writer.write(data, 0, data.length()); } reader.close(); writer.close(); } catch (IOException ie) { ie.printStackTrace(); } }

public static void main(String args[]) { CopyDemo cf = new CopyDemo(); cf.copy("temp.txt", "temp2.txt"); }}

Aqui está o resultado desta versão de CopyDemo.

Figura 2: Saída de Dados para CopyDemo

Introdução à programação II 13

Page 412: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

8. Classe InputStreamEsta seção dá uma visão geral dos diferentes Stream de bytes que são utilizados para leitura.

8.1. Métodos de InputStream

A classe InputStream consiste em diversos métodos para leitura de bytes. Aqui estão alguns dos métodos desta classe:

Métodos da classe InputStream

public int read(-) throws IOExceptionUm método sobrecarregado, o qual também tem três versões como as da classe Reader. Lê bytes.

public abstract int read() - Lê o próximo byte de dados a partir deste Stream.

public int read(byte[] bBuf)- Lê certo número de bytes e os armazena na matriz de bytes bBuf.

public abstract int read(char[] cbuf, int offset, int length)- Lê até length número de bytes e os armazena na matriz de bytes bBuf começando no offset especificado.

public abstract void close() throws IOExceptionFecha este Stream. Chamar os outros métodos InputStream após ter fechado o Stream iria causar a ocorrência de uma exceção IOException.

public void mark(int readAheadLimit) throws IOExceptionMarca a posição atual no Stream. Após marcar, chamadas ao método reset() irão tentar reposicionar o Stream neste ponto. Nem todos os Stream de entrada de bytes suportam esta operação.

public boolean markSupported()Indica se um Stream suporta as operações marca e limpeza. Não suportado por padrão. Deve ser feito override pelas subclasses.

public void reset() throws IOExceptionReposiciona o Stream na última posição marcada.

Tabela 9: Métodos da classe InputStream

8.2. Subclasses de InputStream

As seguintes são algumas das subclasses de InputStream:

Subclasses de InputStream

FileInputStreamPara leitura de bytes a partir de um arquivo.

BufferedInputStreamImplementa um buffer que contém bytes, os quais podem ser lidos a partir do Stream.

PipedInputStreamDeveria estar conectado a um PipedOutputStream. Estes Stream são tipicamente usados por duas tarefas desde que um destas tarefas leia dados a partir desta fonte enquanto a outra tarefa escreve ao correspondente PipedOutputStream.

Tabela 10: Subclasses de InputStream

Introdução à programação II 14

Page 413: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

8.3. Subclasses de FilterInputStream

Para adicionar funcionalidades às classes InputStream básicas, utilizamos as subclasses de FilterInputStream. Aqui estão algumas destas subclasses:

Subclasses de FilterInputStream

BufferedInputStreamUma subclasse de FilterInputStream que permite o uso de um buffer de entrada de forma a prover a eficiente leitura de bytes.

FilterInputStreamPara ler Stream de bytes filtrados, os quais podem transformar a fonte básica de dados no decorrer do processo e prover funcionalidades adicionais.

ObjectInputStreamUsado para serialização de objetos. De-serializa objetos e dados primitivos previamente escritos usando um ObjectOutputStream.

DataInputStreamUma subclasse de FilterInputStream que permite que uma aplicação leia dados Java primitivos a partir de um Stream de entrada de dados subjacente, independente do tipo de máquina.

LineNumberInputStreamUma subclasse de FilterInputStream que permite monitorar o número de linha atual.

PushbackInputStreamUma subclasse da classe FilterInputStream que permite que bytes sejam devolvidos ou não transferidos ao Stream.

Tabela 11: Subclasses de Filter InputStream

Introdução à programação II 15

Page 414: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

9. Classe OutputStream

Esta seção dá uma visão geral dos diferentes Stream de bytes que são utilizados para escrita.

9.1. Métodos de OutputStream

A classe OutputStream consiste em diversos métodos para escrever bytes. Aqui estão alguns dos métodos desta classe:

Métodos da classe OutputStream

public void write(-) throws IOExceptionUm método sobrecarregado para escrever bytes ao Stream. Ele tem três versões:

public abstract void write(int b) – Escreve o valor em bytes b especificado a este Stream de saída de dados.

public void write(byte[] bBuf) – Escreve o conteúdo da matriz de bytes bBuf neste Stream.

public void write(byte[] bBuf, int offset, int length) – Escreve length número de bytes a partir da matriz bBuf neste Stream, começando pelo offset especificado para este Stream.

public abstract void close() throws IOExceptionFecha este Stream e libera quaisquer recursos do sistema associados com este Stream. Invocação de outros métodos após chamar este método iria causar a ocorrência de uma exceção IOException.

public abstract void flush()Descarrega o Stream (ex., bytes salvos no buffer são imediatamente escritos à destinação pretendida).

Tabela 12: Métodos da classe OutputStream

9.2. Subclasses de OutputStream

As seguintes são algumas das subclasses de OutputStream:

Subclasses de OutputStream

FileOutputStreamPara escrever bytes a um arquivo.

BufferedOutputStreamImplementa um buffer que contém bytes, os quais podem ser escritos no Stream.

PipedOutputStreamDeveria estar conectado a um PipedInputStream. Estes Stream são tipicamente usados por duas tarefas desde que uma destas escreva dados a este Stream enquanto a outra tarefa lê a partir do correspondente PipedInputStream.

Tabela 13: Subclasses de OutputStream

Introdução à programação II 16

Page 415: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

9.3. Subclasses de FilterOutputStream

Para adicionar funcionalidades às classes OutputStream básicas, utilizamos as subclasses de Filter Stream. Aqui estão algumas destas subclasses:

Subclasses de FilterOutputStream

BufferedOutputStreamUma subclasse de FilterOutputStream que permite o uso de buffers de saída de forma a prover uma eficiente escrita de bytes. Permite escrever bytes ao Stream de saída de dados subjascente sem necessariamente causar uma chamada ao sistema subjascente para cada byte escrito.

FilterOutputStreamPara escrever Stream de bytes filtrados, os quais podem transformar a fonte de dados básica ao longo do processo e prover funcionalidades adicionais.

ObjectOutputStreamUsado para serialização de objetos. Serializa objetos e dados primitivos a um OutputStream.

DataOutputStreamUma subclasse de FilterOutputStream que permite que uma aplicação escreva dados Java primitivos a um Stream de saída de dados subjascent, independentemente do tipo de máquina.

PrintStreamUma subclasse de FilterOutputStream que provê capacidade para imprimir representações de diversos valores de dados convenientemente.

Tabela 14: Classes Filter OutputStream

Introdução à programação II 17

Page 416: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

10. Um Exemplo de InputStream/OutputStream

O exemplo a seguir utiliza as classes FileInputStream e FileOutputStream para ler a partir de um arquivo especificado pelo usuário e copiar o conteúdo deste para um outro arquivo:

import java.io.*;

class CopyDemo { void copy(String input, String output) { FileInputStream inputStr; FileOutputStream outputStr; int data; try { inputStr = new FileInputStream(input); outputStr = new FileOutputStream(output); while ((data = inputStr.read()) != -1) { outputStr.write(data); } inputStr.close(); outputStr.close(); } catch (IOException ie) { ie.printStackTrace(); } }

public static void main(String args[]) { CopyDemo cf = new CopyDemo(); cf.copy("temp.txt", "temp2.txt"); }}

Aqui está o resultado da execução desta classe:

Figura 3: Saída de dados para CopyFile

Introdução à programação II 18

Page 417: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

11. Exemplo InputStream/OutputStream ModificadoEste exemplo utiliza a classe PushbackInputStream que decora um objeto FileInputStream usando a classe PrintStream.

import java.io.*;

class CopyDemo { void copy(String input) { PushbackInputStream inputStr; PrintStream outputStr; int data; try { inputStr = new PushbackInputStream(new FileInputStream(input)); outputStr = new PrintStream(System.out); while ((data = inputStr.read()) != -1) { outputStr.println("read data: " + (char) data); inputStr.unread(data); data = inputStr.read(); outputStr.println("unread data: " + (char) data); } inputStr.close(); outputStr.close(); } catch (IOException ie) { ie.printStackTrace(); } }

public static void main(String args[]) { CopyDemo cf = new CopyDemo(); cf.copy("temp.txt"); }}

Teste este código em um arquivo contendo algumas poucas linhas ou caracteres. Supondo um arquivo chamado temp.txt contendo o seguinte texto:

one 1two

Ao executarmos esta classe obteremos a seguinte saída:

read data: ounread data: oread data: nunread data: nread data: eunread data: eread data: unread data: read data: 1unread data: 1read data:

unread data: read data:

unread data:

read data: tunread data: tread data: wunread data: wread data: ounread data: o

Introdução à programação II 19

Page 418: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

12. Serialização

A Máquina Virtual Java ou JVM possui a habilidade de ler ou escrever um objeto a um Stream. Esta capacidade é chamada Serialização, corresponde ao processo de "achatar" um objeto de forma tal que o mesmo possa ser salvo a uma fonte de armazenamento permanente ou passado a outro objeto via a classe OutputStream. Ao escrever um objeto, é importante que o seu estado seja escrito em uma forma serializada de tal modo que o objeto possa ser reconstruído conforme o mesmo está sendo lido. Salvar um objeto a alguma forma de armazenamento permanente é conhecido como persistência.

Os Stream podem ser utilizados para de-serializar e re-serializar. São representados respectivamente pelas classes ObjectInputStream e ObjectOutputStream.

Para permitir que um objeto seja serializável (isto é, possa ser salvo e recuperado), a classe deve implementar a interface Serializable. A classe também deve prover um construtor padrão (ou um construtor sem argumentos). Uma das coisas interessantes a respeito de serialização é que a mesma é herdada, o que significa que não precisamos implementar Serializable em cada classe. Isso significa menos trabalho para os programadores. É possível simplesmente implementar Serializable uma única vez ao longo da hierarquia de classes.

12.1. A Palavra-chave transient

Quando um objeto é serializado, apenas os dados do objeto são preservados. Métodos e construtores não são parte do Stream serializado. Há, no entanto, alguns objetos que não são serializáveis porque os dados que eles representam mudam constantemente. Alguns exemplos de tais objetos são FileInputStream e Thread. Uma exceção NotSerializableException é lançada se a operação de serialização falhar por qualquer motivo.

Não há necessidade em se desesperar. Uma classe contendo um objeto não serializável ainda pode ser serializada se a referência e este objeto não serializável for marcada com a palavra-chave transient. Considere o seguinte exemplo:

class MyClass implements Serializable { transient Thread thread; //tente remover transient int data; /* alguns outros dados */}

A palavra-chave transient previne que os dados associados sejam serializados. Objetos instanciados a partir desta classe podem agora ser escritos a um OutputStream.

12.2. Serialização: Escrevendo um Stream de Objetos

Para escrever um objeto a um Stream, é necessário utilizar a classe ObjectOutputStream e seu método writeObject. O método writeObject tem a seguinte assinatura:

public final void writeObject(Object obj) throws IOException

onde obj é o objeto que será escrito ao Stream.

O exemplo abaixo escreve um objeto Boolean a um ObjectOutputStream. A classe Boolean implementa a interface Serializable. Deste modo, os objetos instanciados a partir desta classe podem ser escritos e lidos a partir de um Stream.

import java.io.*;

Introdução à programação II 20

Page 419: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

public class SerializeDemo { public SerializeDemo() { Boolean booleanData = new Boolean("true"); try { FileOutputStream fos = new FileOutputStream("boolean.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(booleanData); oos.close(); } catch (IOException ie) { ie.printStackTrace(); } } public static void main(String args[]) { new SerializeDemo(); }}

12.3. De-serialização: Lendo um Stream de Objetos

Para ler um objeto a partir de um Stream, é necessário utilizar a classe ObjectInputStream e seu método readObject. O método readObject tem a seguinte assinatura:

public final Object readObject() throws IOException, ClassNotFoundException

onde obj é o objeto a ser lido a partir do Stream.

O tipo Object retornado deveria sofrer typecasting ao nome de classe apropriado antes que métodos naquela classe possam ser executados.

O exemplo abaixo lê um objeto Boolean a partir de um ObjectInputStream. Esta é uma continuação do exemplo anterior que tratava de serialização.

import java.io.*;

public class UnserializeDemo { public UnserializeDemo() { Boolean booleanData = null; try { FileInputStream fis = new FileInputStream("boolean.txt"); ObjectInputStream ois = new ObjectInputStream(fis); booleanData = (Boolean) ois.readObject(); ois.close(); } catch (Exception e) { e.printStackTrace(); } System.out.println("Unserialized Boolean from " + "boolean.txt"); System.out.println("Boolean data: " + booleanData); System.out.println("Compare data with true: " + booleanData.equals(new Boolean("true"))); } public static void main(String args[]) { new UnserializeDemo(); }}

O seguinte é a saída de dados esperada de UnserializeBoolean:

Introdução à programação II 21

Page 420: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Unserialized Boolean from boolean.serBoolean data: trueCompare data with true: true

Introdução à programação II 22

Page 421: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

Módulo 2Introdução à Programação II

Lição 13Introdução à Generics

Versão 1.0 - Mar/2007

Page 422: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

1. ObjetivosA versão 5 do Java trouxe grandes avanços na programação. Inclui extensões significantes à sintaxe da linguagem. A mais visível delas foi a adição de Generics. Nessa lição iremos conhecer os conceitos básicos relacionados a Generics.

Ao final desta lição, o estudante será capaz de:

• Enumerar os benefícios de Generics• Declarar classes utilizando Generics• Utilizar Generics limitados• Declarar métodos utilizando Generics• Usar coleções Java com Generics

Introdução à Programação II 4

Page 423: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

2. Por que Generics?

Um dos maiores problemas na linguagem de programação Java é a necessidade constante de fazer typecast ou casting (conversões de tipo explícitas) em expressões para tipos de dados mais específicos do que seus tipos estáticos. Por exemplo, um objeto ArrayList permite adicionarmos objetos de qualquer tipo de referência à coleção, mas quando recuperarmos estes elementos, precisaremos fazer um typecast nos objetos para o tipo de referência específico à nossa necessidade. O casting é um perigo em potencial para gerar uma ClassCastException. Ele também torna nossos códigos mais poluídos e, portanto, menos legíveis. Além disso, o casting efetivamente destrói os benefícios de uma linguagem com os tipos fortemente definidos, uma vez que anula a segurança trazida pela checagem embutida de tipos.

O principal objetivo da adição de Generics ao Java é solucionar este problema. Tipos Generics permite que uma única classe trabalhe com uma grande variedade de tipos. Eles são uma forma natural de se eliminar a necessidade do cast.

Primeiro iremos considerar um objeto ArrayList e ver como os tipos Generics ajudariam a melhorar nosso código. Um objeto ArrayList possui a capacidade de armazenar elementos de qualquer tipo de referência em uma coleção de objetos. Uma instância de ArrayList, entretanto, sempre força a realizar um casting nos objetos que recuperamos da coleção. Considere a seguinte linha de instrução:

String myString = (String) myArrayList.get(0);

A versão utilizando Generics, da classe ArrayList foi desenvolvida para trabalhar nativamente com qualquer tipo de classe. Ao mesmo tempo, ela também preserva os benefícios da checagem de tipos. Podemos eliminar a necessidade do casting no elemento que obtemos da coleção e ter a seguinte linha de instrução:

String myString = myArrayList.get(0);

Embora o casting já tenha sido removido, isso não significa que possamos atribuir qualquer tipo ao valor de retorno do método get e eliminar o casting também. Ao atribuir outra coisa que não uma String à saída do método get, obteremos um erro de equiparação de tipos em tempo de compilação tal como essa mensagem:

found: java.lang.Stringrequired: java.lang.IntegerInteger data = myArrayList.get(0);

Para se ter uma idéia de como Generics é usado, antes de entrarmos em mais detalhes, considere o seguinte fragmento de código:

ArrayList <String> genArrList = new ArrayList <String>();genArrList.add("A generic string");String myString = genArrList.get(0);JoptionPane.showMessageDialog(this, myString);

Analisando estas instruções, observamos a palavra <String> aparecendo imediatamente após a referência do tipo ArrayList. Podemos interpretar esta como o primeiro comando da criação de uma instância de uma versão da classe ArrayList utilizando Generics, e esta versão contém objetos do tipo String. genArrList está preso ao tipo String. Portanto, “prender” um Integer ou outro tipo não String ao resultado da função get seria ilegal. A próxima instrução não seria válida:

int myInt = genArrList.get();

Introdução à Programação II 5

Page 424: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3. Declarando uma Classe Utilizando GenericsPara que o fragmento de código anterior funcione, deveríamos ter definido uma versão da classe ArrayList que utilize Generics. Felizmente, a versão mais recente do Java fornece aos usuários versões que fazem uso de Generics para todas as implementações de Collection. Nessa seção, aprenderemos como declarar sua própria classe utilizando Generics.

Ao invés de uma longa discussão sobre como declarar uma classe utilizando Generics, veremos um exemplo:

class BasicGeneric <A> { private A data; public BasicGeneric(A data) { this.data = data; } public A getData() { return data; }}public class GenericDemo { public String method(String input) { String data1 = input; BasicGeneric <String> basicGeneric = new BasicGeneric <String>(data1); String data2 = basicGeneric.getData(); return data2; } public Integer method(int input) { Integer data1 = new Integer(input); BasicGeneric <Integer> basicGeneric = new BasicGeneric <Integer>(data1); Integer data2 = basicGeneric.getData(); return data2; } public static void main(String args[]) { GenericDemo sample = new GenericDemo(); System.out.println(sample.method("Some generic data")); System.out.println(sample.method(1234)); }}

Na execução desta classe será mostrada a seguinte saída:

Some generic data1234

Iremos agora passar pelas instruções que possuem a sintaxe que utilizam Generics.

Para a declaração da classe BasicGeneric:

class BasicGeneric <A>

o nome da classe é seguido por um par de sinais “menor que” e “maior que” envolvendo a letra maiúscula A: <A>. Isto é chamado de um parâmetro de tipo. Os usos desses sinais “menor que” e “maior que” indicam que a classe declarada é uma classe que utiliza Generics. Isso significa que a classe não trabalha com nenhuma referência a um tipo específico. Por isso, observe que o atributo da classe foi declarado para ser do tipo A:

private A data;

Introdução à Programação II 6

Page 425: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Essa declaração especifica que o atributo data é de um tipo Generic, e depende do tipo de dado com que o objeto BasicGeneric for desenvolvido para trabalhar. Quando declarar uma instância da classe, deve ser especificada a referência ao tipo com que se deseja trabalhar. Por exemplo:

BasicGeneric <String> basicGeneric = new BasicGeneric <String>(data1);

A sintaxe <String> após a declaração de BasicGeneric especifica que essa instância da classe irá trabalhar com variáveis do tipo String.

Podemos trabalhar com variáveis do tipo Integer ou qualquer outro tipo de referência. Para trabalhar com um Integer, o fragmento do código teria a seguinte instrução:

BasicGeneric <Integer> basicGeneric = new BasicGeneric <Integer>(data1);

Consideremos a declaração para o método getData:

public A getData() { return data;}

O método getData retorna um valor do tipo A, que é um tipo Generic. Isso significa que o método terá um tipo de dado em tempo de execução, ou mesmo em tempo de compilação. Depois de declarar um objeto do tipo BasicGeneric, A será “preso” a um tipo de dado específico. Essa instância atuará como se tivesse sido declarada para ter esse tipo de dado específico, e apenas esse, desde o início.

No seguinte código, duas instâncias da classe BasicGeneric foram criadas.

BasicGeneric <String> basicGeneric = new BasicGeneric <String>(data1);String data2 = basicGeneric.getData();

BasicGeneric <Integer> basicGeneric = new BasicGeneric <Integer>(data1);Integer data2 = basicGeneric.getData();

Note que a criação de uma instância de uma classe que utiliza Generics é bem similar à criação de uma classe normal, exceto pelo tipo de dado específico dentro dos sinais <> logo após o nome do construtor. Essa informação adicional indica o tipo de dado com que você trabalhará para essa instância da classe BasicGeneric em particular. Depois de criada a instância, é possível agora acessar os elementos da classe através dela. Não existe mais a necessidade do typecast no valor do retorno do método getData, uma vez que já foi decidido que ele irá trabalhar com um tipo de dado de referência específico.

3.1. Limitação "Primitiva"

Uma limitação de Generics em Java, é que eles são restritos a tipos de referência (Objetos) e não funcionarão com tipos primitivos.

Por exemplo, o comando a seguir seria ilegal, uma vez que int é um tipo de dado primitivo.

BasicGeneric <int> basicGeneric = new BasicGeneric <int>(data1);

Você terá que encapsular os tipos primitivos primeiro, antes de usá-los como argumentos Generics.

Introdução à Programação II 7

Page 426: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

3.2. Compilando Generics

Para compilar códigos fonte Java com Generics usando JDK (v. 1.5.0), utilize a seguinte sintaxe:

javac -version -source "1.5" -sourcepath src -d classes src/SwapClass.java

onde src refere-se à localização do código fonte java, enquanto class refere-se à localização onde o arquivo da classe será gravado.

Aqui está um exemplo:

javac -version -source "1.5" -sourcepath c:\temp -d c:\temp c:/temp/SwapClass.java

Introdução à Programação II 8

Page 427: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

4. Generics LimitadosNo exemplo mostrado anteriormente, os parâmetros de tipo da classe BasicGeneric podem ser de qualquer tipo de dado de referência. Há casos, entretanto, onde você quer restringir os tipos em potencial usados em instanciações de uma classe do tipo Generics. Java permite limitar o conjunto de possíveis tipos utilizados como argumento na instanciação de classes desse tipo, para um conjunto de subtipos de um determinado tipo “amarrado” à classe.

Por exemplo, podemos definir uma classe ScrollPane que utiliza Generics que serviria como um molde para um Container comum com a funcionalidade da barra de rolagem. Em tempo de execução, o tipo da instância dessa classe será, geralmente, uma subclasse de Container, mas o tipo estático ou geral é simplesmente Container.

Para limitar as instanciações de tipo de uma classe, nós usamos a palavra-chave extends seguida pela classe que limita (ou restringe) o tipo Generics como parte de um parâmetro de tipo.

O exemplo a seguir limita as instanciações de tipo da classe ScrollPane para subtipos da classe Container.

class ScrollPane <MyPane extends Container> { ...}class TestScrollPane { public static void main(String args[]) { ScrollPane <Panel> scrollPane1 = new ScrollPane <Panel>(); // O comando seguinte é ilegal ScrollPane <Button> scrollPane2 = new ScrollPane <Button>(); }}

A instanciação de scrollPane1 é válida, uma vez que Panel é uma subclasse de Container, enquanto a criação de scrollPane2 causaria um erro em tempo de compilação, uma vez que Button não é uma subclasse de Container.

Usar Generics limitados nos dá um adicional, que é a checagem estática de tipos. Como resultado, nós temos a garantia que toda instanciação de um tipo Generics respeita os limites (ou restrições) que atribuímos a ele.

Uma vez que asseguramos que toda instância de tipo é uma subclasse do limite atribuído, podemos chamar, de forma segura, qualquer método encontrado no tipo estático do objeto. Se não tivéssemos colocado nenhum limite explícito no parâmetro, o limite default seria Object. Isso significa que não podemos invocar métodos em uma instância do limite que não apareçam na classe Object.

Introdução à Programação II 9

Page 428: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

5. Declarando Métodos GenericsAlém de declarar classe Generics, também podemos declarar métodos Generics. Estes métodos são chamados polimórficos, e são definidos para serem métodos parametrizados pelo tipo.

Parametrizar métodos é útil quando queremos realizar tarefas onde as dependências de tipo entre os argumentos e o valor de retorno são Generics, mas não depende de nenhuma informação do tipo da classe, e mudará a cada chamada ao método.

Por exemplo, suponha que queremos adicionar um método make em uma classe ArrayList. Este método estático admitiria um único argumento, que seria o único elemento do objeto ArrayList. Para fazer com que nosso ArrayList receba qualquer tipo de elemento, o argumento e o retorno do método make deve utilizar Generics.

Para declarar tipos Generics no nível de métodos, considere o exemplo a seguir:

class Utilities { /* T extends Object implicitamente */ public static <T> ArrayList<T> make(T first) { return new ArrayList<T>(first); }}

Java também utiliza um mecanismo de inferência de tipos, para inferir automaticamente os tipos dos métodos polimórficos baseado no tipo dos argumentos. Isso diminui o excesso de palavras, e a complexidade nas invocações de métodos.

Para construir uma nova instância de ArrayList<Integer>, nós simplesmente teríamos o seguinte comando:

Utilities.make(Integer(0));

Introdução à Programação II 10

Page 429: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

6. Generics e Coleções JavaUma discussão sobre métodos da interface Collection já foi mostrada em lições anteriores. Entretanto, no JDK 5.0, esses métodos foram atualizados para acomodar Generics. A tabela a seguir mostra os métodos do JDK 5.0 equivalentes àqueles que você estudou anteriormente.

Métodos da interface Collectionpublic boolean add(E o) Insere o elemento específico o nessa coleção. Retorna true se o foi adicionado com sucesso à coleção.public void clear() Remove todos os elementos dessa coleção.public boolean remove(Object o) Remove uma única instância de Object o dessa coleção, se ele estiver presente. Retorna true se o foi encontrado e removido da coleção.public boolean contains(Object o) Retorna true se essa coleção contém o Object o.public boolean isEmpty() Retorna true se essa coleção não contém nenhum objeto ou elemento. public int size() Retorna o número de elementos nessa coleção. public Iterator<E> iterator() Retorna um iterator que nos permite acessar elementos da coleção. public boolean equals(Object o) Retorna true se o Object o é igual a essa coleção.public int hashCode() Retorna o valor do hash code (i.e., o ID) para essa coleção. Mesmos objetos ou coleções têm o mesmo valor de hash code ou ID.

Table 1: métodos da interface Collection

Aqui está um exemplo de uma classe que não utiliza a versão Generics para a criação de uma lista, observe que podemos incluir sem problemas um objeto String entre os outros elementos

import java.util.*;

class GenericDemo { public static void main(String args[]) { List list = new ArrayList(); list.add(new Integer(1)); list.add(new Integer(2)); list.add("String"); System.out.println(list); Collections.sort(list); System.out.println(list); }}

Executar esta classe é gerada a seguinte saída:

[1, 2, String]Exception in thread "main" java.lang.ClassCastException: java.lang.String at java.lang.Integer.compareTo(Integer.java:35) at java.util.Arrays.mergeSort(Arrays.java:1156) at java.util.Arrays.sort(Arrays.java:1080) at java.util.Collections.sort(Collections.java:117) at GenericDemo.main(GenericDemo.java:10)Java Result: 1

Pelo simples motivo que o Java não sabe como ordenar uma String juntamente com dois

Introdução à Programação II 11

Page 430: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

objetos inteiros, agora vejamos a mesma classe utilizando agora o Generics:

import java.util.*;

class GenericDemo { public static void main(String args[]) { List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(1)); list.add(new Integer(2)); list.add("String"); System.out.println(list); Collections.sort(list); System.out.println(list); }}

O que acontecerá será um erro de compilação na linha 8, ou seja, o Generics bloqueia os elementos estranhos a lista não permitindo que esta tenha elementos diversos fora o especificado.

Introdução à Programação II 12

Page 431: Projeto JEDI - Introdução à Programação - Java -  Módulos 01 e 02 - 431 páginas

JEDITM

Parceiros que tornaram JEDITM possível

Instituto CTSPatrocinador do DFJUG.

Sun MicrosystemsFornecimento de servidor de dados para o armazenamento dos vídeo-aulas.

Java Research and Development Center da Universidade das FilipinasCriador da Iniciativa JEDITM.

DFJUGDetentor dos direitos do JEDITM nos países de língua portuguesa.

Banco do BrasilDisponibilização de seus telecentros para abrigar e difundir a Iniciativa JEDITM.

PolitecSuporte e apoio financeiro e logístico a todo o processo.

BorlandApoio internacional para que possamos alcançar os outros países de língua portuguesa.

Instituto Gaudium/CNBBFornecimento da sua infra-estrutura de hardware de seus servidores para que os milhares de alunos possam acessar o material do curso simultaneamente.

Introdução à Programação II 13