Você está na página 1de 51

JAVA BÁSICO

Lição 1 – Histórico

O que é Java?
Java é uma linguagem de programação orientada à objetos resultado de um consistente desenvolvimento e
trabalho de pesquisa realizado por projetistas da Sun Microsystems, que introduziu a linguagem no mercado em
1995. Mais do que uma simples linguagem de programação Java é um ambiente de desenvolvimento e execução de
programas, uma plataforma segura e capaz de proporcionar as facilidades da orientação à objetos aliadas à uma
portabilidade instrínseca que facilita a sua integração aos diversos ambientes existentes.

História
Um grupo de engenheiros da Sun Microsystems denominado Green, em 1991, foram encarregados de criar uma
nova geração de computadores inteligentes, simples e portáteis capazes de se comunicar entre si, ou seja, com uma
capacidade de uso potencialmente alta. Para tal, era necessário que fosse utilizada uma plataforma de
desenvolvimento em que os softwares pudessem ser portáveis para os mais diferentes equipamentos como controles
de TV, telefones, fornos, geladeiras, etc.

O C++ foi a primeira escolha como ponto de partida para tal desenvolvimento. No entanto, as facilidades de
orientação à objeto introduzidas pelo C++ não foram suficientes para alcançar tudo aquilo que o grupo almejava. Foi
então que James Gosling, coordenador do projeto Green, optou pela criação de uma nova linguagem de
programação que fosse realmente portátil, simples e interpretada. Assim surgiu o Oak(carvalho em inglês), que em
1995 após várias melhorias muda de nome, por problemas de direitos autorais, e passa a ser chamado de Java.

Hoje, Java não é utilizada em eletrodomésticos(pelo menos comercialmente). Ao invés disso, juntamente com o
crescimento da Internet e o desenvolvimento dos applets(mini-aplicativos)ela se tornou um das linguagens de
programação mais utilizadas no mundo.

As especificações da linguagem Java são mantidas uniformes através de um processo comunitário gerido
pela Sun Microsystems, que é também detentora da marca registrada com o nome da linguagem.

Características principais da linguagem Java são:

Orientada a objeto por basear-se nos quatro princípios do paradigma da programação que são: Abstração,
encapsulamento, herança e polimorfismo;
Neutra porque a Máquina Virtual Java (JVM) pode ser implementada em qualquer plataforma;
Distribuída por suportar vários tipos de conectividade em aplicações distribuídas na rede;
Sem ponteiros pois a JVM possui o garbage collector capaz de gerenciar automática e dinâmicamente a memória;
Segura por proteger as "máquinas-alvo" contra quaisquer operações em seus sistema de arquivos por aplicações
obtidas pela rede, já que os applets são desenhados para existirem na máquina cliente somente em tempo de
execução.

A maioria dessas características da linguagem serão desenvolvidas durante o curso.

Lição 2 - Instalação

Instalação

Temos à nossa disposição uma variedade de métodos de instalação do Java, podendo variar dependendo da
distribuição GNU/Linux utilizada.

É importante notar que diferentes métodos de instalação poderão prover versões diferentes do software. Neste
curso, por exemplo, utilizaremos a versão 1.5.0_0x, o pacote disponível no repositório testing/non-free do Debian.
Vale observar que o pacote do Java se encontra na seção non-free, o que indica que ele é considerado não-livre. Isto
ocorre porque ele possui uma licença que não é considerada livre pelos padrões do Debian.

Podemos diferenciar os métodos de instalação basicamente entre aqueles que utilizam pacotes pré-compilados da
própria distribuição e aqueles que utilizam um binário genérico para Linux, provido pela própria Sun Microsystems.

Distribuições derivadas do Debian utilizam pacotes nativos às distribuições (.deb) e para instalá-los basta
simplesmente descompá-los e mover os arquivos para os lugares apropriados. Já o pacote binário da Sun deverá ser
baixado do site do fabricante, prosseguindo com a instalação do mesmo.

Instalação através de pacote binário

O primeiro método que iremos abordar quanto à instalação do Java será o da instalação do pacote binário provido
pela Sun. Para atingir sucesso por esse método de instalação devemos saber como obter esse pacote e instalá-lo,
além de adicionar entradas apropriadas nos arquivos de configuração do sistema.

O pacote binário do Java pode ser obtido a partir do site da Sun, na página de downloads do Java
SE(http://java.sun.com/javase/downloads/index_jdk5.jsp).

Nesta página, podemos observar que existem várias versões a serem baixadas, porém a que (provavelmente) se
adequa à sua necessidade é a JDK 5.0 Update 17, que inclui o Java Runtime Environment(JRE) que consiste no
software da Java Virtual Machine(JVM) e nas bibliotecas de classes Java e também o development kit (JDK) básico
para o Java.

Clicando no referido link, você deverá aceitar a licença e baixar o pacote apropriado para o seu sistema operacional
que, no caso do autor, é Linux self-extractingfile para arquiteturas de 32 bits (para 64 bits, o pacote se chama Linux
x64 self-extracting file). Caso esteja utilizando distribuições derivadas de Red Hat, você pode ainda obter o RPM
caso queira.

Obtido o pacote, agora você deve descompactá-lo, o que implica apenas executar o arquivo em questão, já que ele
tem a extensão (.bin) . Caso ele não esteja executável, pode ser necessário dar permissões de execução ao arquivo
utilizando o comando:

$ chmod a+x jdk(...).bin

Feito isso, execute o arquivo com o comando:

$ ./jdk(...).bin

Recomenda-se que, antes de executar este arquivo, você o mova para o diretório /opt, que segundo a FHS (File
Hierarchy System) é o diretório padrão para instalações de programas independentemente instalados. Outro
benefício é que todos os usuários da máquina poderão utilizar o software, pois o /opt é legível por todos do sistema.
Para fazê-lo, porém, você deverá ser o usuário root, já que apenas este possui privilégios de escrita nesse diretório.

Seguidos estes passos, um diretório será gerado (caso tenha seguido o conselho, dentro do /opt), contendo
binários, documentação e arquivos adicionais da JDK e JRE do Java. Agora, basta adicionar o caminho desses
binários ao caminho de busca de binários do sistema, designado pela variável de ambiente $PATH, setada pelo
arquivo de configuração /etc/profile.

Pronto, instalamos o Java através de seu pacote binário! Não foi nada difícil, não é mesmo?

Distribuições derivadas do Debian

Para instalar o Java em distribuições derivadas do Debian podemos simplesmente utilizar o gerenciador de pacotes
nativo, o apt-get. Vale lembrar que, como o Java não é considerado livre pelos padrões do Debian, você deve
adicionar à seção non-free à sua lista de repositórios. Feito isso, devemos primeiramente buscar o nome do pacote
correspondente ao Java utilizando o comando apt-cache:
hungria@debian3:~$ apt-cache search java5
sun-java5-bin - Sun Java(TM) Runtime Environment (JRE) 5.0
sun-java5-demo - Sun Java(TM) Development Kit (JDK) 5.0 demos and examples
sun-java5-doc - Sun JDK(TM) Documention -- integration installer
sun-java5-fonts - Lucida TrueType fonts (from the Sun JRE)
sun-java5-jdk - Sun Java(TM) Development Kit (JDK) 5.0
sun-java5-jre - Sun Java(TM) Runtime Environment (JRE) 5.0
sun-java5-plugin - The Java(TM) Plug-in, Java SE 5.0
sun-java5-source - Sun Java(TM) Development Kit (JDK) 5.0 source files
hungria@debian3:~$

Como podemos ver, o nome do pacote correspondente ao Java JDK é sun-java5-jdk, acompanhado de uma série
de bibliotecas e plugins. Sabendo disso, basta-nos agora instalar, como usuário root, o pacote utilizando o
comando apt-get:

debian3:~# apt-get install sun-java5-jdk


Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
odbcinst1debian1 sun-java5-bin sun-java5-demo sun-java5-jre unixodbc
Suggested packages:
sun-java5-doc sun-java5-source sun-java5-plugin ia32-sun-java5-plugin sun-java5-fonts ttf-baekmuk ttf-sazanami-
gothic
ttf-sazanami-mincho ttf-arphic-bsmi00lp libmyodbc odbc-postgresql libct1
Recommended packages:
gsfonts-x11
The following NEW packages will be installed
odbcinst1debian1 sun-java5-bin sun-java5-demo sun-java5-jdk sun-java5-jre unixodbc
0 upgraded, 6 newly installed, 0 to remove and 58 not upgraded.
Need to get 45.1MB of archives.
After unpacking 114MB of additional disk space will be used.
Do you want to continue [Y/n]? y
0% [Connecting to ftp.at.debian.org]
debian3:~#

Pronto, agora já temos o JDK Java instalado através do gerenciador de pacotes apt-get. Foi bem fácil também, não
é?

Vale lembrar que os exemplos acima foram testados na distribuição Debian GNU/Linux, porém eles poderiam ser
executados da mesma maneira em qualquer outra distribuição compatível com o Debian, como o Ubuntu Linux,
Kurumin ou Knoppix, dentre outras.

Lição 3 - Introdução à linguagem

Aspectos de programação
Um programa é a implementação de um algoritmo em uma linguagem de programação. O algoritmo precisa ser
bem definido do início ao fim, tendo comandos ordenados e finitos capazes de produzirem um resultado perceptível.
Para programar bem deve-se fazer um algoritmo apropriado e ter um conhecimento léxico, sintático e semântico da
linguagem de programação a ser utilizada.

No campo léxico as linguagens de programação permitem que o programador crie novas palavras, desde que se
respeite as regras nativas da linguagem. Já a sintaxe habilita o programador a exercer sua função de implementar o
algoritmo através do uso de símbolos, termos e palavras que formarão expressões válidas. Finalmente, a semântica é
a representação do resultado observável do algoritmo implementado na máquina pelo programador.

Estrutura, Compilação e Execução

Um programa é um texto (chamado de programa fonte) que possui comandos e declarações necessárias para a
implementação de um algoritmo que é traduzido para um produto equivalente escrito em comandos binários (código
binário) os quais são executados pelo computador. O processo de tradução é chamado de compilação e
posteriormente a ele se produz a ligação do código binário a outros códigos para se obter finalmente o programa
executável.

O programa executável é carregado na memória e colocado sobre o controle de um ambiente de execução, que faz
com que cada comando seja executado pelo processador.

Todo programa deve ter uma estrutura que permita definir seu inicio e fim, de tal forma que o ambiente de
execução possa identificar precisamente o ponto de entrada do programa, isto é, o primeiro comando que será
executado e o término da execução.

A estrutura de um programa em Java

Os programas orientados a objetos são baseados no conceito Classe*. Cada classe contém as declarações e os
comandos que, em conjunto, implementam o algoritmo do programa. Estes comandos são organizados na forma de
Métodos* e devem possuir um método principal que é o ponto de início da execução, a partir dele os demais métodos
são acionados.

Em Java, especificamente, a sua estrutura consiste de um conjunto de unidades de compilação. Cada uma delas
contêm as especificações de classes e interfaces, juntamente com as declarações necessárias para a compilação.
Quando compiladas essas unidades geram arquivos com os códigos binários referentes às classes e interfaces nelas
descritas.

A estrutura básica de uma classe consiste de uma palavra chave class, de um identificador (o nome da classe), e
de um corpo que é delimitado por chaves e contém opcionalmente declarações e comandos próprios da classe.

Programando em Java

Em Java todos os arquivos com os respectivos códigos podem ser escritos em um editor de texto
utilizando UNICODE e terminadas com a extensão “.java”. Cada arquivo representa uma unidade de compilação,
podendo conter uma ou mais especificações de classes e interfaces.

Em Java temos alguns comandos que nos ajudam na compilação e execução dos programas, como o
comando javac e o comando java.

javac: Ele é o compilador da linguagem Java. Este comando ao ser executado em um arquivo que contenha o
código da linguagem, irá gerar um segundo código contendo o código binário que é utilizado para a execução do
programa. Para compilar seu código digite javac NomeDoArquivo.java.

java: O executável Java é a máquina virtual Java (JVM). Ou seja, é o programa responsável pela execução do
código compilado pelo javac. Para fazer uso do comando digite java NomeDoArquivo, para executar um arquivo não
deve-se colocar a sua extensão.

Comentários

Os comentários são textos normalmente explicativos que servem para informar tanto o programador que o
escreveu quanto outros que venham a utilizar ou somente ler aquele código. Em Java os comentários podem ser de
três tipos:

Uma linha - Utiliza duas barras // marcando seu início. Exemplo:

// tudo após as barras é considerado como comentário


Múltiplas linhas - Utiliza barra asterisco no início /* e asterisco barra no fim */. Exemplo:

/* comentário inicial
e final de multiplas linhas */

Documentação - Semelhante ao de múltiplas linhas mas com propósito de documentar o código. Iniciado por /**e
finalizado com */. Exemplo:

/**
comentário de documentação
pode conter diversas
linhas
*/

Lição 4 - Tipos de dados

Variáveis
Na linguagem Java todas as variáveis têm seus tipos de dados definidos. Os tipos de dados definem quais são os
valores que uma variável pode armazenar e quais operações pode executar. Esses tipos básicos são os mesmos para
qualquer ambiente de programação Java, por se tratar de uma linguagem portável.

As variáveis locais são declaradas no corpo de um método*, existindo somente durante a atividade dele. Já as
variáveis de instância e variáveis de classe são declaradas ambas no corpo de uma classe*, mas as de instância
especificam atributos próprios de cada objeto da classe, enquanto que as de classe especificam atributos comuns a
todos objetos da classe.

Existem também as variáveis paramétricas que são declaradas como tratadoras de exceção, construtoras e
parâmetros formais de métodos. São variáveis declaradas na especificação de um método, estas variáveis possuem
algum valor que será usado no método invocado. Seu uso é semelhante ao das variáveis locais podendo ser
modificado o seu valor.

As variáveis paramétricas são criadas quando chamadas ao método que pertencem e existem só durante a
execução do método. Existem duas maneiras de atribuir os valores às variáveis paramétricas, passagem de
argumento por valor ou por referência.

Passagem de argumentos por valor

A passagem por valor é feita com a chamada a um método e os parâmetros reais utilizados na chamada são
avaliados, produzindo valores que são atribuídos aos parâmetros formais correspondentes.

Falando de forma mais simplificada, o método cria uma "cópia" dos valores dos argumentos para que sejam
utilizados somente dentro do método. Portanto, por mais que se alterem esses valores, eles não afetarão as variáveis
externas ao método.

Passagem de argumentos por referência

Ao se invocar uma função ou procedimento, as variáveis paramétricas armazenam uma referência aos parâmetros
reais em vez de uma cópia do valor, como é feito na passagem por valor. Mas, este tipo de passagem em Java não é
implementada, isto acontece porque em Java não existem ponteiros, existem objetos. Assim, toda variável do tipo
"objeto" é na realidade uma referência para aquela instância do objeto.

Mais simplificadamente, os argumentos passados por referência terão seu valor alterado dentro e fora do método,
pois não é feita uma cópia daquela variável.
Obs: Variáveis do tipo de dados primitivo são passadas por valor. Objetos (o conteúdo) não são passados
diretamente para métodos. Em vez disso, são passados aos métodos referências a objetos. As próprias referências
também são passadas por valor. Quando um método recebe uma referência a um objeto, o método pode manipular o
objeto diretamente.

*Os conceitos de Método e Classe serão abordados em próximas lições.

Escopo de variáveis

O escopo de uma variável é a parte do programa no qual pode-se diretamente referenciá-la. Uma variável local tem
seu escopo com alcance somente dentro do bloco onde ela foi declarada. Bloco este que em Java é delimitado por
chaves { }.

As variáveis de instância e de classe têm escopo com alcance em todo o corpo da classe em que foram
declaradas.

Tipos básicos

Existem oito tipos primitivos em Java, todo o resto é objeto. Estes tipos ficaram na linguagem pela sua velocidade
de interação e, por isso, não foram transformados em Objetos. Como não são objetos a sua declaração já cria a
variável em memória não necessitando de construtores.

Inteiros

Tipo Tamanho Valor

byte 8 bits de -128 a 127

short 16 bits de -32.768 a 32.767

int 32 bits de -2.147.483.648 a 2.147.483.647

long 64 bits de -9.223.372.036.854.775.808 a

9.223.372.036.854.775.807

Reais ou ponto flutuante

Tipo Tamanho Valor

float 32 bits -1.40239846E-45 a


3.40282347E+38

(com nove dígitos significativos de


precisão)
double 64 bits -4.9406564584124654E - 324 a

1.79769313486231570E+ 308

(com 18 dígitos significativos de


precisão)

Outros tipos
Tipo Valor Tamanho Descrição

char 16 bits 0 a 65535 Um caractere

boolean 8 bits true ou false Valor booleano(V ou F)

OPERADORES

Executam alguma função sobre os operandos. Existem operadores unários que requerem só um operando
e operadores binários e ternários que requerem dois e três operandos respectivamente. Depois de ser executada
uma determinada função um operador retorna um valor, sendo que esse valor e o tipo de retorno dependem do
operador e de seus operandos.

Operadores binários

Operador Uso Descrição

+ (Adição) X+Y Soma X e Y

- (Subtração) X-Y Subtrai Y de X

* (Multiplicação) X*Y Multiplica X por Y

/ (Divisão) X/Y Divide X por Y

% (Resto) X%Y Resto da divisão de X por Y

Operadores unários

Operador Uso Descrição

++ X++ Utiliza o valor de X antes de fazer o


incremento.
++ ++X Incrementa antes de utilizar o valor de
X.
-- X-- Utiliza o valor de X antes de fazer o
decremento.
-- --X Decrementa antes de utilizar o valor de
X.

* Incrementar é o mesmo que somar 1.


* Decrementar é o mesmo que subtrair 1.

Operadores condicionais e relacionais


Resp: letra c).

