Академический Документы
Профессиональный Документы
Культура Документы
Introdução à Programação I
Lição 1
Introdução à Programação de Computadores
Requerimentos de Software
NetBeans 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).
Introdução à Programação I 2
JEDITM
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
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
JEDITM
2. Introdução
O 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
JEDITM
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.
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
JEDITM
3.2. Software
O 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
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
JEDITM
Introdução à Programação I 9
JEDITM
Introdução à Programação I 10
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 NomeLista
2. Obter o nome a ser procurado, vamos chamá-lo de NomeChave
3. Criar um contador, vamos chamá-lo de Conta
4. Pegar cada nome em NomeLista
5. Se NomeChave for igual ao nome selecionado em NomeLista
6. Adicionar 1 a Conta
7. Repetir 4 até que todos os nomes já tiverem sido comparados
8. Exibir o valor de Conta
Introdução à Programação I 11
JEDITM
Introdução à Programação I 12
JEDITM
Introdução à Programação I 13
JEDITM
6.1. Decimal
Normalmente 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ário
Nú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. Octal
Nú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. Hexadecimal
Nú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
6.5. Conversões
Introdução à Programação I 14
JEDITM
NOTA: O último dígito menor que o divisor (2) será o primeiro número do resultado.
Por Exemplo:
12610 = ? 2
Quociente Resto
126 / 2 = 63 0
63 / 2 = 31 1
Escreva
31 / 2 = 15 1
nesta
15 / 2 = 7 1 direção
7 / 2 = 3 1
3 / 2 = 1 1
1 / 2 = 1
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 0
Dígitos
1 1 1 1 1 1 0
Binários
0 x 20 = 0
1 x 21 = 2
1 x 22 = 4
1 x 2 3= 8
1 x 24= 16
1 x 25 = 32
1 x 26 = 64
TOTAL: 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
Escreva
15 6 nesta
126 / 8 =
direção
15 / 8 = 1 7
1/8= 1
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
JEDITM
Quociente Resto
14 (igual ao dígito Escreva
hexadecimal E) nesta
126 / 16 = 7 direção
7 / 16 = 7
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 0
Dígitos Octais 1 7 6
6 x 80 = 6
7 x 81 = 56
1 x 82 = 64
TOTAL: 126
Posição 1 0
Dígitos
7 E
Hexadecimais
14 x 160 = 14
7 x 161 = 112
TOTAL: 126
Por Exemplo:
Introdução à Programação I 16
JEDITM
11111102 = ? 8
0 0 1 1 1 1 1 1 0
1 7 6
Nú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.
Dígito Representação
Hexadecimal 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
Introdução à Programação I 17
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
JEDITM
7. Exercícios
7.1. Escrevendo Algoritmos
Dado 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
Introdução à Programação I 19
Módulo 1
Introdução à Programação I
Lição 2
Histórico de Java
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
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.
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.
Introdução à Programação I 5
JEDITM
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
JEDITM
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.
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.
Depois que tudo isso tiver sido feito, o código é finalmente executado.
Introdução à Programação I 7
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.
Introdução à Programação I 8
Módulo 1
Introdução à Programação I
Lição 3
Primeiros passos no ambiente de programação
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.
• 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
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
JEDITM
Para iniciar um editor de texto no Linux selecione Applications ⇒ Accessories ⇒ Text Editor.
Para abrir o terminal no Windows, selecione Start ⇒ Run... e na janela que se apresenta, digite
cmd e pressione o botão OK.
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
JEDITM
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.
Introdução à Programação I 7
JEDITM
javac Hello.java
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
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.
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.
Introdução à Programação I 8
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:
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.
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
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.
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:
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
Depois de abrir a IDE NetBeans será mostrada a interface gráfica GUI, conforme à Figura 3:
Introdução à Programação I 10
JEDITM
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
JEDITM
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
JEDITM
Introdução à Programação I 13
JEDITM
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):
Introdução à Programação I 14
JEDITM
Introdução à Programação I 15
JEDITM
Introdução à Programação I 16
JEDITM
Introdução à Programação I 17
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:
5.2 A árvore
Utilizando o NetBeans, crie uma classe chamada TheTree. O programa deverá mostrar as
seguintes linhas na saída:
Introdução à Programação I 18
Módulo 1
Introdução à Programação I
Lição 4
Fundamentos da programação
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.
Introdução à Programação I 4
JEDITM
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:
/**
* 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,
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
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.
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!");
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 :
Introdução à Programação I 6
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).
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 exemplo de comentário
* estilo C ou um comentário de bloco
*
*/
/**
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
*/
Introdução à Programação I 7
JEDITM
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:
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:
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:
Introdução à Programação I 8
JEDITM
5. Identificadores em Java
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.
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:
ExemploDeNomeDeUmaClasse
exemploDeNomeDeUmMetodo
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:
_NomeDeClasse.
Introdução à Programação I 9
JEDITM
6. 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
JEDITM
Java possui 4 tipos de dados. Estes tipos de dados são divididos em: boolean, character,
integer e float-point.
7.1. Boolean
7.2. Character
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
Introdução à Programação I 11
JEDITM
A linguagem Java possui 8 tipos de dados primitivos. Eles são divididos nas seguintes
representações:
8.1. Lógico
O tipo boolean pode representar dois estados: true (verdadeiro) ou false (falso). Um
exemplo é:
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 decimal
077 // 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
É 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
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:
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:
8 bits byte 7 7
-2 até 2 -1
16 bits char 16
0 até 2 -1
16 bits short 15 15
-2 até 2 -1
32 bits int 31 31
-2 até 2 -1
64 bits long 63 63
-2 até 2 -1
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.
Introdução à Programação I 13
JEDITM
+23. Os dados de tipo ponto-flutuante podem assumir valores dentro das seguintes faixas:
32 bits float 38 38
-10 até 10 -1
64 bits double 308 308
-10 até 10 -1
Tabela 3: Tipos e faixa de valores dos Número Fracionários
Introdução à Programação I 14
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.
nota: os valores colocados entre < > são obrigatórios, enquanto que os valores contidos entre
[ ] são opcionais.
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;
Introdução à Programação I 15
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()
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
System.out.print("Hello ");
System.out.print("world!");
Hello world!
Considere as seguintes:
System.out.println("Hello ");
System.out.println("world!");
Hello
world!
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
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.
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.
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
JEDITM
10. Operadores
Aqui temos a lista dos operadores aritméticos que podem ser utilizados na criação de
expressões matemáticas:
Introdução à Programação I 18
JEDITM
// 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));
}
}
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
JEDITM
é equivalente a,
count++;
Incrementa op em 1; Avalia a
++ op++
expressão antes do valor ser acrescido
Incrementa op em 1; Incrementa o
++ ++op
valor antes da expressão ser avaliada
Decrementa op em 1; Avalia a
-- op-- expressão antes do valor ser
decrescido
Decrementa op em 1; Decrementa op
-- --op
em 1 antes da expressão ser avaliada
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
int i = 10,
int j = 3;
int k = 0;
k = j++ + i; //resultará em k = 3+10 = 13
Dicas de programação:
Introdução à Programação I 20
JEDITM
// 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
JEDITM
// 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
}
}
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
JEDITM
x1 op x2
Onde x1 e x2 podem ser expressões, variáveis ou constantes lógicas, e op pode tanto ser &&,
&, ||, | ou ^.
x1 x2 Resultado
VERDADEIRO VERDADEIRO VERDADEIRO
VERDADEIRO FALSO FALSO
FALSO VERDADEIRO FALSO
FALSO 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:
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.
Introdução à Programação I 23
JEDITM
}
}
0
10
false
0
11
false
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.
x1 x2 Resultado
VERDADEIRO VERDADEIRO VERDADEIRO
VERDADEIRO FALSO VERDADEIRO
FALSO VERDADEIRO VERDADEIRO
FALSO FALSO FALSO
Tabela 8: Tabela para || e |
Dada a expressão,
exp1 || exp2
o 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.
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
JEDITM
0
10
true
0
11
true
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.
x1 x2 Resultado
VERDADEIRO VERDADEIRO FALSO
VERDADEIRO FALSO VERDADEIRO
FALSO VERDADEIRO VERDADEIRO
FALSO 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 ^.
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);
}
}
false
true
false
true
Introdução à Programação I 25
JEDITM
13.4. ! (negação)
x1 Resultado
VERDADEIRO FALSO
FALSO VERDADEIRO
Tabela 10: Tabela para o operador !
false
true
Introdução à Programação I 26
JEDITM
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.
//status do aluno
status = (grade >= 60)?"Passed":"Fail";
//print status
System.out.println( status );
}
}
Passed
Introdução à Programação I 27
JEDITM
Score = 10
Introdução à Programação I 28
JEDITM
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:
Introdução à Programação I 29
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.
number = 10
letter = a
result = true
str = hello
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 é:
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:
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 + i
2. 3 * 10 *2 / 15 – 2 + 4 ^ 2 ^ 2
3. r ^ s * t / u – v + w ^ x – y++
Introdução à Programação I 30
Módulo 1
Introdução à Programação I
Lição 5
Capturando entrada de dados através do
teclado
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.
Introdução à Programação I 4
JEDITM
Passos para capturar os dados digitados, tomemos por base o programa visto na lição
anterior:
import java.io.*;
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");
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
Introdução à Programação I 5
JEDITM
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:
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:
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.
try {
name = dataIn.readLine();
} catch (IOException e) {
System.out.println("Error!");
}
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
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.
Introdução à Programação I 7
JEDITM
import java.util.Scanner;
Compare-o com o programa visto anteriormente. Percebe-se que fica mais simples conseguir a
mesma funcionalidade.
import java.util.Scanner;
Definimos uma variável, denominada sc, que será criada a partir da classe Scanner e
direcionada para a entrada padrão:
Utilizamos a variável sc para chamarmos o método que fará o recebimento dos dados
digitados:
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
JEDITM
Introdução à Programação I 9
JEDITM
import javax.swing.JOptionPane;
A primeira instrução:
import javax.swing.JOptionPane;
Introdução à Programação I 10
JEDITM
import javax.swing.*;
A instrução seguinte:
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.
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
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: Goodbye
Palavra 2: and
Palavra 3: Hello
Introdução à Programação I 12
Módulo 1
Introdução à Programação I
Lição 6
Estruturas de controle
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.
• 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
JEDITM
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.
if (expressão_lógica)
instrução;
ou:
if (expressão_lógica) {
instrução1;
instrução2
...
}
ou:
int grade = 68;
if (grade > 60) {
System.out.println("Congratulations!");
System.out.println("You passed!");
}
Introdução à Programação I 5
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;
}
if (expressão_lógica)
instrução_caso_verdadeiro;
else
instrução_caso_falso;
if (expressão_lógica) {
instrução_caso_verdadeiro1;
instrução_caso_verdadeiro2;
...
} else {
instrução_caso_falso1;
instrução_caso_falso2;
...
}
ou:
Introdução à Programação I 6
JEDITM
Dicas de programação:
if (expressão_lógica) {
if (expressão_lógica) {
...
} else {
...
}
} else {
...
}
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
JEDITM
// ERRADO
int number = 0;
if (number) {
// algumas instruções aqui
}
Introdução à Programação I 8
JEDITM
// ERRADO
int number = 0;
if (number = 0) {
// algumas instruções aqui
}
// ERRADO
int number = 0;
if (number == 0) {
// algumas instruções aqui
} elseif (number == 1) {
// algumas instruções aqui
}
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.
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.
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
JEDITM
Notas:
Dicas de Programação:
Introdução à Programação I 10
JEDITM
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
JEDITM
while (expressão_lógica) {
instrução1;
instrução2;
...
}
As instruções contidas dentro do bloco while são executadas repetidas vezes enquanto o valor
de expressão_lógica for verdadeira.
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.
Exemplo 1:
int x = 0;
while (x<10) {
System.out.println(x);
Introdução à Programação I 12
JEDITM
x++;
}
Exemplo 2:
// laço infinito
while (true)
System.out.println("hello");
Exemplo 3:
do {
instrução1;
instrução2;
...
} while (expressão_lógica);
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.
Exemplo 1:
int x = 0;
Introdução à Programação I 13
JEDITM
do {
System.out.println(x);
x++;
} while (x<10);
Exemplo 2:
// laço infinito
do {
System.out.println("hello");
} while(true);
Exemplo 3:
Este exemplo mostrará a palavra hello escrita na tela uma única vez.
Dicas de programação:
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.
onde:
Introdução à Programação I 14
JEDITM
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.
int i = 0;
while (i < 10) {
System.out.print(i);
i++;
}
Introdução à Programação I 15
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.
Por exemplo:
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.
teste:
Introdução à Programação I 16
JEDITM
O exemplo seguinte conta a quantidade de vezes que a expressão "Beah" aparece no array.
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
JEDITM
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
JEDITM
5. Exercícios
5.1. Notas
Obtenha 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 :-(
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.4. Potências
Receba como entrada um número e um expoente. Calcule este número elevado ao expoente.
Faça três versões deste programa:
Introdução à Programação I 19
Módulo 1
Introdução à Programação I
Lição 7
Array em Java
1. Objetivos
Nesta lição, abordaremos Array em Java. Primeiro, definiremos o que é array e, então,
discutiremos como declará-los e usá-los.
Introdução à Programação I 4
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.
Introdução à Programação I 5
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;
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ção
int ages[];
// construindo
ages = new int[100];
// declarar e construir
int ages[] = new int[100];
Exemplos:
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
JEDITM
Lembre-se que o array, uma vez declarado e construído, terá o valor de cada membro
inicializado automaticamente. Conforme a seguinte tabela:
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:
O código abaixo utiliza uma declaração for para mostrar todos os elementos de um array.
Introdução à Programação I 7
JEDITM
}
}
}
Dicas de programação:
int [] arr;
arr = new int[100];
Introdução à Programação I 8
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
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:
Introdução à Programação I 9
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 de caracteres de 8 x 16 x 24
char [][][] threeD = new char[8][16][24];
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:
Introdução à Programação I 10
JEDITM
7. Exercícios
Usando uma declaração while, imprima todo o conteúdo do array. Faça o mesmo para as
declarações do-while e for.
Name : Florence
Tel. # : 735-1234
Address: Manila
Name : Joyce
Tel. # : 983-3333
Address: Quezon City
Name : Becca
Tel. # : 456-3322
Address: Manila
Introdução à Programação I 11
Módulo 1
Introdução à Programação I
Lição 8
Argumentos de linha de comando
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.
Introdução à Programação I 4
JEDITM
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
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 firstArg = 0;
if (args.length > 0) {
firstArg = Integer.parseInt(args[0]);
}
Dicas de programação:
Introdução à Programação I 5
JEDITM
Introdução à Programação I 6
JEDITM
Introdução à Programação I 7
JEDITM
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.
Introdução à Programação I 8
JEDITM
Execute o projeto.
Introdução à Programação I 9
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:
world
that
is
all
java ArithmeticOperation 20 4
sum = 24
subtraction = 16
multiplication = 80
division = 5
Introdução à Programação I 10
Módulo 1
Introdução à Programação I
Lição 9
Trabalhando com Bibliotecas de Classe
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.
Introdução à Programação I 4
JEDITM
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.
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
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.
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.
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
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.
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.
ou, o equivalente:
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
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.
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.
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.
nomeDoObjeto.nomeDoMétodo([argumentos]);
Usando os métodos:
Introdução à Programação I 8
JEDITM
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.
Por exemplo:
Introdução à Programação I 9
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 );
Dicas de programação:
Introdução à Programação I 10
JEDITM
NomeClasse.nomeMétodoEstático(argumentos);
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.
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
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.
class TestPassByReference {
public static void main(String[] args) {
// criar um array de inteiros
int []ages = {10, 11, 12};
ages[] - escopo A
i em B - escopo B
i em C – escopo C
arr[] - escopo D
i 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:
Introdução à Programação I 12
JEDITM
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
JEDITM
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:
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)valor
onde:
tipoDado é o nome do tipo de dado para o qual se quer converter o valor
valor é um valor que se quer converter.
Por exemplo:
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:
Introdução à Programação I 14
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:
(nomeClasse)objeto
onde:
nomeClasse é o nome da classe destino
objeto é 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
JEDITM
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:
Usando as classes que correspondem a cada um dos tipos primitivos, é possível criar objetos
que armazenam este mesmo valor. Por exemplo:
Introdução à Programação I 16
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.
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:
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.
class EqualsTest {
public static void main(String[] args) {
String str1, str2;
str1 = "Free the bound periodicals.";
str2 = str1;
Introdução à Programação I 17
JEDITM
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.
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.
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
JEDITM
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:
Por exemplo:
Introdução à Programação I 19
JEDITM
6. Exercícios
6.1. Definindo termos
Em suas palavras, defina os seguintes termos:
1. Classe
2. Objeto
3. Instanciação
4. Atributo de objeto
5. Método de objeto
6. Atributo de classe ou atributos estáticas
7. Construtor
8. Método de classe ou métodos estáticos
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: Integer
Declaraçã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
Módulo 1
Introdução à Programação 1
Lição 10
Criando nossas classes
1. Objetivos
Algumas observações devem ser feitas quanto à sintaxe que será usada nesta
e nas próximas seções:
Introdução à Programação I 4
JEDITM
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.
Dicas de programação:
onde:
Introdução à Programação I 5
JEDITM
Dicas de programação:
Introdução à Programação I 6
JEDITM
3. Declarando Atributos
onde:
nome - String
endereço - String
idade - int
nota de matemática - double
nota de inglês - double
nota de ciências - double
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:
Introdução à Programação I 7
JEDITM
onde:
Dicas de programação:
Introdução à Programação I 8
JEDITM
Introdução à Programação I 9
JEDITM
4. Declarando Métodos
onde:
<tipoArgumento> <nomeArgumento>
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.
Introdução à Programação I 10
JEDITM
return name;
}
}
onde:
A instrução:
return name;
Introdução à Programação I 11
JEDITM
onde:
A instrução:
name = temp;
É 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.
Introdução à Programação I 12
JEDITM
if (num == 1) {
return "one"; // retorna uma constante
} else if( num == 2) {
return "two"; // retorna uma constante
}
// retorna um atributo
return defaultNum;
}
onde:
Dicas de programação:
Introdução à Programação I 13
JEDITM
/**
* Retorna o nome do estudante
*/
public String getName(){
return name;
}
/**
* Muda o nome do estudante
*/
public void setName( String temp ){
name = temp;
}
/**
* 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
JEDITM
StudentRecord.
Anna
Count = 0
Introdução à Programação I 15
JEDITM
5. this
age = age;
this.<nomeDoAtributo>
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
JEDITM
6. Overloading de Métodos
annaRecord.setName("Anna");
annaRecord.setAddress("Philippines");
annaRecord.setAge(15);
Introdução à Programação I 17
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());
}
Name:Anna
Address:Philippines
Age:15
Name:Anna
Math Grade:80.0
English Grade:95.5
Science Grade:100.0
1. o mesmo nome
2. argumentos diferentes
3. tipo do retorno igual ou diferente
Introdução à Programação I 18
JEDITM
7. Declarando Construtores
public StudentRecord() {
}
public StudentRecord() {
// qualquer código de inicialização aqui
}
public StudentRecord(String temp){
Introdução à Programação I 19
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;
}
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
JEDITM
}
public StudentRecord(double mGrade, double eGrade,
double sGrade) {
studentCount++; // adicionar um estudante
mathGrade = mGrade;
englishGrade = eGrade;
scienceGrade = sGrade;
}
public StudentRecord() {
this("some string");
}
public StudentRecord(String temp) {
this.name = temp;
}
public static void main( String[] args ) {
StudentRecord annaRecord = new StudentRecord();
}
public StudentRecord() {
studentCount++; // adicionar um estudante
}
public StudentRecord(String name) {
this();
Introdução à Programação I 21
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
JEDITM
8. Pacotes
import <nomeDoPacote>.<nomeDaClasse>;
import java.awt.Color;
ou:
import java.awt.*;
java.awt.Color color;
package <nomeDoPacote>;
Introdução à Programação I 23
JEDITM
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;
C:\schoolClasses>javac StudentRecord.java
C:\schoolClasses>java StudentRecord
Exception 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)
Introdução à Programação I 24
JEDITM
C:\schoolClasses>set classpath=C:\
C:\schoolClasses>java schoolClasses.StudentRecord
export classpath=/usr/local/myClasses
set classpath=C:\myClasses;D:\;E:\MyPrograms\Java
export classpath=/usr/local/java:/usr/myClasses
Introdução à Programação I 25
JEDITM
9. Modificadores de Acesso
Introdução à Programação I 26
JEDITM
Especifica que somente classes no mesmo pacote podem ter acesso aos
atributos e métodos da classe. Por exemplo:
Introdução à Programação I 27
JEDITM
Dicas de programação:
Introdução à Programação I 28
JEDITM
10. Exercícios
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
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 registro
2. Excluir registro
3. Visualizar registros
4. Modificar um registro
Introdução à Programação I 29
Módulo 1
Introdução à Programação I
Lição 11
Herança, polimorfismo e interfaces
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.
Introdução à Programação I 4
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).
/**
* 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
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:
Introdução à Programação I 6
JEDITM
Inside Person:Constructor
Inside 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.
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.
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 pai
this.name = "student name"; // Nome da classe atual
}
Introdução à Programação I 7
JEDITM
Student: getName
Parent: getName
Student: getName
Introdução à Programação I 8
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:
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
JEDITM
3. Polimorfismo
Considerando 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:
Supondo que tenhamos um método getName em nossa superclasse Person, iremos realizar
uma modificação deste nas subclasses Student e Employee:
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.
Introdução à Programação I 10
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);
}
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.
Introdução à Programação I 11
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:
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
JEDITM
Se a classe Human não implementar o método walk, será mostrada a seguinte mensagem de
erro de compilação:
Dicas de programação:
Introdução à Programação I 13
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.
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:
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.
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.
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
JEDITM
Entretanto, não se pode criar uma instância de uma interface sem implementá-la. Um exemplo
disso é:
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.
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
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:
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.
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:
Outro exemplo de uma classe que estende de outra superclasse e implementa interfaces:
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
JEDITM
Introdução à Programação I 17
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.
Introdução à Programação I 18
Módulo 1
Introdução à Programação I
Lição 12
Tratamento básico de exceções
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.
Introdução à Programação I 4
JEDITM
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:
Introdução à Programação I 5
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.
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.
Para um melhor entendimento, observe a figura 1 que demonstra o fluxo seguido pelo try-
catch-finally:
Introdução à Programação I 6
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.
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:
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
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
JEDITM
4. Exercícios
4.1. Capturando Exceções 1
Dada a seguinte classe:
Modifique a classe TestException para tratar esta exceção. A saída depois do tratamento da
exceção deverá ser:
Introdução à Programação I 9
Módulo 1
Introdução à Programação 1
Apêndice A
Instalação do Java e do NetBeans
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 Windows:
Copie os instaladores em qualquer diretório temporário.
Introdução à Programação I 4
JEDITM
Introdução à Programação I 5
JEDITM
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.
cd /usr/local/bin
Introdução à Programação I 6
JEDITM
sudo ln -s /usr/java/jdk1.5.0_07/bin/* .
Introdução à Programação I 7
JEDITM
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
JEDITM
Introdução à Programação I 9
JEDITM
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
JEDITM
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
JEDITM
Modifique o nome do diretório para: /usr/java/netbeans-5.5, então pressione o botão Next >.
Introdução à Programação I 12
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.
Introdução à Programação I 13
JEDITM
cd /usr/local/bin
sudo ln -s /usr/java/netbeans-5.5 .
netbeans &
Introdução à Programação I 14
JEDITM
Introdução à Programação I 15
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
JEDITM
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
JEDITM
Introdução à Programação I 18
Módulo 1
Introdução à Programação 1
Apêndice B
Conhecendo seu ambiente de
programação (versão Windows XP)
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.
Introdução à Programação I 4
JEDITM
Introdução à Programação I 5
JEDITM
Passo 2: Para abrir uma janela de console, clique em Start Programs Accessories
Comand Prompt.
Introdução à Programação I 6
JEDITM
Depois de executar o procedimento acima descrito, uma caixa de diálogo será mostrada,
conforme a Figura 4.
Pressione o botão MY DOCUMENTS para abrir a pasta My Documents onde salvaremos nossos
programas em Java.
Introdução à Programação I 7
JEDITM
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.
Após criar a pasta, digite o nome MYJAVAPROGRAMS, e então pressione a tecla ENTER.
Introdução à Programação I 8
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
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
JEDITM
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
JEDITM
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
JEDITM
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!".
Introdução à Programação I 13
JEDITM
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.
Introdução à Programação I 14
JEDITM
5. Utilizando NetBeans
Como 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.
Passo 2: Vamos criar um projeto para o NetBeans. Selecione File New Project.
Introdução à Programação I 15
JEDITM
Introdução à Programação I 16
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".
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
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.
Se não houver nenhum erro em seu programa, você verá uma mensagem de “build successful”
Introdução à Programação I 18
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.
Introdução à Programação I 19
Módulo 1
Introdução à Programação 1
Apêndice C
Respostas dos exercícios
Requerimentos de Software
NetBeans 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.html
2. 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).
Introdução à Programação I 2
JEDITM
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
JEDITM
Fluxograma:
Introdução à Programação I 4
JEDITM
2. Acessar o computador
Pseudo código:
Fazer power = botão ligar do computador
Fazer in = status do usuário (inicialmente falso)
Se power == off
Pressione o botão ligar
Aguardar o procedimento inicial
Enquanto 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
JEDITM
Fluxograma:
Introdução à Programação I 6
JEDITM
1980/2 = 990 0
247/2 = 123 1
123/2 = 61 1
61/2 = 30 1
30/2 = 15 0
15/2 = 7 1
7/2 = 3 1
3/2 = 1 1
1/2 = 0 1
Binário = 11110111100
Para Hexadecimal:
0111, 1011, 1100,
7 B C
Hexadecimal = 7BC
Para Octal:
011, 110, 111, 100
3 6 7 4
Octal = 3674
Para Hexadecimal:
0010, 0100, 1101
2 4 D
Hexadecimal = 24D
Para Octal:
001, 001, 001, 101
1 1 1 5
Octal = 1115
Introdução à Programação I 7
JEDITM
Binário = 111110
Para Hexadecimal:
0011, 1110,
3 E
Hexadecimal = 3E
Para Decimal:
6 * 1 = 6
7 * 8 = 56
TOTAL = 62
Decimal = 62
Para Decimal:
F * 1 = 15
3 * 16 = 48
4 * 256 = 1024
TOTAL = 1087
Decimal = 1087
Para Octal:
010, 000 , 111 , 111
2 0 7 7
Octal = 2077
Introdução à Programação I 8
JEDITM
Introdução à Programação I 9
JEDITM
/**
* 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
JEDITM
Introdução à Programação I 11
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);
}
}
Introdução à Programação I 12
JEDITM
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
JEDITM
Introdução à Programação I 14
JEDITM
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
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+" :-(");
}
}
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
JEDITM
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
JEDITM
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
JEDITM
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]);
Introdução à Programação I 19
JEDITM
Introdução à Programação I 20
JEDITM
Introdução à Programação I 21
JEDITM
//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");
}
}
1. Classe: String
Método: public boolean endsWith(String suffix)
2. Classe: Character
Método: public static char forDigit(int digit, int radix)
3. Classe: Math
Método: public static double floor(double a)
4. Classe: Math
Método: public static boolean isDigit(char ch)
5. Classe: System
Método: public static void exit(int status)
Introdução à Programação I 22
JEDITM
/**
* 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
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. Agenda
import 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
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
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
JEDITM
/**
* 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;
/**
* 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
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
JEDITM
/**
* Altera a nota de ciência de computação do estudante
*/
public void setComSciGrade(double temp) {
comSciGrade = temp;
}
}
/**
* 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
JEDITM
/**
* 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
JEDITM
Introdução à Programação I 31
Módulo 1
Introdução à Programação 1
Apêndice D
Testes de programação
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 (fernando.anselmo@dfjug.org) 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:
Introdução à Programação I 4
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.
MENUPRINCIPAL
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
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
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.
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
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
Módulo 2
Introdução à Programação II
Lição 1
Revisão dos Conceitos Básicos em Java
Requerimentos de Software
NetBeans 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).
Introdução à Programação II 2
JEDITM
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 II 3
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.
Introdução à Programação II 4
JEDITM
2.2. Classe
Permite 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. Atributo
Refere-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étodo
Descreve 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. Encapsulamento
Princípio de ocultar a modelagem ou as informações de implementação que não são referentes ao
objeto atual.
2.9. Abstração
Princí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
JEDITM
2.10. Herança
Princí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 UnderwaterSuperHero
Figura 1: Exemplo de herança
2.11. Polimorfismo
Habilidade 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
JEDITM
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]);
}
}
}
Guia de código:
Introdução à Programação II 7
JEDITM
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;
}
}
Dicas de programação:
Introdução à Programação II 8
JEDITM
ConstructObj() {
/* Inicialização dos dados */
}
public static void main(String args[]) {
ConstructObj obj = new ConstructObj();
}
}
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
}
}
10
3.7. Pacotes
Para indicar que uma determinada classe pertence a um pacote em particular, utilizamos a
seguinte sintaxe:
<declaraçãoPacote> ::=
package <nomePacote>;
Guia de código:
+ que pode ter 1 ou mais ocorrências da linha onde isso foi aplicado.
Introdução à Programação II 9
JEDITM
package registration.reports;
3.9. Encapsulamento
Protege 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ça
Para 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.
import java.awt.*;
class Point {
int x;
Introdução à Programação II 10
JEDITM
int y;
}
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);
}
}
sub: 3
sub: 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() {
}
}
Introdução à Programação II 11
JEDITM
Uma classe contendo um método abstrato deve ser declarada como uma classe abstrata.
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:
3.13. Interface
Declarar 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
JEDITM
<declaraçãoInterface> ::=
<modificador> interface <Nome> {
<declaraçãoAtributo>*
[<modificador> <tipoRetorno> <nome>(<argumento>*);]*
}
Dicas de programação:
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 InterfaceDemo {
public static void main(String args[]) {
MyClass1 mc1 = new MyClass1();
MyClass2 mc2 = new MyClass2();
mc1.iMethod();
mc1.myMethod();
mc2.iMethod();
}
}
Introdução à Programação II 13
JEDITM
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();
}
}
Dicas de programação:
Introdução à Programação II 14
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;
}
}
Dicas de programação:
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 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
JEDITM
a = 1
a = 2
a = 3
2
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);
}
}
Introdução à Programação II 16
JEDITM
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:
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();
}
}
Introdução à Programação II 17
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
Módulo 2
Introdução à Programação II
Lição 2
Exceções e Assertivas
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.
Introdução à Programação II 4
JEDITM
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.
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.
class DivByZero {
public static void main(String args[]) {
System.out.println(3/0);
System.out.println(“Pls. print me.”);
}
}
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
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.
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:
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.”);
}
}
java.lang.ArithmeticException: / by zero
After 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
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.”);
}
}
Veja o que acontece ao executar a classe quando os seguintes argumentos abaixo são informados
pelo usuário:
Missing argument.
After exception.
3
After exception.
Divisor was 0.
After exception.
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!");
}
}
}
a) Nenhum argumento
Introdução à Programação II 7
JEDITM
b) Valor 15
c) Valor 15 3
d) Valor 15 0
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!");
}
}
}
a) Nenhum argumento
b) 15
c) 15 3
d) 15 0
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
JEDITM
Dicas de programação:
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.
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!");
}
}
}
}
2
Finally forever!
Divide by zero error!
Finally forever!
Introdução à Programação II 9
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>;
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);
}
}
}
É 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.
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);
}
}
}
Introdução à Programação II 10
JEDITM
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.
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();
}
}
}
first case
try-block is entered.
second case
try-block is entered.
third case
RuntimeException caught: third case demo
try-block is entered.
fourth case
try-block is entered.
Exception caught: fourth case demo
Introdução à Programação II 11
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.
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
JEDITM
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.
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:
Introdução à Programação II 13
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.
Para compilar arquivos que usam assertivas, um parâmetro extra na linha de comando é
necessário como mostrado abaixo:
java MyProgram
Todavia, para habilitar o recurso das assertivas, é necessário utilizar os argumentos –ea ou
-enableassertions:
1. Procure o nome do projeto no painel Projects à esquerda. Pressione com o botão direito no
nome do projeto
2. Selecione Properties
3. À esquerda, no painel Categories, selecione run
4. No campo VM Options insira -ea
5. Clique no botão OK
6. Compile e execute o projeto normalmente.
Introdução à Programação II 14
JEDITM
Introdução à Programação II 15
JEDITM
assert <expressãoLógica>;
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.
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
JEDITM
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:
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.
Para os outros casos, esta classe nos apresenta uma saída similar ao exemplo anterior.
Introdução à Programação II 17
Módulo 2
Introdução à Programação II
Lição 3
Técnicas Avançadas de Programação
1. Objetivos
Esta lição introduz algumas técnicas avançadas de programação. Veremos detalhes sobre
recursão e tipos de dados abstratos.
Introdução à Programação II 4
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.
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.
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
JEDITM
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));
}
}
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));
}
}
a) Entrada: 1
1
b) Entrada: 3
6
c) Entrada: 5
120
Introdução à Programação II 6
JEDITM
Na solução, 10 é equivalente a 12 base 8. Aqui está outro exemplo. A entrada decimal é 165 para
ser convertida em base 16.
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));
}
}
}
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
JEDITM
Introdução à Programação II 8
JEDITM
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.
n-1
...
6
5 Jayz Top
4 KC
3 Jojo
2 Toto
1 Kyla
0 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
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).
0 1 2 3 4 5 6 7 8 9 ... n-1
Eve Jayz KC Jojo Toto Kyla DMX
front 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.
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.
Introdução à Programação II 10
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());
}
}
Introdução à Programação II 11
JEDITM
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.
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;
}
}
}
Introdução à Programação II 12
JEDITM
Introdução à Programação II 13
JEDITM
Agora que aprendemos sobre lista encadeada, estamos prontos para implementar uma
representação encadeada de uma pilha.
Introdução à Programação II 14
JEDITM
Introdução à Programação II 15
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> <interface>
Set 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
JEDITM
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
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);
}
}
Introdução à Programação II 18
Módulo 2
Introdução à Programação II
Lição 4
Passeio pelo pacote java.lang
1. Objetivos
Java possui muitas classes úteis para serem utilizadas. Nesta lição iremos explorá-las.
Introdução à Programação II 4
JEDITM
2. Classe Math
Java 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:
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
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.
Introdução à Programação II 6
JEDITM
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.
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);
}
}
hello
world
ell
hello
hello
Introdução à Programação II 7
JEDITM
Introdução à Programação II 8
JEDITM
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);
}
}
name: Jonathan
3rd character of name: n
Jonathan compared to Solomon: -9
Solomon compared to Jonathan: 9
Jonathan compared to jonathan: -32
Jonathan compared to jonathan (ignore case): 0
Is Jonathan equal to Jonathan? true
Is Jonathan equal to jonathan? false
Is Jonathan equal to jonathan (ignore case)? true
content of charArr after getChars method: Hi Jo
Length of name: 8
Replace a's with e's in name: Jonethen
A substring of name: Jo
Trim " a b c d e f ": "a b c d e f"
String representation of boolean expression 10>10: false
String representation of boolean expression 10<10: false
name: Jonathan
Introdução à Programação II 9
JEDITM
Aqui estão alguns dos métodos da Classe StringBuffer. Para maiores informações consulte a
documentação da API Java.
class StringBufferDemo {
public static void main(String args[]) {
Introdução à Programação II 10
JEDITM
sb = Jonathan
capacity of sb: 24
append 'O' to sb: JonathanO
sb = JonathanO
3rd character of sb: n
getChars method: Hi Jo
Insert 'jo' at the 3rd cell: JojonathanO
Delete 'jo' at the 3rd cell: JonathanO
length of sb: 9
replace: Jon Ong
substring (1st three characters): Jon
implicit 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:
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
JEDITM
Hello : 69609650
Hello World!! : 22678948
Hello : 17523401
Hello 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
JEDITM
4. Classes Wrapper
Obviamente, 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:
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);
}
}
booleanVar = false
booleanObj = true
booleanObj2 = false
compare 2 wrapper objects: false
booleanVar = true
Introdução à Programação II 13
JEDITM
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.");
}
}
}
Introdução à Programação II 14
JEDITM
Introdução à Programação II 15
JEDITM
6. Classe System
A 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.
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
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
Módulo 2
Introdução à Programação II
Lição 5
Aplicações Textuais
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.
Introdução à Programação II 4
JEDITM
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.
Introdução à Programação II 5
JEDITM
Propriedades de sistema são bastante semelhantes às variáveis de ambiente. Porém, não são
Introdução à Programação II 6
JEDITM
É 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);
-- 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-b05
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
user.country=US
sun.os.patch.level=Service Pack 2
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Documents and Settings\becca\Neste...
java.runtime.version=1.5.0_06-b05
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jdk1.5.0_06\jre...
os.arch=x86
java.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
JEDITM
os.name=Windows XP
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jdk1.5.0_06\jre...
java.specification.name=Java Platform API Specification
java.class.version=49.0
sun.management.compiler=HotSpot Client Compiler
os.version=5.1
user.home=C:\Documents and Settings\becca
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=Cp1252
java.specification.version=1.5
user.name=becca
java.class.path=C:\Documents and Settings\becca\Neste...
java.vm.specification.version=1.0
sun.arch.data.model=32
java.home=C:\Program Files\Java\jdk1.5.0_06\jre
java.specification.vendor=Sun Microsystems Inc.
user.language=en
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode, sharing
java.version=1.5.0_06
java.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=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=
Introdução à Programação II 8
JEDITM
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:
O método read do objeto do tipo BufferedReader é utilizado para ler do dispositivo de entrada.
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:
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
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 é:
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
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.
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.
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
JEDITM
Assumindo que temp.txt existe e seja o arquivo de texto, está é uma possível saída 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.
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
JEDITM
fos.write(data);
}
} while (!done);
} catch (IOException ex) {
System.out.println("Problem in reading from the file.");
}
}
}
Introdução à Programação II 13
Módulo 2
Introdução à Programação II
Lição 6
Algoritmos de Ordenação
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.
Introdução à Programação II 4
JEDITM
2.1. O algoritmo
2.2. Um exemplo
Introdução à Programação II 5
JEDITM
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
3.2. Um exemplo
Introdução à Programação II 6
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.
1.Dividir
Dividir o problema principal em subproblemas.
2.Conquistar
Conquistar 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.Combinar
Unir as soluções dos subproblemas, direcionando à solução do problema principal.
1.Dividir
Dividir a sequência dos elementos dados em duas partes.
2.Conquistar
Conquistar cada parte de modo repetitivo, chamando o método Merge Sort.
3.Combinar
Combinar 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
Introdução à Programação II 7
JEDITM
4.4. Um exemplo
Dados:
7 2 5 6
ArrayEsq ArrayDir
7 2 5 6
ArrayEsq ArrayDir
7 2
Combinar
2 7
ArrayEsq ArrayDir
5 6
Combinar
5 6
Combinar
ArrayEsq e ArrayDir.
2 5 6 7
Figura 3: Exemplo de Merge sort
Introdução à Programação II 8
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.Dividir
Separaçã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.Conquistar
Ordenar os subarrays pela recursividade, chamado de método quickSort.
5.1. O algoritmo
5.2. Um exemplo
Array dado:
3 1 4 1 5 9 2 6 5 3 5 8
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
Introdução à Programação II 9
JEDITM
Esq. Dir.
3 1 3 1 5 9 2 6 5 4 5 8
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
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
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
Módulo 2
Introdução à Programação II
Lição 7
Abstract Window Toolkit e Swing
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.
Introdução à Programação II 4
JEDITM
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
JEDITM
Para configurar o tamanho da janela, podemos utilizar o método setSize, do seguinte modo:
Reconfigura o tamanho da janela para o width (largura) e height (altura) fornecidos como
argumentos.
void setSize(Dimension d)
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.*;
Introdução à Programação II 6
JEDITM
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.
Relacionada a essa classe está a classe Color, que tem três construtores.
Aqui está uma classe demonstrando a utilização de alguns métodos da classe Graphics:
import java.awt.*;
Introdução à Programação II 7
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.
Introdução à Programação II 8
JEDITM
import java.awt.*;
Introdução à Programação II 9
JEDITM
4. Gerenciadores de Layout
A 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:
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:
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
Introdução à Programação II 10
JEDITM
• FlowLayout.RIGHT
import java.awt.*;
Construtores BorderLayout
BorderLayout()
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
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
JEDITM
• BorderLayout.SOUTH
• BorderLayout.EAST
• BorderLayout.WEST
• BorderLayout.CENTER
Aqui está uma classe demonstrando como a BorderLayout pode ser utilizada:
import java.awt.*;
Aqui está o resultado desta classe. A segunda figura mostra o efeito do redimensionamento do
frame.
Construtores GridLayout
GridLayout()
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
JEDITM
import java.awt.*;
import java.awt.*;
Introdução à Programação II 13
JEDITM
Introdução à Programação II 14
JEDITM
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.
Para a lista completa de componentes Swing, por favor recorra à documentação API.
Introdução à Programação II 15
JEDITM
import javax.swing.*;
import java.awt.*;
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:
Introdução à Programação II 16
Módulo 2
Introdução à Programação II
Lição 8
Tratamento de Eventos em Interfaces Gráficas
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.
Introdução à Programação II 4
JEDITM
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
JEDITM
<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.
Introdução à Programação II 6
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:
<Tipo>Event
Introdução à Programação II 7
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:
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
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
Introdução à Programação II 8
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
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
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
JEDITM
Introdução à Programação II 10
JEDITM
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.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
Introdução à Programação II 11
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");
}
}
Introdução à Programação II 12
JEDITM
Introdução à Programação II 13
JEDITM
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Introdução à Programação II 14
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.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
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
JEDITM
6. Inner Class
Nesta 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.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Introdução à Programação II 16
Módulo 2
Introdução à Programação II
Lição 9
Threads
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.
Introdução à programação II 4
JEDITM
Figura 1: Threads
• Read
A 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
JEDITM
• Running
A thread esta sendo executada e esta sob controle da CPU.
• Sleeping
A thread é interrompida por determinado tempo.
• Waiting
A thread é interrompida por indeterminado tempo.
• Blocked
Uma thread bloqueada não é capaz de rodar, pois esta esperando por um recurso
disponível ou que algum evento aconteça.
• Dead
A 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
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
JEDITM
import javax.swing.*;
import java.awt.*;
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
JEDITM
Introdução à programação II 9
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).
Neste próximo exemplo, veremos uma classe que mostra 100 vezes o nome do objeto thread.
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:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDABCDABCDABCDABCD
ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDAB
CDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCD
BCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDB
CDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCD
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á.
Introdução à programação II 10
JEDITM
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.
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.
Introdução à programação II 11
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.
Running Threads…
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDBCDBCDBCDBCBCBCBCBCBCDB
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Threads 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
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.
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:
Introdução à programação II 13
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.
synchronized (<object>) {
//trecho de código a ser sincronizado
}
Com isso, os métodos do objeto podem ser invocados uma vez por thread.
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 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
JEDITM
}
}
Hello there.
How are you?
Thank you very much!
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 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);
}
}
Introdução à programação II 15
JEDITM
Observe neste cenário que a parte que aguarda é executada assim que o cliente informa o
garçom. O mesmo é verdade nas threads.
Introdução à programação II 16
JEDITM
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;
}
}
Generate 8
Generate 45
Generate 52
Generate 65
Get 65
Generate 23
Introdução à programação II 17
JEDITM
Get 23
Generate 49
Get 49
Generate 35
Get 35
Generate 39
Get 39
Generate 85
Get 85
Get 85
Get 85
Generate 35
Get 35
Get 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 76
Get 76
Generate 25
Get 25
Generate 34
Get 34
Generate 84
Get 84
Generate 48
Get 48
Generate 29
Get 29
Generate 26
Get 26
Generate 86
Get 86
Generate 65
Get 65
Generate 38
Get 38
Generate 46
Get 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
JEDITM
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
JEDITM
7. Utilidades concorrentes
Com 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.
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.
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:
Introdução à programação II 20
JEDITM
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();
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.
import java.util.concurrent.*;
Introdução à programação II 21
JEDITM
return someValue;
}
}
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
Módulo 2
Introdução à Programação II
Lição 10
Redes
1. Objetivos
A 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.
Introdução à Programação II 4
JEDITM
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.
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
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.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.
Introdução à Programação II 6
JEDITM
import java.net.*;
import java.io.*;
Introdução à Programação II 7
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) {
}
}
}
}
O exemplo a seguir é uma implementação de um cliente simples, que apenas envia dados para
um servidor.
Introdução à Programação II 8
JEDITM
import java.io.*;
import java.net.*;
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:
Introdução à Programação II 9
JEDITM
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.
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.
Introdução à Programação II 10
JEDITM
import java.net.*;
import java.net.*;
import java.io.*;
Aqui está uma amostra de execução das classes ChatServer e ChatClient, assumindo que
ChatServer foi executada antes de rodarmos a classe cliente:
Introdução à Programação II 11
JEDITM
Introdução à Programação II 12
Módulo 2
Introdução à Programação II
Lição 11
Applets
1. Objetivos
Applets é 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.
Introdução à Programação II 4
JEDITM
2. Criando Applets
Uma 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.
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.*;
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:
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.
Outra forma de executar uma applet é através do aplicativo appletviewer. Simplesmente siga
essa sintaxe:
Introdução à Programação II 5
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
JEDITM
3. Métodos da Applet
Esta secção demonstrará alguns métodos de Applets extremamente interessantes
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.*;
<HTML>
<TITLE>Life Cycle Demo</TITLE>
Introdução à Programação II 7
JEDITM
import java.awt.*;
import java.applet.*;
O próximo exemplo reproduz continuamente um áudio até que o método stop da applet seja
Introdução à Programação II 8
JEDITM
acionado.
import java.awt.*;
import java.applet.*;
Introdução à Programação II 9
JEDITM
<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>
VSPACE, HSPACE
Espaço acima e abaixo (VSPACE) e o dos lados (HSPACE) do applet.
PARAM NAME, VALUE
Serve 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
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.
import java.awt.*;
import java.applet.*;
O resultado dessa classe é o mesmo da AppletDemo. Logo abaixo vemos a tela com o resultado
esperado:
Introdução à Programação II 11
Módulo 2
Introdução à Programação II
Lição 12
Stream de Entrada e Saída de Dados (I/O)
Avançados
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.
Introdução à programação II 4
JEDITM
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.
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.
Introdução à programação II 5
JEDITM
3. Classe File
A classe File não é uma classe do tipo Stream, é uma representação abstrata de arquivos reais e
de caminhos de diretórios.
A classe File provê diversos métodos para manipulação de arquivos e diretórios. Na tabela abaixo
estão alguns destes métodos:
Introdução à programação II 6
JEDITM
import java.io.*;
Name: temp.txt
temp.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:
Introdução à programação II 7
JEDITM
4. Classe Reader
Esta seção descreve Stream de caracteres que são utilizados para leitura.
Subclasses de Reader
FileReader
Para leitura a partir de arquivos de caracteres.
CharArrayReader
Implementa um buffer de caracteres a partir do qual pode-se ler.
StringReader
Para leitura a partir de uma String.
PipedReader
Introdução à programação II 8
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
Subclasses de FilterReader
BufferedReader
Permite o armazenamento de caracteres em um buffer, de forma a prover uma eficiente
leitura de caracteres, matrizes, e linhas.
FilterReader
Para ler Stream de caracteres filtrados.
InputStreamReader
Converte bytes lidos em caracteres.
LineNumberReader
Uma subclasse da classe BufferedReader que é capaz de manter registro do número das
linhas.
PushbackReader
Uma 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
JEDITM
5. Classe Writer
Nesta seção descrevemos os Stream de caracteres que são utilizados para escrita.
Subclasses de Writer
FileWriter
Para escrever caracteres a um arquivo.
CharArrayWriter
Implementa um buffer de caracteres para o qual pode-se escrever.
StringWriter
Para escrever em uma String.
PipedWriter
Usado 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
JEDITM
Subclasses de FilterWriter
BufferedWriter
Permite o uso de buffers de caracteres de forma a prover eficiente escrita de caracteres,
matrizes, e linhas.
FilterWriter
Para escrever Stream de caracteres filtrados.
OutputStreamWriter
Codifica caracteres escritos a ele em bytes.
PrintWriter
Imprime 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
JEDITM
6. Um Exemplo de Reader/Writer
O 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();
}
}
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:
Introdução à programação II 12
JEDITM
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();
}
}
Introdução à programação II 13
JEDITM
8. Classe InputStream
Esta seção dá uma visão geral dos diferentes Stream de bytes que são utilizados para leitura.
Subclasses de InputStream
FileInputStream
Para leitura de bytes a partir de um arquivo.
BufferedInputStream
Implementa um buffer que contém bytes, os quais podem ser lidos a partir do Stream.
PipedInputStream
Deveria 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
JEDITM
Subclasses de FilterInputStream
BufferedInputStream
Uma subclasse de FilterInputStream que permite o uso de um buffer de entrada de
forma a prover a eficiente leitura de bytes.
FilterInputStream
Para ler Stream de bytes filtrados, os quais podem transformar a fonte básica de dados
no decorrer do processo e prover funcionalidades adicionais.
ObjectInputStream
Usado para serialização de objetos. De-serializa objetos e dados primitivos previamente
escritos usando um ObjectOutputStream.
DataInputStream
Uma 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.
LineNumberInputStream
Uma subclasse de FilterInputStream que permite monitorar o número de linha atual.
PushbackInputStream
Uma 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
JEDITM
9. Classe OutputStream
Esta seção dá uma visão geral dos diferentes Stream de bytes que são utilizados para escrita.
Subclasses de OutputStream
FileOutputStream
Para escrever bytes a um arquivo.
BufferedOutputStream
Implementa um buffer que contém bytes, os quais podem ser escritos no Stream.
PipedOutputStream
Deveria 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
JEDITM
Subclasses de FilterOutputStream
BufferedOutputStream
Uma 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.
FilterOutputStream
Para escrever Stream de bytes filtrados, os quais podem transformar a fonte de dados
básica ao longo do processo e prover funcionalidades adicionais.
ObjectOutputStream
Usado para serialização de objetos. Serializa objetos e dados primitivos a um
OutputStream.
DataOutputStream
Uma 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.
PrintStream
Uma 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
JEDITM
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();
}
}
Introdução à programação II 18
JEDITM
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();
}
}
Teste este código em um arquivo contendo algumas poucas linhas ou caracteres. Supondo um
arquivo chamado temp.txt contendo o seguinte texto:
one 1
two
Introdução à programação II 19
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.
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.
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:
import java.io.*;
Introdução à programação II 20
JEDITM
O tipo Object retornado deveria sofrer typecasting ao nome de classe apropriado antes que
métodos naquela classe possam ser executados.
import java.io.*;
Introdução à programação II 21
JEDITM
Introdução à programação II 22
Módulo 2
Introdução à Programação II
Lição 13
Introdução à Generics
1. Objetivos
A 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.
Introdução à Programação II 4
JEDITM
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:
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:
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.String
required: java.lang.Integer
Integer 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:
Introdução à Programação II 5
JEDITM
Ao invés de uma longa discussão sobre como declarar uma classe utilizando Generics, veremos
um exemplo:
Iremos agora passar pelas instruções que possuem a sintaxe que utilizam Generics.
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
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:
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:
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.
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.
Por exemplo, o comando a seguir seria ilegal, uma vez que int é um tipo de dado primitivo.
Você terá que encapsular os tipos primitivos primeiro, antes de usá-los como argumentos
Generics.
Introdução à Programação II 7
JEDITM
Para compilar códigos fonte Java com Generics usando JDK (v. 1.5.0), utilize a seguinte
sintaxe:
onde src refere-se à localização do código fonte java, enquanto class refere-se à localização
onde o arquivo da classe será gravado.
Introdução à Programação II 8
JEDITM
4. Generics Limitados
No 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.
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
JEDITM
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.
class Utilities {
/* T extends Object implicitamente */
public static <T> ArrayList<T> make(T first) {
return new ArrayList<T>(first);
}
}
Utilities.make(Integer(0));
Introdução à Programação II 10
JEDITM
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);
}
}
[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
JEDITM
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);
}
}
Introdução à Programação II 12
JEDITM
Instituto CTS
Patrocinador do DFJUG.
Sun Microsystems
Fornecimento de servidor de dados para o armazenamento dos vídeo-aulas.
DFJUG
Detentor dos direitos do JEDITM nos países de língua portuguesa.
Banco do Brasil
Disponibilização de seus telecentros para abrigar e difundir a Iniciativa JEDITM.
Politec
Suporte e apoio financeiro e logístico a todo o processo.
Borland
Apoio internacional para que possamos alcançar os outros países de língua
portuguesa.
Instituto Gaudium/CNBB
Fornecimento 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