Operador Uso Retorna verdadeiro se

> X>Y X é maior que Y.

>= X >= Y X é maior ou igual a Y.

< X<Y X é menor que Y.

<= X <= Y X é menor ou igual a Y.

== X == Y X e Y são iguais.

!= X != Y X e Y são diferentes.

Operadores binários condicionais

Operador Uso Retorna verdadeiro se

&& X && Y X e Y verdadeiros, avalia


condicionalmente Y(se X é falso, não
avalia Y).
|| X || Y X ou Y verdadeiro, avalia
condicionalmente Y(se X é

verdadeiro, não avalia Y).


! X!Y X é falso.

& X&Y A operação "e" bit-a-bit entre X e Y


resulta em valor

diferente de zero, sempre avalia X e Y.


| X|Y A operação "ou" bit-a-bit entre X ou
Y resulta em valor

diferente de zero, sempre avalia X e Y.


^ X^Y A operaçao "ou exclusivo"(XOR) bit-a-
bit entre X e Y resulta em valor
diferente de zero, sempre avalia X e Y.

QUESTÃO 5 - TIPOS DE DADOS

Considerando como verdadeira as informações abaixo:

"x" uma variável do tipo "int";


o método estático "System.out.print(x)" imprime o valor atual de x.

Pergunta:

Qual é a diferença entre os comandos "System.out.print(x++)" e "System.out.print(++x)"?

a) "System.out.print(++x)" imprime o valor atual de x e depois incrementa 1 no seu valor, enquanto que
"System.out.print(x++)" incrementa 1 no valor de x e imprime seu valor já incrementado

b) Ambos não são construções válidas em Java e dará um erro de compilação.

c) "System.out.print(x++)" imprime o valor atual de x e depois incrementa 1 no seu valor, enquanto que
"System.out.print(++x)" incrementa 1 no valor de x e imprime seu valor já incrementado.

d) Não possuem diferença alguma.

Lição 5 - Classes, Objetos, Atributos e Métodos

CLASSES
Conceitos de classe e objeto são centrais para a programação orientada a objeto, por isso é
extremamente necessária a sua compreensão.
Uma classe é o elemento básico da programação orientada a objetos que define as formas e
comportamentos dos objetos pertencentes à ela. Também pode ser entendida como uma estrutura que
associa atributos(dados) e métodos(funções), controlando o acesso a estes. Ou seja, definir uma classe
implica em especificar seus objetos.
Para a criação de uma classe coloca-se um comando que inicia a declaração da classe. Após a
palavra-chave class segue-se o nome da classe, que deve ser um identificador válido para a linguagem.
Os modificadores indicam como classe pode ser utilizada por outras classes e aplicações.
Nota: Usualmente recomenda-se que as classes sejam declaradas utilizando nomes iniciados com
letras Maiúsculas enquanto que nomes variáveis ou instâncias de objetos sejam iniciados com
letras minúsculas. No caso de duas ou mais palavras, as palavras a partir da segunda devem iniciar com
letra maiúscula para substituir o espaço. Veja o exemplo:
"Nome da coisa", caso esse fosse o nome de uma classe deveria ficar assim: "NomeDaCoisa", se fosse
o nome de uma variável deveria ficar assim: "nomeDaCoisa". Porém, lembre-se que isso é apenas uma
recomendação. Mas é bom segui-la para que o código possa ser lido com facilidade por outro programador
e até mesmo por você.
Sintaxe: [modificador] class <NomeClasse>{ <corpo classe> }
Exemplo:
public class ExemploDeClasse{
//atributos
//métodos
}
Modificadores
A primeira palavra nos dá a possibilidade de atribuir permissões de acesso à nossa classe, neste caso
nossa permissão é de tipo pública (public). Uma classepublic é acessível, irrestritamente, por qualquer
outra classe que pertença ou não ao mesmo pacote. Ou seja, quando usamos este modificador, as
classes, métodos e variáveis podem ser acessadas a partir de qualquer outra classe sem qualquer
restrição, bem seja diretamente ou por herança. Esse modificador é o que permite o maior grau de acesso
a um recurso Java.
Um pacote(pakage) em Java é um diretório que contenha um conjunto de classes. Os pacotes, em
certa medida, equivalem às bibliotecas(libraries) de outras linguagens de programação.
Existem também os modificadores privado(private) e protegido(protected) que serão melhor
abordados na Lição 10. Exemplos de uso de pacotes:
/* O ponto seguido do asterisco indica que todas classes dentro do pacote serão importadas */
import java.io.*;
import java.lang.Math;
import java.awt.*;
O corpo da classe normalmente segue a seguinte seqüencia:
Variáveis de classe
Atributos
Construtores
Métodos
Pode também conter um método main, que é utilizado pelo interpretador Java para dar início à
execução de uma aplicação.
Exemplo 1:
class Estudante {
/* declaração dos atributos da classe estudante */
String aluno;
String matrícula;

/* métodos da classe estudante */


void setAluno (String novoAluno){
aluno = novoAluno;
}
void setMatricula (String novaMatricula){
matrícula = novaMatricula;
}
void impEstudante (){
System.out.println( "aluno: "+aluno);
System.out.println( "matrícula: "+matrícula);
}
}
Em nossa classe Estudante temos 3 métodos setAluno, setMatricula e impEstudante, os dois
primeiros usam parâmetros e servem para modificar os atributos aluno e matricula do objeto que os
executa. O último método contém a solicitação de um objeto referenciado por System.out para que este
execute seu método println, o qual fará com que seja impresso na tela o aluno e sua matrícula.
A palavra void indica que os métodos não retornam valores.

OBJETOS
É através deles que praticamente todo o processamento ocorre em aplicações desenvolvidas com
linguagens de programação orientadas a objetos. Toda linguagem de programação orientada a objetos
oferece mecanismos para definir os tipos de objetos para cada aplicação através do conceito de classes.
Objetos são a instância de uma classe. Em outras palavras, são um pedaço de memória reservada para
armazenar os dados e os métodos declarados na classe. Um objeto não é mais que uma abstração que
contém um identificador, um estado e um conjunto de operações que ele consegue realizar. Eles indicam
ao computador como proceder em determinadas situações.
Os identificadores são definidos pelo ambiente ao serem criados, seu estado é determinado pelos
valores referentes a seus atributos e as operações executadas são implementadas por meio de código
(chamado método). No objeto pode-se executar os métodos que foram definidos, além de poder acessar e
alterar dados.

CRIANDO OBJETOS
Para, praticamente, toda classe existe definido algum método (metodo()), que é usado para criar os
objetos da classe. Estes métodos usados para a criação de objetos são chamados de construtores e se
caracterizam por não possuir valor de retorno.
A criação de um objeto da classe "Exemplo" é feita através do comando:
new Exemplo();
Sendo iniciada a execução do construtor da classe.
Exemplo2: Suponhamos que num programa temos duas classes a Classe1 e a Classe2.
class Classe1 {
int soma;
void somar(){
//algum código aqui
}
}
Criaremos o objeto assim:
class Classe2 {
public static void main(String[] args) {
Classe1 objeto = new Classe1(); /* Criando o objeto que referencia a Classe1 */
Resp: correta(verdadeiro)

int obj = objeto.soma; /* referenciando atributos da classe 'Classe1' */


}
}
A referência de um objeto se faz com a indicação do objeto sendo concatenado ao nome do atributo
através de um ponto (objeto.soma). Ou seja, usa-se o operador ponto (.) com uma referência a objeto
para manipular os valores ou invocar os métodos de um objeto específico.
QUESTÃO 6 - CLASSES, OBJETOS, ATRIBUTOS E MÉTODOS
Pergunta:

O programa a seguir satisfaz a necessidade criarmos uma classe nomeada como Aluno, com o atributo nome e adicionar o métodoestudar() com a variável materia?

class Aluno {

String nome;

void estudar() {

/* corpo do método estudar */


String materia;

ATRIBUTOS
Atributos são um modo de modificar uma ou mais declarações(as quais são feitas no corpo da classe, fora dos métodos). Um atributo de uma classe é a própria variável da
classe que se destina a armazenar informações singulares daquela classe. Exemplo:

/* Camiseta.java */
public class Camiseta {

/* Atributos */
String cor;
}

Naturalmente foi definida a classe Camiseta com seu atributo singular cor que poderá armazenar dados sobre aquela camiseta. Outros atributos podem ser adicionados
como, tamanho por exemplo. Ou seja, diversos atributos podem descrever vários aspectos de um objeto. Exemplo:

public class Camiseta {

String cor;
char tamanho;
float preco;
}

Referência de Atributos

Pode-se referir aos atributos de um objeto das seguintes formas:

Pelo nome do atributo, se a referência e o atributo referenciado pertencem à mesma classe. Exemplo:

cor = verde;
A referência acima só poderá ser feita em métodos da própria classe onde o atributo cor foi declarado, no caso na classe Camiseta.

Pela identificação do objeto seguida de um ponto seguido do nome do atributo. Isso é ocorre quando a referência é feita a um atributo de um determinado objeto. Exemplo:

Camiseta objeto = new Camiseta(); /* criando o objeto camiseta */


objeto.cor = "verde";
Pela identificação de uma classe seguida de um ponto seguido do nome do atributo, quando se trata de atributos estáticos.

Atributos estáticos

Os atributos estáticos são declarados com o modificador static, estes atributos se aplicam a funções, dados e não exigem instanciação do objeto. Sua declaração não é
aplicada a uma instância particular do objeto(objetos individuais), mas ao tipo do objeto.

A variável totalDeAlunos, ao ser declarada como um atributo estático (static int totalDeAlunos), permite que seu valor seja compartilhado por todos os objetos da
classe Aluno. Ou seja, todas as instâncias estarão compartilhando a mesma porção de dado. Exemplo de uma referência de atributo a objetos específicos:

class Aluno {

char turma;
static int totalDeAlunos;
int matricula;
void imprimeAluno() {
System.out.println("Matricula: " + matricula);
System.out.println("Turma: " + turma);
}

}
class CriadorObjetos{

public static void main(String[] arg){

Aluno obj1 = new Aluno();


Aluno obj2 = new Aluno();

obj1.totalDeAlunos++;
obj2.totalDeAlunos++;

obj1.matricula = 1;
obj2.matricula = 2;

obj1.turma = 'K';
obj2.turma = 'F';

System.out.println("Dados do aluno 1");


obj1.imprimeAluno();

System.out.println("Dados do aluno 2");


obj2.imprimeAluno();

}
Resp: correta(verdadeiro)

Será impresso na tela:

Dados do aluno 1
Matricula: 1
Turma: K
Dados do aluno 2
Matricula: 2
Turma: F

Repare que totalDeAlunos foi incrementado em cada objeto, porém seu valor é
compartilhado pelos dois objetos. Note que o melhor jeito de referenciar uma variável estática é
utilizando o nome da classe e não o nome do objeto. Por exemplo:

As linhas:

obj1.totalDeAlunos++;
obj2.totalDeAlunos++;

Ficariam melhor se substituídas por:

Aluno.totalDeAlunos++;
Aluno.totalDeAlunos++;
OBS:. O uso abusivo de elementos estáticos é desencorajado, pois elementos estáticos são armazenados uma vez na memória e todos os objetos com acesso permitido
acessarão o mesmo local. Isso pode ser fonte de inconsistência já que diversos objetos estarão lendo e escrevendo no mesmo local concorrentemente. Adicionalmente, na
orientação à objeto deve-se evitar que informações desnecessárias sejam visíveis por objetos externos.

Em nosso programa, foi mais efetivo definir a variável totalDeAlunos como estática, já que o totalDeAlunos é um valor compartilhado por todos os alunos e não específico
de cada aluno como a matrícula.

QUESTÃO 7 - CLASSES, OBJETOS, ATRIBUTOS E MÉTODOS


Para imprimirmos a variável estática quantidade da classe Livro, utilizamos o seguinte comando:

System.out.println("Quantidade de livros: " + Livro.quantidade);

Na seqüência serão relembrados os conceitos de classe e objeto, porque é necessário que os manipulemos perfeitamente para poder entender tudo o que será
apresentado nesta lição.

Objetos são instâncias de classes. Ao serem criados, possuem uma identificação única que é atribuída pelo ambiente e um conjunto de atributos que o caracteriza. Estes
atributos assumem valores que compõem o estado do objeto e cada objeto executa operações definidas através de códigos chamados métodos.

Nas classes encontramos os objetos e suas devidas descrições, isto é , as classes descrevem os atributos de seus objetos, bem como os métodos que eles podem
executar.

MÉTODOS
Nas linguagens orientadas a objetos os métodos são usados para implementar operações que serão usadas pelos objetos criados no programa.

Os métodos definem as ações a serem tomadas em diversos momentos da execução de um programa, dando dinamismo capaz de permitir que os objetos, em muitos
casos, imitem o comportamento de objetos reais. São os métodos que realizam todas as tarefas para as quais o programa foi escrito, por exemplo, fazer cálculos, resumir
informações de um arquivo, criar gráficos, etc.

Chamando Métodos

Podemos chamar um método explicitamente ou implicitamente. A chamada explícita se dá através da execução de um comando ou por meio de uma expressão que
contém o nome do método. Por exemplo ao chamar o método System.out.println (sua função é imprimir na tela) fazemos uma chamada explícita. Chamada implícita
ocorre quando o interpretador Java chama um método por sua própria deliberação. Por exemplo quando o interpretador Java chama o método main para iniciar a
execução do programa.

Declarando Métodos
Os métodos são declarados como parte da especificação de uma classe.

Sintaxe:

<tipo de retorno> <nome do método> {

<corpo do método>
}

Caso seja necessário, podemos ter nos métodos um valor de retorno. Na sintaxe acima se utilizarmos void no lugar de <tipo de retorno>, significa que o método não
retorna nenhum valor. O <nome do método> é um identificador que define o nome pelo qual o método é conhecido, o <corpo do método> contém todas as declarações
e especificações necessárias para que quando seja chamado os comandos sejam executados.

Nos métodos também podemos fazer uso de moderador de acesso como public, protected e private que são empregados para restringir o acesso a um método. Os
modificadores permitem dar algumas propriedades ao método.

Exemplo 1:

class Exemplo1 {

public static int soma(int num, int num2 ) {

int res = 0;
res = num + num2;
return res;

}
}

Para retornar o resultado da soma que é de tipo inteiro é necessário colocar a palavra chave int antes do nome do método.

O método termina quando o comando return é executado.

Exemplo2

class Exemplo2 {

public static String somaPositivos (int num, int num2 ) {

int res = 0;

if ((num < 0) || (num2 < 0))

return "numeros negativos";

System.out.println(num + num2);
return "fim de programa";
}
}

No método somaPositivos temos um if que testa se as variáveis num e num2 são maiores que zero. Se não forem, ele dá umreturn e sai do método, caso contrário,
imprime a soma de num e num2 e posteriormente dá um return e sai do método. O comando if será visto mais detalhadamente na seguinte lição.

Referindo-se a métodos

Se a referência e o método são da mesma classe, então nos referimos a ele pelo seu nome. Quando se quer invocar a execução do método por um objeto específico, faz-
se a referência pela identificação de um objeto seguido do nome do método.

Para métodos estáticos, faz-se a identificação de uma classe seguida do nome do método que se quer dentro desta classe.
Exemplo 3:

class Exemplo3{

int x;
int soma;
static int quantidadeSomas = 0;

void somaX(){
quantidadeSomas++;
soma += x;

imprime(); /*referencia ao método */

void imprime(){
System.out.println("Soma dessa instância: " + soma);

System.out.println("fim de programa");

static void conta() {


System.out.println("Quantidade de somas feitas: " + quantidadeSomas);
}
}

Neste exemplo, a referência ao método imprime() é feita só pelo nome porque ele pertence à mesma classe do método somaX()que a chamou.

class Exemplo3TestDrive {

public static void main(String[] arg){

Exemplo3 obj = new Exemplo3();


obj.x = 21;
obj.somaX(); /* executar método por um objeto */
Exemplo3.conta(); /* executar o método estático da classe Exemplo3 */

Exemplo3 obj2 = new Exemplo3();


obj2.x = 23;
obj2.somaX();
Exemplo3.conta();

}
}

No caso do Exemplo3TestDriveo método somaX() teve que ser chamado utilizando o objeto instânciado, já o método conta()foi chamado utilizando o nome da classe
(pois é um método estático).

Método println
Este método é executado pelo objeto referenciado System.out e imprime o argumento que recebe. Para imprimir uma seqüencia de caracteres é necessário que a
seqüencia seja colocada entre aspas duplas, exemplo:

System.out.println("Imprimindo seqüencia de caracteres");

Aparecerá na tela do computador:

Imprimindo seqüencia de caracteres

Os caracteres são impressos exatamente como são escritos. O println após imprimir da um salto de linha, enquanto o print imprime os argumentos mas não produz salto
de linha.

Exemplo 4:

class Exemplo4 {

public static void main ( String [] argumento) {

System.out.print("Imprimindo primeira linha ");


System.out.println("Imprimindo segunda linha ");
System.out.println("Imprimindo terceira linha ");

}
}

Aparecerá na tela do computador:

Imprimindo primeira linha Imprimindo segunda linha

Imprimindo terceira linha

Na primeira impressão está sendo usado o método print, por isso não se produz salto de linha e a segunda impressão aparece na mesma linha da primeira.

Para imprimir uma variável ela pode ser passada como argumento sem fazer uso das aspas duplas. Por exemplo: se a váriavel vartem como valor 1000, usamos a
seguinte seqüência de comandos para imprimir este valor.

System.out.println(var);

Aparecerá na tela o valor 1000.

Observando o exemplo 5 :

void impEstudante (){

System.out.println("Aluno: " + aluno);


System.out.println("Matricula: "+ matricula);
}

Podemos observar que neste método para cada println são passados dois argumentos, uma
seqüencia de caracteres e uma variável, o símbolo de adição "+"serve para indicar que outro
argumento será impresso.

Construtores

Construtores são métodos especiais chamados pelo sistema no momento da criação de um


objeto. Eles determinam que ações devem ser executadas, fazendo referência a uma área de
memória e preparando para a utilização do novo objeto. Em Java, o construtor é definido como
um método cujo nome deve ser o mesmo nome da classe a qual pertence e sem indicação do
tipo de retorno(nem mesmo void). O construtor é unicamente invocado no momento da criação
do objeto através do operador new, sendo que o retorno do operador new é uma referência para
o objeto recém-criado. O construtor pode receber argumentos, como qualquer método mas tendo
a especificidade de inicializar seus dados de forma organizada.

Para a classe String, pré-definida na linguagemm, o construtor tem a forma String("Constante


do tipo String"); com o argumento entre aspas que é especificado pelo programador. Ele seria
chamado automaticamente no momento da criação, declaração de uma String, sem necessidade
de uso do nome do construtor como método, apenas dos argumentos:

String a;
a = new String("Texto"); //alocacao e inicializacao atraves do construtor
a.mostra(); //mostra so pode ser chamada depois do construtor

Neste exemplo podemos notar a criação de vários objetos String diferentes:

// UseStrings.java
public class UseStrings {

public static void main(String args[]) {

String s0 = null;
String s1 = new String();
String s2 = new String("Alo pessoal!");
System.out.println("Testando contrutores Strings:");
System.out.println("s0 = " + s0);
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);

Nota-se que uma classe pode ter vários tipos de construtores, todos com o mesmo nome
obrigatório. Diferem-se somente pela sobrecarga do construtor ou pela lista de argumentos. Toda
classe tem pelo menos um construtor sempre definido. O construtor pode ou não receber
argumentos, como qualquer método. Usando o mecanismo de sobrecarga, mais de um
construtor pode ser definido para uma classe. Veja por exemplo os construtores definidos para a
classe Point de Java.

Se nenhum construtor for explicitamente definido pelo programador da classe, um construtor


padrão(default), que não recebe argumentos(não contém parâmetros) e de mesmo nome que a
classe é incluído para a classe pelo compilador Java. Esse construtor padrão é o único criado
para atender aos requisitos do compilador. No entanto, se o programador da classe criar pelo
menos um método construtor, o construtor padrão não será criado automaticamente. Se o
programador desejar mantê-lo, deverá criar um construtor sem argumentos explicitamente. Veja
o modelo:

Tipo Valor default


byte, short, int, long 0
float, double 0
Boolean False
Referência para objetos Null

Ele será criado apenas no momento da compilação e apenas nos casos que não exista
construtor declarado. Podemos fazer:
public class RadioSemConstrutor {
boolean estado;
public boolean desligar() {
return estado=false;
}
public boolean ligar() {
return estado=true;
}
}
Para provar, basta compilarmos este código e entrar com o comando no diretório do
arquivo RadioSemConstrutor.java:
$ javap RadioSemConstrutor
Este comando retornaria na tela:
Compiled from RadioSemConstrutor.java

public class RadioSemConstrutor extends java.lang.Object {


boolean estado;
public RadioSemConstrutor();
public boolean desligar();
public boolean ligar();
}
Pode-se perceber a presença de um método público que não contém parâmetro,
chamado RadioSemConstrutor. Sendo assim, acabamos de encontrar o
construtor default usando o disassembler bytecodes.
No momento em que um construtor for invocado serão executadas as seguintes ações
para a criação de um objeto:
1. O espaço para o objeto é alocado e seu conteúdo é inicializado com zeros(bitwise).
Este passo garante que nenhum campo do objeto terá um valor arbitrário, que possa
dificultar a detecção de erros de não inicialização.
2. O construtor da classe base é invocado. Se a classe não tem uma superclasse
definida explicitamente, a classe Object é a classe base.
3. Os membros da classe são inicializados para o objeto que segue a ordem em que
foram declarados na classe.
4. O restante do corpo do construtor é executado. É uma necessidade seguir essa
seqüência de forma a garantir que no momento em que o corpo de um construtor esteja
sendo executado, o objeto já tenha à sua disposição funcionalidades mínimas
necessárias(aquelas definidas por seus ancestrais).
Resp: correta(letra b)

QUESTÃO 8 - CLASSES, OBJETOS, ATRIBUTOS E MÉTODOS


Pergunta:

O que acontecerá ao tentarmos compilar e executar o programa a seguir?

public class Pergunta {

int x = 0;
int y = 0;

int somarXY() {
return x + y;
}

static int somar(int x, int y) {


return x + y;
}

public static void main ( String [] args ) {

Pergunta obj = new Pergunta();

System.out.println("Valor da primeira soma: " + obj.somarXY());


obj.x = 10;
obj.y = 20;
System.out.println("Valor da segunda soma: " + obj.somarXY());
System.out.println("Valor da terceira soma: " + somar(10,2));

}
a) O programa imprime na tela:
b) O programa imprime na tela: c) O programa imprime na tela: d) Haverá um erro de compilação
Valor da primeira soma: 0 porque o método somar(10,2) foi
Valor da segunda soma: 30 Valor da primeira soma: 0 Valor da primeira soma: 0 chamado de forma incorreta
Valor da terceira soma: 30 Valor da segunda soma: 30 Valor da segunda soma: 0
Valor da terceira soma: 12 Valor da terceira soma: 12
.

Lição 6 - Estruturas de controle

Estruturas de repetição
Na execução de programas as ações primitivas nem sempre são executadas na ordem em que são escritas, devido à lógica de programação que foi aplicada na
construção do algoritmo. Isto acontece porque às vezes necessitamos que determinada parte do programa deva repetir-se algumas vezes ou que uma parte do programa
deva ser executada de acordo com uma condição

Os ciclos de repetição em sua estrutura possuem um conjunto de comandos e uma condição.


Comando While

Na execução do comando while primeiro testa-se a <condição>. Se a condição resultar em falso o comando termina passando o controle para posição após a chave de
fechamento do comando. Se resultar em verdadeiro uma nova iteração tem início e o controle passa para o primeiro comando da cláusula de repetição.

Sintaxe: while (<condição>){ <comandos>; }

Exemplo:

while (cont != 0) {

cont = cont -1;


}

Na primeira linha é testado se cont é diferente de zero, se for, então são executados os comandos que estão dentro do bloco while, mas se a condição não é satisfeita o
ciclo de repetição termina e o controle passa para a primeira linha depois do bloco.

Comando do-while

Este comando é parecido ao while sua diferença é que a condição é testada após a execução do bloco de instruções. Portanto, este bloco é executado no mínimo uma
vez.

Sintaxe: do { <comandos>; } while (<condição>);

Exemplo:

do {

cont = cont - 1;
} while (cont != 0);

Neste exemplo, o controle esta no bloco do comando do, onde primeiro são executadas todas as instruções, neste caso subtrai-se um da variável cont, posteriormente é
testada a condição que, caso seja satisfeita (verdadeira), o controle volta para o comando do e se repete o procedimento. Mas se não for satisfeita (falso), termina o ciclo
de repetição e o controle passa para a primeira linha que está depois do comando while.

Comando for

Como os comandos anteriores, o comando for serve para repetir um conjunto de instruções, diferindo dos demais pela existência de procedimentos executados no inicío
de sua estrutura.

Na execução do comando for o <comando inicial> é executado (Caso ele não exista nenhuma ação é realizada nesse passo). Em seguida a <condição de parada> é
avaliada e se o resultado for falso o comando termina. Se o resultado for verdadeiro uma nova interação tem início e o controle passa para o primeiro comando da cláusula
de repetição.A <cláusula_fim_iteração> é processada depois do corpo, mas antes de cada reteste subsequente de <condição de parada>.

Sintaxe: for ( <comando inicial> ; <condição de parada> ; <cláusula_fim_iteração>){ }

Possui um cabeçalho com três elementos separados por ponto e vírgula, no primeiro elemento declaramos o tipo de variável que vamos utilizar e atribuimos um valor inicial
para ela. No segundo elemento é declarada a condição de parada(normalmente uma expressão booleana) e no terceiro temos a cláusula de fim de iteração.

Exemplo:

for ( int var = 0; var <= 10; var++){

System.out.println(var);

Neste exemplo, primeiro foi declarada uma variável var de tipo inteiro com um valor inicial de zero, depois é testada a condição que se for satisfeita será impresso o valor
de var, senão terminará o ciclo de repetição e o controle passará para o primeiro comando que estiver depois do bloco for .

OBS :. O exemplo usando for acima equivale ao código abaixo usando o while:

int var = 0;
while (var <= 10) {

System.out.println (var);
var ++;
Resp: correta(verdadeiro)

QUESTÃO 9 - ESTRUTURAS DE CONTROLE


Pergunta:

O que será impresso pelo programa abaixo?

import java.io.*;
class Exemplo {

public static void main(String [] arg) {

int res = 0;
for(int n = 1; n <= 6; n++) {

res = (n * 2);
System.out.println("res = "+ res);

}
Resp: correta(letra b)
}

}
Imprime:

res = 2
res = 4
res = 6
res = 8
res = 10
res = 12.

ESTRUTURAS CONDICIONAIS
A estrutura condicional faz com que o fluxo de execução de um programa seja desviado, pois às vezes precisamos executar um bloco de ações ou uma seqüência de
ações primitivas apenas se uma determinada condição for satisfeita.

Comando if

Sua sintaxe é if (<condição>) { <comandos> }, ela nos diz que se a condição for verdadeira as ações que seguem serão executadas. Veja o exemplo:

if (x > 0) {

++x;

}
Lê-se: se x for maior que zero então incremente um em x.

Comando else

No caso em que a condição for falsa, por exemplo se x não é maior que zero então outras ações serão executadas, neste caso utilizamos o comando else. Tenha em
mente que sempre antes de um else deve existir um if.

Sintaxe: if (<condição>) { <comandos> } else { <comandos> }

Exemplo:

if (x > 0)
++x;

else

--x;

Tomando x menor que zero, o programa passa o controle para o if e testa a primeira condição, como ela é falsa o controle passa para o else e executa o que esta no bloco
dele, neste caso será decrementado o valor da variável x. Veja que não foi necessário colocar chaves no if e no else, isto acontece porque para cada um deles temos um
único comando, portanto podem ser suprimidas as chaves.

Exemplo 1:

class Exemplo1 {

public static void main (String [] arg){

int num = 10;


float x;
if (num != 0) {

x = 100/num;

if( x > 10)

System.out.println(x + " > 10");

else

System.out.println(x + " <= 10");

}
System.out.println("fim de programa");

}
}

Neste programa testamos no primeiro if se num é diferente de zero, se for, então 100 é dividido por num. Posteriormente se faz um novo teste na condição do segundo if ,
se o valor obtido em x for maior que 10, então imprime x > 10 senão o controle vai para o else e é impresso x < 10, terminando assim o bloco do primeiro if . Por último é
impresso a palavra fim de programa .

No caso em que num é igual a zero, a condição testada no primeiro if será falsa e, portanto, controle não entra no bloco do if, sendo passado o controle à primeira linha de
comando depois do if , consequentemente será impresso fim de programa.

Comando switch

O comando switch também desvia, por meio de um teste na condição, o controle do programa para outro trecho, trabalhando de forma semelhante ao if, sua diferença é
que pode tratar mais de dois blocos de execução.
Sintaxe:

switch (<expressão>){

case <valor1>:<comandos 1>

break;

case <valor2>:<comandos 2>

break;

.
.
.

default: <comandos default>


}

No comando switch a <expressão> que é passada será testada nas diferentes cláusulas case. A <expressão> testa valores do tipo int,short,byte ou char e compara-os
com o rótulo (no caso <valor1> e <valor2>) em cada cláusula case. A comparação é feita do primeiro comando case até o último, ordenadamente, se ela for igual ao valor
de alguma das cláusulas o controle passa para ela e serão executados todos seus comandos. Em seguida o controle passa para o primeiro comando após este rótulo.

Se nenhum rótulo for igual a <expressão>, então verifica-se a existência de um rótulo default. Caso exista, os comandos de defaultserão executados. Se não existir um
rótulo default o fluxo do programa segue sem desvio feito pelo comando switch. O break é utilizado para sair do switch transferindo o controle para o comando seguinte.
Se o break é utilizado em comandos internos à outros comandos apenas o mais interno é interrompido.

Exemplo 2:

import java.io.*;

class Exemplo2 {

public static void main(String[] arg){

int x = 21;
switch (x) {

case 1: {

System.out.println("x vale 1");


break;

case 21: {

System.out.println("x vale 21");


break;

default: {

System.out.println("x não é valido, nesse caso");


break;

case 30: {

System.out.println("x vale 30");


break;

}
}
}

Se o valor de x for 1 aparecerá na tela:

x vale 1

Se o valor de x for 21 aparecerá na tela:

x vale 21

Se o valor de x não for 1 ou 21 ou 30, então aparecerá na tela:

x não é valido, nesse caso

Se o valor de x for 30 aparecerá na tela:

x vale 30
Como o valor de x não existe em nenhuma cláusula o controle é desviado para o comando default, prosseguindo-se a partir deste ponto com a execução dos outros
comandos.

Exemplo 3:

import java.io.*;

class Exemplo3 {

public static void main(String[] arg){

int x = 10;
switch (x) {

case 1: System.out.println("rótulo 1");

break;

case 2: x = 2+x;

switch (x){

case 4: System.out.println("dentro do segundo switch");

break;

case 7: System.out.println ("no segundo switch");

break;

System.out.println("fora do segundo switch");

break;

}
}
}

Se o valor de x é 1 então é impresso na tela rótulo 1 e sai do switch terminando o programa.

Se o valor de x é 2 o controle vai para a classe 2, e é incrementado 2 à variável x que fica valendo 4 agora. O controle é passado para o segundo switch em case 4 é
impresso na tela a frase dentro do segundo switch , posteriormente encontra-se um break que faz o controle sair do segundo switch, depois é impresso a frase fora do
segundo switch e logo encontramos um break com o qual saímos do primeiro switch e termina o programa.

QUESTÃO 10 - ESTRUTURAS DE CONTROLE


Pergunta:

O que acontecerá se tentarmos compilar e executar o seguinte programa:

class Questao {

public static void main (String [] arg){

int x = 10;
if ( x == 10 )
System.out.println("x = 10");
if ( x > 9 )
System.out.println("x > 9");
if ( x < 10 )
System.out.println("x < 10");
System.out.println("O valor de x é: " + x);
switch (x) {
case 10: System.out.println("x = 10");
}

}
}

a) O programa não será compilado b)Será impresso na tela: c)Será impresso na tela: d)Será impresso na tela:
devido a um erro no código:
if ( x < 10 ) x = 10 x = 10 x = 10
System.out.println("x < 10"); x>9 x = 10 x>9
System.out.println("O valor de x x = 10 O valor de x é: 10
é: " + x); x = 10
Resp: correta(letra d)

Lição 7 - E/S Teclado e Arquivo

Obtendo Valores do Teclado

Para poder obter os valores do usuário a partir do teclado é necessário criar uma classe auxiliar que chamaremos de Teclado. Ela será criada em um arquivo com nome
de Teclado. java e deve ser colocada no mesmo pacote ou diretório da outra classe onde ela será usada.

import java.io.*;

public class Teclado {

private BufferedReader fonte = new BufferedReader(new InputStreamReader(System.in));


public int lerInteiro() {

while (true) {

try {

return Integer.parseInt(fonte.readLine());

} catch (IOException e) {}

catch (NumberFormatException e) {

System.out.println("Numero invalido!");
System.out.print("Por favor, digite um numero inteiro: ");

public double lerReal() {

while (true) {

try {

return Double.parseDouble(fonte.readLine());

} catch (IOException e) {}

catch (NumberFormatException e) {

System.out.println("Numero invalido!");
System.out.print("Por favor, digite um numero real: ");

public String lerLinha() {

String linha = null;


try {
linha = fonte.readLine();

} catch (IOException e) {}
return linha;

Nesta classe Teclado, temos 3 métodos public int lerInteiro(),public doublelerReal() e public String lerLinha(), que nos permitem ler inteiros, reais e strings.

NOTA: Não se preocupe por não conseguir entender a classe Teclado completamente, pois ela possui assuntos mais avançadas que serão vistos mais para frente. Por
enquanto você só precisa saber como usá-la para obter dados do teclado.

E/S TECLADO

Vias Lógicas de comunicação

O canal comunicante entre um repositório de dados e um programa é a representação da chamada via lógica de comunicação. Essas vias diferenciam operações físicas (dependem
de repositórios e fontes) das operações lógicas (gravação e leitura). As vias podem ser de entrada, de saída ou de ambas(entrada e saída).

Vias de entrada - Estabelecem um canal comunicação entre uma fonte onde os dados são lidos e o programa leitor.

Vias de saída - Estabelecem um canal comunicação entre uma repositório onde os dados são lidos e o programa gravador.

Vias de entrada e saída - Estabelecem um canal comunicação entre uma fonte ou repositório com um programa permitindo leitura e/ou gravação.

A implementação das vias se dá em classes que contenham métodos apropriados de leitura, gravação e conexão entre fontes e repositórios de dados. O comando new é o
responsável por criar um objeto capaz de implementar uma via de comunicação. O objeto recém-criado então deve ser associado à fonte ou repositório de dados, passando-se
sua identificação como argumento que use seus métodos de gravação e leitura.

Exemplo: new FileReader("dados.txt");

O arquivo identificado pordados.txt está associado ao objeto da classe FileReadernew no exemplo anterior. que implementa a via de entrada criada pelo comando

Vias padrões para gravação e leitura

A classe System e seus atributos in e out estão diponíveis automaticamente pelo ambiente Java associados ao teclado e ao vídeo. O método read (leitura) pode ser usado através
do objeto in. Enquanto que o objeto out permite o uso dos métodos print (imprime algo mantendo o cursor na mesma linha) e println(imprime algo transferindo o cursor para
próxima linha).

System.in.read();

System.out.print();

System.out.println();

Leitura de dado

Na execução do método read se a tecla x for digitada teremos a impressão do valor 120, que é o código inteiro correspondente à letra x. Ou seja, o
método readInputStream retorna valores inteiros(tipo int) ao ler um byte da fonte de dados.Exemplo: pertencente à classe

import java.io.*;

class Leitura{

public static void main (String[] args) throws IOException {

int lido = System.in.read();

System.out.print(lido);

As declarações import java.io.* e throws IOException serão melhor abordadas na lição de tratamento de erros. Por hora basta saber que a primeira declaração serve para
importar as classes de entrada e saída e a segunda serve para posteriormente tratar possíveis erros também de entrada e saída.

Leitura da linha
O método readLine da classe BufferedReader permite leitura de todo o conteúdo de uma linha. Esse método usa leituras provenientes da classe InputStreamReader. Sendo
assim, a fonte de dados informada deve ser implementada a partir de um objeto da classe InputStreamReader para a classe BufferedReader.

Exemplo1:

import java.io.*;

class LerLinha {

public static void main (String[] args) throws IOException {

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


System.out.print("Digite algo: ");
String linha = teclado.readLine();
System.out.print("Voce digitou: " + linha);

Exemplo2:

import java.util.*;

class LerLinha2 {

public static void main(String[] args) {

Scanner teclado = new Scanner(System.in);


System.out.print("Digite algo: ");
String linha = teclado.nextLine();
System.out.print("Voce digitou: "+linha);

A declaração import java.util.* é necessária para localizar a classe Scanner e usar o método nextLine() tento o teclado como fonte de dados.

Leitura de valores múltiplos

Com objetos da classe StringTokenizer pode-se ler valores múltiplos do teclado que foram digitados numa mesma linha, sendo que esses dados serão tratados como sequência de
caracteres chamados tokens. O espaço é o delimitador padrão dos tokens, mas o delimitador pode ser alterado. Exemplo:

A sequência de caracteres " leitura de 4 tokens " contém 4 tokens.

O método nextToken retorna o próximo token como uma sequência de caracteres. Já os métodos hasMoreTokens ehasMoreElements determinam a existência de mais tokens
na sequência de caracteres caso o valor true tenha sido retornado.

import java.io.*;

import java.util.*;

class SeqCaracteres {

public static void main(String[] args) throws IOException {

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


StringTokenizer linha = null;
System.out.print("Digite algo: ");
linha = new StringTokenizer(teclado.readLine());
while (linha.hasMoreElements()) {

String token = linha.nextToken();


System.out.println("valor: "+token);

}
QUESTÃO 11 - E/S TECLADO E ARQUIVO
Pergunta:

Para fazer referência da classe Teclado, deve-se criar um objeto para a classe Teclado e depois chamar um método da classe Teclado, por exemplo se quisermos que o
usuário digite um numero inteiro:

Teclado tec = new Teclado(); //cria objeto


num = tec.lerInteiro(); // chama método lerInteiro

Resp:verdadeiro

E/S Arquivo
São um conjunto de dados armazenados em um formato específico. Eles podem ser textos(dados gravados em formas de caracteres) ou binários(dados gravados
usando-se tipos primitivos da linguagem) que têm diferenças apenas lógicas. O acesso aos arquivos pode ser feito sequencialmente ou randomicamente. No primeiro o
cursor sempre move-se pra frente com gravação e leituras sequenciais. Já no segundo o cursor movimenta-se para frente e para trás, o que permite regravações e
releitura de dados de maneira não sequencial.

Leitura e Gravação de arquivos sequenciais

Primeiro identifica-se um arquivo passando o caminho para determinar a localização dele. Em seguida o ambiente de execução deve localizá-lo e prepará-lo para leitura ou
gravação. Finalmente, fecha-se o arquivo.

O método read da classe FileReader após ler o caractere retorna o inteiro que corresponde ao código do caractere lido e identifica o fim do arquivo pelo valor -1.

import java.io.*;

class ArqSequencial {

public static void main(String[] args) throws IOException {

int i;

FileReader arq = new FileReader("/home/usr/arqSeq");

while ((i = arq.read()) != -1)

System.out.print(i+".");

arq.close();

}
}

O método readLine da classe BufferedReader lê um arquivo linha a linha e identifica o fim do arquivo pelo valor null.

import java.io.*;

class LinhaArqSequencial {

public static void main(String[] args) throws IOException {

FileReader fonte = new FileReader("/home/usr/linhaArqSeq");

BufferedReader arq = new BufferedReader(fonte);

String linha;
while ((linha = arq.readLine()) != null)

System.out.println(linha);

arq.close();

}
}

O método write da classe FileWriter grava um caractere ou uma sequência de caracteres. Se o argumento for do tipo int o método grava o código correspondente ao
valor. Se for char ou String serão gravados como caractere e sequência de caracteres respectivamente.

import java.io.*;

class Soma {

public static void main(String[] args) throws IOException {

FileWriter arq = new FileWriter("/home/usr/soma");

String s1 = "Um mais um é igual a ";


String s2 = " e dois mais dois é igual a ";
char d = '4';
arq.write(s1);
arq.write(50);
arq.write(s2);
arq.write(d);
arq.close();

}
}

Será criado um arquivo texto chamdo soma no diretório /home/usr cujo conteúdo será:

Um mais um é igual a 2 e dois mais dois é igual a 4

Obs: É necessária ter permissão de gravação no diretório /home/usr.

Os objetos da classe DataInputStream e DataOutputStream permitem respectivamente leitura(pelo método read<tipo>) e gravação(pelo método de write<tipo>) direta
de tipos primitivos. Por exemplo dados gravados com método writeInt devem ser lidos pelo métodos readInt.

Um arquivo acessado através de um objeto da classe DataInputStream tem seu final indicado pela ocorrência da exceçãoEOFException. Isso para prevenir que o
método read<tipo> de tente continuar lendo depois o fim do arquivo.

Leitura e gravação de arquivos randômicos

A classe RandomAcessFile poussui métodos write<tipo> e read<tipo> para cada tipo primitivo Java. Tais métodos devem ser usados em conjunto, ou sejam, dados
gravados por um write<tipo> devem ser lidos por read<tipo>. Essa classe deve conter, além da identificação do arquivo, o modo de utilização separados por vírgula.
Sintaxe:

new RandomAcessFile("/home/usr/arquivo","rw" );

r - abre o arquivo apenas para leitura.


rw - abre o arquivo para leitura e gravação.
rws e rwd - abrem o arquivo para leitura e gravação, garantindo o sincronismo entre as operações lógicas e físicas de entrada e saída.

Outro métodos úteis são:

seek(x) - posiciona o cursor no início do byte de ordem x.


length - retorna o tamanho do arquivo em bytes.
getFilePointer - retorna a posição corrente do cursor.
setLength(x) - define um novo tamanho para o arquivo.

QUESTÃO 12 - E/S TECLADO E ARQUIVO


Resp: letra c) (0x37);
Pergunta:

O que será gravado no arquivo questao caso o comando arq.write(55) da classe Questao seja substituído pelo comandoarq.write(0x37) ?

import java.io.*;

class Questao {

public static void main(String[] args) throws IOException {

FileWriter arq = new FileWriter("/home/usr/questao");

String s1 = "Resposta certa "; char c1 = 'd';


arq.write(s1);
arq.write(c1);
arq.write(97);
arq.write(" Lição ");
arq.write(55);
arq.close();

Resposta certa da Lição %


Resposta certa da Lição sete.
Resposta certa da Lição 0x37
Resposta certa da Lição 7

Lição 8 - Vetores e Cadeia de caracteres

VETORES
Também conhecidos como arrays os vetores são seqüências de elementos de um determinado tipo, em um número pré-determinado de dimensões (vetores de uma, duas
ou mais dimensões, por exemplo).

Arrays são ditos unidimensionais quando possuem apenas uma dimensão, podendo assim referenciar seus elementos através de um único índice numérico, geralmente
entre colchetes(vetor[1]). Arrays multidimensionais são aqueles em que devemos referenciar cada elemento através de dois ou mais índices numéricos(vetor[1][2]).
Podemos implementar matrizes facilmente através dessa possibilidade de manipulação de arrays.

Arrays são referenciados como variáveis, cabendo ao programador determinar qual o tipo deste vetor. Além de definirmos o nomedo array, devemos também definir
portanto o tipo deste array e quantas dimensões possuirá. Como dito anteriormente, as dimensões são especificadas por pares de colchetes, quando declaramos o array.

O comando new seguido do nome da classe e da quantidade de elementos da sua dimensão pode criar explicitamente objetos que representam vetores. Exemplo de um
vetor de inteiros de 100 elementos:

array_identificador = new int[100];

Vejamos agora exemplos de declarações de arrays unidimensionais e multidimensionais:

Uma dimensão:

A B C D

Multidimensionais (matriz):

A B C

D E F

G H I

J K L
Para declarar arrays usaremos a seguinte sintaxe, que já foi apresentada:
Unidimensional: tipo nome_array[];

Multidimensionais:tipo nome_array[][]; sendo que nos primeiros colchetes temos o número


de linhas da matriz e no segundo o número de colunas.
Exemplo:

int numeros[10];

char Lista[5][4];

Os elementos dos vetores são referenciados por seu índice que é sua própria posição no vetor. Todos os objetos de Array têm uma variável de atributo length que contém
o comprimento ou os limites da matriz. Os limites de uma matriz, como essa numeros[10]; vai de numeros[0] a numeros[9], já que todas as matrizes começam com o
elemento zero(0).

array_identificador = new int [length];

O número de elementos é armazenado como parte do objeto array e o comprimento é usado pelo software JVM para garantir que o acesso à matriz corresponda aos
elementos reais da matriz. Caso tente acessar elementos não existentes da matriz, comonumeros[14], do exemplo anterior cujo comprimento é [10], você receberá um
erro.

ARRAY UNIDIMENSIONAL

Podemos utilizar arrays para evitar o uso de múltiplas variáveis redundantes em um programa, facilitando a manipulação de grande quantidade de dados. Normalmente,
manipula-se uma estrutura utilizando for para percorrer o array, conforme o exemplo abaixo:

class EscreveVetor {

public static void main(String[ ] args) {

int[ ] lnum = new int[100];


Teclado tec = new Teclado();
System.out.println("Digite ate 100 numeros (0 para parar): ");
int qtd = 0;

for (; qtd < 100; qtd++) {

int valor = tec.lerInteiro();


if (valor == 0) break;

lnum[qtd] = valor;

for (int i = qtd - 1; i > -1 ; i--)

System.out.print(lnum[i]+" ");

}
}

Exemplo 2:

import java.io.*;
public class EscrevePolinomio {

public static void main (String[] args) {


Teclado tec = new Teclado();
double[] n = new double[5], n1 = new double[5];
int j = 0, tam;
/* Laço de leitura dos coeficientes */
for (int i = 0; i <= 3; i++) {

System.out.print("Digite o "+(i+1)+"º coeficiente: ");


n[i] = tec.lerReal();
if (n[i] == 0){

j = j + 1;

}
System.out.println("");
System.out.print("");
/* Laço condicional para a impressao da expressao */
for (int i=0; i <= 3; i++){

if( n[i] != 0 && n[i] > 0 && i == 0){

System.out.print(n[i]+"X^3");

}
if( n[i] != 0 && n[i] < 0 && i == 0){

System.out.print(n[i]+"X^3");

}
if( n[i] != 0 && n[i] > 0 && i == 1){

System.out.print(" + "+n[i]+"X^2");

}
if( n[i] != 0 && n[i] < 0 && i == 1){

System.out.print(" "+n[i]+"X^2");

}
if( n[i] != 0 && n[i] > 0 && i == 2){

System.out.print(" + "+n[i]+"X");

}
if( n[i] != 0 && n[i] < 0 && i == 2){

System.out.print(" "+n[i]+"X");

}
if( n[i] != 0 && n[i] > 0 && i == 3){

System.out.print(" + "+n[i]);

}
if( n[i] != 0 && n[i] < 0 && i == 3){

System.out.print(" "+n[i]);

}
System.out.println("");
System.out.println("");
System.out.println("Fim de programa");

}
}

O ciclo de repetição for é usado para percorrer o array e guardar em cada posição um valor real. Lembre-se de que a primeira posição do vetor inicia com o número zero,
por isso nossa variável de posição está declarada com o valor inicial de zero. Para imprimir os elementos de um vetor se o segundo for foi utilizado.

ARRAY MULTIDIMENSIONAL

A criação de matrizes é muito parecida ao vetor unidimensional, podemos criar arrays de muitas dimensões:

int array[][] => array de duas dimensões.


int array[][][] => array de tres dimensões.
int array[][][][] => array de quatro dimensões.

Para criar um array de n dimensões, devemos colocar n colchetes abertos e fechados.

Percorrer Matriz

Para percorrer uma Matriz faremos uso de dois for, um percorre as linhas enquanto o outro percorre as colunas, exemplo:

class EscreveMatriz {

public static void main(String[] args) {

Teclado tec = new Teclado();


int L, C;
do {

System.out.print("Digite a qtd de linhas: ");


L = tec.lerInteiro();

} while (L <= 0);


do {

System.out.print("Digite a qtd de colunas: ");


C = tec.lerInteiro();

} while (C <= 0);


int[] mat[] = new int[L][C];
Resp: letra c) (int charnum[];)

System.out.print("Digite,coluna a coluna, os elementos ");


System.out.println("de uma matriz "+L+"x"+C);
for (int j = 0; j < C; j++)

for (int i = 0; i < L; i++) {

System.out.print("digite o elem ("+(i+1)+","+(j+1)+"): ");


mat[i][j] = tec.lerInteiro();

for (int i = 0; i < mat.length; i++) {

for (int j = 0; j < mat[i].length; j++)

System.out.print(mat[i][j]+" ");

System.out.println();

}
}

No exemplo acima, é percorrido o array para receber os dados do teclado e serem guardados em cada posição da matriz, posteriormente é impresso o valor que foi
inserido. Ou seja, foi usado a instrução for de maneira avançada para se itera em uma matriz por meio de loops compactos e fáceis de ler.

QUESTÃO 13 - VETORES E CADEIA DE CARACTERES


Pergunta:

Selecione a declaração NÃO válida.

a) int[] listanum;

b) String nome[][];

c) int char listanum[];

d) int listanum[];

CADEIA DE CARACTERES
Representam uma seqüência de caracteres e são implementadas como objetos da classe String. Uma cadeia de caractere é o único objeto que possui uma
representação no código fonte do programa, ou seja, uma cadeia de caractere é o único objeto que tem um literal na linguagem Java.

System.out.println(21);
System.out.println("meu programa");

O literal 21 é de tipo int e a cadeia de caracteres "meu programa" é de tipo String. O int é um tipo primitivo e a cadeia de caracteres é de tipo String (que é uma
classe em Java).

Quando temos String str; estamos definindo uma variável com nome str de tipo String, mas o seu conteúdo não é definido. Agora definiremos o conteúdo da
variável, String str = "programa"; o conteúdo corresponde a um endereço de memória onde o compilador montou um objeto contendo a cadeia de caracteres
"programa".
Para construir um novo objeto usamos new. A expressão str = new String("oi"); corresponde a um construtor. Um construtor instrui o operador new em como deve
ser construído o novo objeto.

Algumas operações

Concatenação:

Esta operação é feita em operandos de tipo String por meio do símbolo (mais) +, se o operando que está sendo concatenado não for de tipo String, ele será
transformado antes da concatenação na cadeia de caracteres que o representa.
Exemplo 1:

class Exemplo1{

public static void main (String[] arg){

String aluno;
String nome = "Felipe";
int matricula = 3219;
String curso = new String(" Computacao ");
aluno = nome + curso + matricula;
System.out.println(aluno);

}
}

Aparecerá na tela do computador: Felipe Computacao 3219

Subcadeia:

Fazendo uso do método substring() podemos obter uma subcadeia de uma cadeia de caracteres. O método recebe um valor inteiro e ele retorna a subcadeia formada
pelos caracteres a partir da posição dada pelo valor inteiro.

Exemplo:

String x;
String srt = "testando metodo subcadeia";
x = srt.substring(9);

Então na variável x produz-se a cadeia de caracteres: "metodo subcadeia".

Podemos converter o conteúdo de uma cadeia de caracteres em um tipo primitivo através dos métodos parse<tipo> das classes<tipo>. Existe um método para cada
tipo primitivo Java. Exemplos:

Byte.parseByte
Short.parseShort
Integer.parseInt
Boolean.parseBoolean

Alguns outros métodos que permitem fazer certas operações:

<retorno> <objeto>.<método>([<parâmet ro>]);

int str.length() : Retorna o tamanho da cadeia de caracteres referenciado pelo nome str;

int str.compareTo(String str2) : Sendo executado por um objeto instanciado str, compara lexicograficamente a cadeia str com str2, retorna um inteiro negativo
se str precede (em ordem da tabela UNICODE, que é alfabética) str2 e positivo se str2 precede str, caso sejam iguais retorna o valor zero;

char str.charAt(int ind) : Usa o inteiro ind e retorna o caracter que está na posição do índice ind do objeto referenciado pelo nomestr;

String str.toLowerCase() : Todos os caracteres são convertidos a minúscula. O str deve ser um objeto instanciado do tipo String;

String str.toUpperCase() : Todos os caracteres são convertidos a maiúscula. O str deve ser um objeto instanciado do tipo String.
Lição 9 - Tratamento de erros

Tratamento de erros
Na execução de um programa podem ocorrer erros que podem tanto causar a interrupção do programa quanto produzir resultados incorretos ou comportamento
inesperado. Existem erros de lógica e erros de execução.

ERROS LÓGICOS

Estes erros se apresentam no desenvolvimento de um algoritmo não apropriado para solucionar o problema que se propõe. Estes erros não necessariamente causam
interrupção na execução do programa.

ERROS DE EXECUÇÃO

São erros mais específicos em relação aos lógicos, que decorrem de uma operação inválida e causam interrupção na execução do programa. Este tipo de erro
depende da plataforma e da linguagem que está sendo utilizada, por exemplo se realizamos uma divisão por zero vai causar um erro de execução.

Ao se causar um erro a execução é interrompida e é enviado um sinal ao programa indicando que a operação não pode ser realizada.

As linguagens de programação possuem formas para identificar e tratar os erros de execução. Em Java eles são detectados pela JVM e um objeto de uma classe que
caracteriza o erro é criada. Notifica-se o programa da operação inválida e caso seja possível tratá-lo, pode-se acessar o objeto que caracteriza o erro.

Os erros são caracterizados por objetos de classes específicas, estas classes são classe Error e classe Exception. Funcionam como superclasses, mas ambas são
subclasses da classe Throwable.

Classe Error: a classe Error, com suas subclasses, é utilizada para indicar erros graves que não se espera que sejam tratados pelo programas.

Classe Exception: Esta classe indica erros que podem e devem ser tratados pelos programas, como por exemplo erros aritméticos.

COMANDO TRY

Os tratamentos de erros são feitos pelo comando try, em suas sintaxes temos um corpo e a ele associadas várias cláusulas catch.

Quando o controle está no bloco do comando try o ambiente passa a monitorar todos os comandos declarados em seu bloco (corpo). Se nenhum erro aparecer o
comando try termina, mas se ocorrer algum erro a cláusula catch é acionada imediatamente, ao fim da execução da cláusula catch o comando try termina
normalmente e o fluxo passa para o próximo comando após ele.

try {

res = 100/num;

System.out.println("100/"+num+" = "+res);

}catch (ArithmeticExecption e) {

System.out.println("não se pode calcular");


}

Aqui é tratado o erro em que num tenha o valor zero, neste caso é um erro aritmético que é tratado na cláusula catch.

try {

int num = Interger.parseInt(teclado.readLine());


}catch (NumberFormatException e) {

System.out.println("digitou um valor não inteiro");


}

Neste é tratado a entrada de um número não inteiro.

CLÁUSULA FINALLY

Esta cláusula é sempre executada e se encontra no corpo do comando try, caso não se produza nenhum erro os comandos são executados e o controle passa para a
cláusula finally. Caso ocorra algum erro o controle passa para a cláusula catch onde é tratado o erro e depois é enviado para a cláusula finally.

try {

int num = Interger.parseInt(teclado.readLine());


}catch (NumberFormatException e) {

System.out.println("digitou um valor não inteiro");


}finally {

System.out.println("saindo do bloco try");


}

Caso ocorra um erro no programa será impresso na tela:

digitou um valor não inteiro saindo do bloco try

Propagando erros

A cláusula throws indica que o método pode gerar erros das classes relacionadas, que devem ser subclasses de Throwable, que precisam ser tratados pelos métodos
chamadores. Ou seja, erros das classes relacionadas ou de alguma subclasse têm seu tratamento postergado. O comando throw é usado para criar erros que não
ocorreriam em sitações normais.

Exemplo de tratamento de erros:

import java.io.*;
class TratandoErrodeFormato {

public static void main(String[] arg) throws IOException {

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

System.out.print("Digite um numero: ");

int num = 0;

while (true) {

try {

num = Integer.parseInt(teclado.readLine());

break;

}catch (NumberFormatException e) {

System.out.print("Por favor, digite um valor inteiro: ");

System.out.println("O numero digitado foi: "+num);


System.out.println("fim de programa");

}
}

QUESTÃO 15 - TRATAMENTO DE ERROS


Pergunta:

O parâmetro formal da cláusula catch indica o tipo de erro que a cláusula pode tratar. Por exemplo, o parâmetro formal IOExceptionpode tratar qualquer erro dessa
classe ou de alguma de suas subclasses.

Resposta: verdadeiro

Lição 10 - Encapsulamento, Herança e Polimorfismo

ENCAPSULAMENTO
É a capacidade de poder restringir ou controlar na classe o acesso e a visibilidade a seus elementos. É normalmente feito através de um qualificador. Os qualificadores,
que são palavras reservadas, permitem a visibilidade a um determinado atributo ou método definido. Em Java existem os qualificadores private, public, protected e
"sem" qualificador (quando não especificamos os qualificadores, é automaticamente adotado o qualificador em nível de pacote - package), estas palavras reservadas
permitem restringir o acesso às declarações de uma classe e à própria classe.

O conceito de encapsulamento está intimamente relacionado ao conceito de abstração na programação. A abstração é o processo de "esconder" dos detalhes de
implementação para que o programador possa se preocupar somente com a "essência". O encapsulamento, através da sua restrição de visibilidade dos elementos
internos à classe, permite a abstração.

Benefícios de se restringir uma classe:

1.Código de programa legível;


2.Minimização de erros;
3.Facilidade de modificação;
4.Facilidade de extensão;
5.Programa mais seguro (pois pode-se controlar os usos);

Qualificadores:

public: permite que os atributos e métodos sejam acessíveis a todos os métodos de todas as classes, isto é, sejam acessados por códigos externos;
private: os atributos e métodos só podem ser acessados por métodos que pertençam à mesma classe deles. Este é o mais rígido nível de acesso;
protected: o acesso dos métodos ou atributos pode ser feito na própria classe ou em subclasses, isto quer dizer, em classes filhas;
"sem" qualificador ou em nível de pacotes: os atributos e métodos são acessíveis pela própria classe ou por classes que pertencem ao mesmo pacote (package) em
que foram criados.

Exemplo:

public class nome_classe{ //declaração inicial da classe de tipo public

private int valor;

private float valor2; //atributos da classe

public void exemplo(){ }

} //fim da classe

HERANÇA
Definida como a habilidade de uma classe poder herdar características de uma outra. A classe que recebe a herança é dita como derivada da classe ou subclasse. A
subclasse inclui o comportamento da superclasse e dá a possibilidade de adicionar-lhe funcionalidades.

Esta propriedade de uma classe poder herdar características de outra e assim sucessivamente é chamado de hierarquia de classes. Podemos imaginar a hierarquia
como uma árvore genealógica, onde temos a superclasse pai e a partir dele as subclasses filhos.

Este mecanismo permite que a mesma porção de código projetada para a classe pai possa ser utilizada para a classe filho sem alteração do código. Utilizamos a
palavra chave extends para declarar uma herança de classe, sendo que o qualificador é opcional, no caso abaixo é [static]. A sintaxe é:

<qualificador> [static] class <nome_subclasse> extends <nome_superclasse> { <código_classe_filho> }

Exemplo:
//declaração da superclasse
class Colegio{

String nomeColegio; //atributos da classe colegio

String endereco; //atributos da classe colegio

public String getEndereco(){ //metodo

return endereco;

}
} // fim da superclasse
// declaração subclasse

class ColegioParticular extends Colegio{

float custoMensal;//atributo adicional à superclasse

public String toString(){//metodo adicional à superclasse

return "Sou o colegio particular " + nomeColegio;

// pode-se usar o "nomeColegio" declarado na superclasse pois não usamos "protected"

}
} //fim da subclasse

OBS:. A herança é uma relação do tipo "é um" . Ou seja, se a classe Mamiferos herda (extends) a classe Animal, estamos dizendo que os Mamíferos são também
Animais. Essa é a idéia que o Java implementa como herança, portanto, um programa criado para rodar com a classe Animal rodará também com a classe Mamifero.

Uma visualização da herança:

image

POLIMORFISMO
É o princípio pelo qual um mesmo comando tem diferentes comportamentos dependendo do contexto em que estão sendo usados. A forma mais comum de
implementar polimorfismo é usando, em heranças, métodos com o mesmo nome nas subclasses de uma determinada classe, mas com conteúdo diferente. As
subclasses invocam métodos que têm a mesma identificação (nome), mas as classes derivadas possuem distintos comportamentos.

Como exemplo, suponha que a classe Filho1 e Filho2 herdam da superclasse Pai e as três classes possuem um método com o nome metodoQualquer. Suponha
também que obj seja declarado como um objeto da classe Pai. Ou seja, ele pode referenciar Pai,Filho1 e Filho2 graças à herança. Então, o
comando obj.metodoQualquer()obj estiver instanciando naquela porção do código. pode ter diferentes comportamentos dependendo do que classe o

Em uma máquina virtual Java, uma chamada a um método (a execução de um método) ocorre da maneira abaixo:

Ao fazer a chamada de um método apartir de um objeto de uma classe A, gera-se a busca do método nesta classe, caso ele não seja encontrado é realizada a busca
na superclasse (que chamaremos de classe B ) da classe A, caso não seja encontrado na classe B é feita a busca na sua superclasse, isto é feito ate encontrar o
método ou até chegar na raiz da hierarquia de classes (que, por padrão, é a classe Object). Encontrado o método ele é executado e qualquer outra chamada dentro
dele gera a mesma busca do método desde essa classe.

Então, mesmo que um determinado método esteja já definido em uma superclasse, você pode a reescrever em uma subclasse, pois a máquina virtual sempre
procurará o método na própria classe primeiro. Essa propriedade facilita o polimorfismo de um método.

OBS:. Temos o polimorfismo em operadores também. Por exemplo, a operação "+" (adição) retorna a soma caso os operandos sejam números, enquanto que fará uma
concatenação caso os operadores sejam uma String.

QUESTÃO 16 - ENCAPSULAMENTO, HERANÇA E POLIMORFISMO


Pergunta

Com base na classe a seguir marque a resposta correta:

public class Item {

private double preco;

private int id_Produto;

private String marca;

Os atributos da classe Item são de classe ou de objeto. E por eles são privados?

a) Atributos de classe. São privados para garantir o polimorfismo.

b) Atributos de objeto. São privados para garantir o encapsulamento.

c) Atributos de classe. São privados para garantir o encapsulamento.

d) Atributos de objeto. São privados para garantir a herança.

Resposta letra b)

Lição 11 - Interfaces gráficas


GERÊNCIA DE JANELAS
Em Java existem vários pacotes com classes específicas para criação e gerência de interfaces gráficas(GUI), sendo que os mais conhecidos são java.awt(abstract
window toolkit) e java.swing que é uma extensão do pacote awt.

JANELAS DE DIÁLOGO

No pacote swing existe a classe JOptionPane que possui métodos estáticos responsáveis pelo surgimento de janelas que param a execução do programa até que a
janela seja destruída ou alguma ação(pressionar o botão) seja realizada. Isso cria uma interação com usuário sendo feita por botões, mensagens informativas ou
ícones.

Fornecimento de informação

import javax.swing.*;
import javax.swing.JOptionPane;

class JanelaAviso {

public static void main(String[] arg) {

JOptionPane.showMessageDialog(null,"Pressione OK para
iniciar","JanelaAviso",JOptionPane.WARNING_MESSAGE);

JOptionPane.showMessageDialog(null,"Pressione OK para terminar");

System.out.println("fim do programa");

}
}

O método showMessageDialog mostra uma mensagem e espera confirmação do usuário. Sintaxe:

void showMessageDialog(Component comp, Object mensagem);

void showMessageDialog(Component comp, Object mensagem, String titulo, int tipodeMensagem);

As variáveis mesagem e titulo são menemônicas(correspondem à própria mensagem e título da janela) e aparecerão tem todos os métodos abaixo. Já
o tipodeMensagem pode ser:

ERROR_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE e INFORMATION_MESSAGE

Solicitando informações:

import javax.swing.*;

import javax.swing.JOptionPane;

class JanelaSolicita {

public static void main(String[] arg) {

int[] aceitoNum = new int[5];

String aceitoStr = "";

int op = 0, num = 0, ind = 0;

do {

num = (int)Math.floor(100*Math.random());

op = JOptionPane.showConfirmDialog(null,"Aceita o valor
"+num+"?","JanelaSolicita",JOptionPane.YES_NO_OPTION);

if (op == JOptionPane.YES_OPTION)

aceitoNum[ind++] = num;

} while (ind < 5);

for (int i = 0; i < ind; i++)

aceitoStr = aceitoStr+" "+aceitoNum[i];

JOptionPane.showMessageDialog(null, aceitoStr);
System.out.println("fim do programa");

}
}

int showConfirmDialog(Component comp, Object mensagem, String titulo, int tipodeBotoes);

int showConfirmDialog(Component comp, Object mensagem);

O primeiro método mostra uma janela de opções com botões de confimação para o usuário. Já o segundo mostra uma janela com três botões(YES, NO e CANCEL).

O tipodeBotao pode ser:

DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION

O DEFAULT_OPTION mostra apenas o botão OK, os demais são menemônicos.

Obtendo valores:

import javax.swing.*;

import javax.swing.JOptionPane;

class JanelaObter {

public static void main(String[] arg) {

int[] aceitoNum = new int[5];

String aceitoStr = "";

for (int i = 0; i < 5; i++) {

String texto = JOptionPane.showInputDialog(null,"Digite o "+(i+1)+". numero");

aceitoNum[i] = Integer.parseInt(texto);

aceitoStr = aceitoStr+" "+texto;

JOptionPane.showMessageDialog(null, aceitoStr,"Numeros
Digitados",JOptionPane.INFORMATION_MESSAGE);

System.out.println("fim do programa");

}
}

String showInputDialog(Component comp, Object mensagem);

String showInputDialog(Component comp, Object mensagem, Object valorInserir);

O primeiro método mostra uma janela para recebimento de dados. O segundo mostra o campo texto que é preenchido com o conteúdo de valorInserir. Depois de
digitar os dados no campo texto e o botão OK for pressionado, o método retornará o conteúdo digitado em forma de cadeia de caracteres. O retorno será vazio caso o
botão CANCEL seja pressionado ou seja destruída a janela.
Gerência de layout

Saber gerenciar janelas significa controlar a posição dos componetes, sendo capaz de redesenhá-los ou reposicioná-los quando necessário for, segundo políticas
previamente determinadas. Usa-se normalmente um dos gerentes disponíveis no ambiente Java como uma das classes que implementam a interface LayoutManager.

Gerência de eventos

Esses gerentes é que monitoram eventos do ambiente e notificam as aplicações sob seu controle da ocorrência de tais eventos. Os gerentes definem modelos,
classes, fontes e registradores de eventos para tratá-los. Para cada classe de eventos há uma interface que especifica métodos que devem ser executados de acordo
com o tipo de evento.

Obs:. Os conceitos de gerência de layout e eventos, assim como o estudo de interfaces gráficas em Java, que foram aqui abordados são meramente introdutórios.
Seria necessário um novo curso para desenvolvimento pleno de tais assuntos, o que foge do escopo deste curso.

QUESTÃO 17 - INTERFACES GRÁFICAS


Pergunta:

Ao se executar uma das classes JanelaAviso, JanelaSolicita e JanelaObter é possível perceber a ocorrência de erro de formato não tratado em determinada
situação. Em qual das classes esse erro ocorre?

a) classe JanelaSolicita

b) classe JanelaObter

c) classe JanelaAviso

Resposta: letra b)

Lição 12 - Threads

Threads
Até o momento foram vistos programas cuja execução tem apenas um único fluxo. Em Java, pode-se lançar múltiplas atividades dentro de um único processo. A isso
chamamos Threads ou MultiThreading ou, ainda, sub-processos no sistema operacional. Um programa em execução é dito como um processo. Um processo em
adamento aloca diversos recursos como memória, hd e outros sendo que o sistema operacional é o responsável por esse controle. Já quem controla as várias threads
dentro do programa é o próprio interpretador Java. Por isso o uso de threads proporciona um maior desempenho em ambientes mulltiprocessados, simplifica a
modelagem de algumas aplicações e tem um custo menor de gerenciamento em relação aos processos.

Para se utilizar multithreads é necessário instanciar um objeto de uma classe que estende a classe básica Thread já que não há herança múltipla em Java. Há duas
maneiras de se implementar threads em Java, usando-se herança ou implementando umainterface. Uma thread têm os seguintes estados: Criada, em Execução,
Suspensa ou Morta.

Principais Métodos

run() - Executa as atividades da thread. Se este método finaliza, a thread também o faz;
start() - Determina a execução da thread. Chama o método run() antes de finalizar;
sleep(int x) - Coloca a thread para dormir por x milisegundos;
join() - Espera o término da thread para qual foi mandada a mensagem para poder ser liberada;
interrupt() - Interrompe a execução da thread;
interrupted() - Testa se a thread está ou não está interrompida.

USANDO HERANÇA

Esta é a maneira que oferece maior simplicidade na codificação. Para usar herança deve-se estender a classe Thread que pertence ao pacote java.lang.Thread.
Nossa classe deve sobrescrever o método public void run(). O método run() é sempre chamado quando uma linha de execução é criada para o objeto.
Sintaxe:

public Thread (String nomedaThread);


public Thread();

Exemplo1:
class Tarefa1 extends Thread {

public void run() {

for(int i=0; i<1000; i++)

System.out.println(“Herança”);

}
}

Exemplo2:

// ThreadTest1.java
public class ThreadTest1 extends Object {

public static void main(String args[]){

new ThreadTest1();

ThreadTest1(){

Contador cc = new Contador();

for (int i=0; i<5; i++){

System.out.println("(ThreadTest1) Contador = " +cc.proximoValor());

ClasseNormal CN = new ClasseNormal();

CN.func(cc);

for (int i=0; i<5; i++) {

System.out.println("(ThreadTest1) Contador = " + cc.proximoValor());

}
class Contador {

int ct = 0;

public Contador() { }

int proximoValor() {
ct++;
try{

Thread.sleep(500);

}catch (Exception e) { }
return ct;

}
class ClasseNormal {

void func(Contador cx) {

for (int i=0; i<5; i++) {

System.out.println("(ClasseNormal) Contador = " + cx.proximoValor());

USANDO A INTERFACE RUNNABLE

Toda classe que implementa a interface Runnable nos obriga a especificar o método public void run(), que será executado no momento em que a linha de execução
do programa é inicializada. Se a classe Filha implementar a interface Runnable, ela se capacita a ser tratada como se fosse um objeto do tipo da interface Runnable.
Sintaxe:

public class Filha extends Pai implements Runnable;

Despois de criada a classe Thread passando para o seu construtor a referência do objeto que implementará a interface Runnable,temos:

Thread umaTarefa = new Thread(Runnable objetodaThread);

ou

Thread umaTarefa = new Thread(Runnable objetodaThread, String nomedaThread);

Exemplo3:

class Tarefa2 implements Runnable {

public void run() {

for(int i=0; i<1000; i++)

System.out.println(“Runnable”);

}
}

Exemplo4:
// ThreadTest2.java
import java.lang.Thread;
public class ThreadTest2 extends Object {

public static void main(String args[]) {

new ThreadTest2();

ThreadTest2() {

Contador cc = new Contador();

for (int i=0; i<5; i++) {

System.out.println("(ThreadTest2) Contador = " + cc.proximoValor());

ThreadClass1 objetoThread = new ThreadClass1(cc);

Thread thread = new Thread(objetoThread);

thread.start();

for (int i=0; i<5; i++) {

System.out.println("(ThreadTest2) Contador = " + cc.proximoValor());

}
class Contador {

int ct = 0;

public Contador() {}

int proximoValor() {

ct++;
try {

Thread.sleep(500);

}catch (Exception e) { }
return ct;
}

}
class ThreadClass1 implements Runnable {

Contador cx = null;

ThreadClass1(Contador cz) {

cx = cz;

}
public void run(){

func();

}
void func() {

for (int i=0; i<5; i++) {

System.out.println("(ThreadClass1) Contador = " + cx.proximoValor());

}
Para usar as classes(Tarefa1 e Tarefa2) dos exemplos 1 e 3 deve-se acrescentar:

Thread comHeranca = new Tarefa1();


Thread comRunnable = new Thread(new Tarefa2());
comHeranca.start();
comRunnable.start();

Prioridades de Threads

Em Java, a prioridade é determinada como um valor inteiro de 1 à 10. A prioridade 10 é a maior, a 1 é a menor e a 5 é a prioridade padrão. A thread herda a prioridade
da thread que a criou. Métodos:

void setPriority(int prioridade);


int getPriority();

Sincronismo entre Threads

Mesmo sendo o mais eficiente dentre os processos, as threads têm a desvantagem de tornar o interpretador pouco eficiente. Isso porque o uso de memória
compartilhada entre as threads obriga o programador a sincronizar as ações de suas threads. Para tal, existe no ambiente Java locks ou monitores. O lock funciona
como uma permissão para determinar que apenas uma thread possa utilizar um recurso por vez. Os locks são obtidos através do comando synchronized. Sintaxe(Os
comandos abaixo são equivalentes):

synchronized public void sincronizando() {

algumaAcao();
}

ou

public void sincronizando() {


synchronized(this) {

algumaAcao();
}

Alguns métodos da classe Object implementam o conceito de locks notificando as threads para indicar se elas devem ser suspensas ou se devem voltar a ficar em
execução. Para tal, será utilizado o lock do objeto chamado pela thread para realizar as notificações necessárias. Por isso, antes de chamar um dos três
métodos(wait(), notify() ou notifyAll()), o lock deve ser obtido utilizando-se o comando synchronized.

wait() - Suspende a thread chamadora do método até que tempo especificado como argumento tenha passado ou até que outra thread a acorde;
notify() - Acorda, se existir alguma thread que esteja esperando um evendo neste objeto;
notifyAll() - Acorda todas as threads que estejam esperando neste objeto.

QUESTÃO 18 - THREADS
Questão

Uma vez que Java não possui herança múltipla, pode-se utilizar um objeto, cuja classe já é derivada, como no caso da classe Thread dada a seguir:

public class Filho extends Pai extends Thread {

//comandos

()Falso

()Verdadeiro

Resposta:Falso

Avaliação de aprendizagem
1- Com base na sintaxe abaixo, identifique a afirmativa correta sobre o loop for
code_block no loop while.

while (boolean_expression) {
code_block;
}

Escolher uma resposta.


a. Representa linhas de código executadas se boolean_expression retornar null.
b. Representa linhas de código executadas se boolean_expression for true.
c. Representa linhas de código executadas se boolean_expression for false.

2 - Identifique um recurso do pacote java.awt.


Escolher uma resposta.
a. Contém classes que tratam E/S de arquivo.

b. Contém classes para realizar operações relacionadas à rede.


c. Contém classes que fornecem comportamento específico do applet.
d. Contém classes usadas para construir e gerenciar a GUI da aplicação.

3 Qual dos seguintes é um recurso da construção switch?


a. A construção switch testa o valor do tipo int, short, byte ou char.

b. A construção switch testa se os valores são maiores ou menores que um valor único.

c. A construção switch testa em variáveis ternárias.

4 - Identifique a vantagem de criar uma thread estendendo a classe Thread.


Escolher uma resposta.

a. Fornece um código mais simples.

b. Oferece suporte a herança múltipla.

c. Fornecer um melhor design orientado a objetos.

5 - Qual das seguintes palavras-chave é opcional na sintaxe de uma declaração de subclasse abaixo?
[class_modifier] class class_identifier extends superclass_identifier
Escolher uma resposta.
a. superclass_identifier
b. class_identifer
c. class_modifier

6 - Identifique a declaração de classe correta da linguagem de programação Java:


Escolher uma resposta.
a. class Test

b. private class Test

c. public Class Test

d. public Test

7 - Identifique a linha de código que cria corretamente a variável String 'myName'.


Escolher uma resposta.
a. String myName = String("Fred Smith")
b. String myName = "Fred Smith";

c. String myName = new String("Fred Smith");

d. String = new String("Fred Smith");

8 - Com base na sintaxe abaixo, identifique a afirmativa correta sobre o loop for.
for(initialize [,initialize]; boolean_expression; update [,update]) {
code_block;
}

Escolha pelo menos uma resposta.


a. A seção update[,update] é processada depois do corpo, mas antes de cada reteste subsequente de
boolean_expression.
b. A parte initialize[,initialize] da construção for é processada uma vez, antes da outra parte do loop.
c. boolean_expression é processado após cada interação do loop.
d. code_block representa linhas de código executadas se boolean_expression for false.

9 - Identifique a sintaxe de instanciação de uma matriz unidimensional.


Escolher uma resposta.
a. array_identifier[index] = value;

b. array_identifier = new type [length]

c. type [ ] array_identifier;

10 - Identifique a sintaxe para instanciar um objeto.


Escolher uma resposta.
a. Classname identifier = new (Classname);

b. new Classname();

c. Classname identifier;

»»»»»»Fim do curso_End Of Course«««««««

Gabarito: 1-b; 2-d; 3-a; 4-a; 5-c; 6-a; 7-b; 8-a e b; 9-b; 10-a.