|
|
Universidade Federal do Paraná Centro de Computação Eletrônica Divisão de Microinformática |

INDICE REMISSIVO
1 INTRODUÇÃO
1.1 A HISTÓRIA DA LINGUAGEM JAVA
Em 1991, um pequeno grupo de funcionários da Sun mudou-se para a San Hill Road, uma empresa filial. O grupo estava iniciando um projeto chamado Projeto Green, que consistia na criação de tecnologias modernas de software para empresas eletrônicas de consumo. Logo o grupo percebeu que não poderia ficar preso à plataformas, pois os clientes não estavam interessados no tipo de processador que estavam utilizando, e fazer uma versão do projeto para cada tipo de sistema seria suicídio. Desenvolveram então o sistema operacional GreenOS, com a linguagem de programação Oak.
Em 1993 surgiu uma oportunidade para o grupo Green, agora incorporado como FirstPerson: a Time-Warner, uma empresa que estava solicitando propostas de sistemas operacionais de decodificadores e tecnologias de video-on-demand1. Isso foi na mesma época em que o NCSA lançou o MOSAIC 1.0, o primeiro navegador gráfico para Web. A FirstPerson apostou nos testes de TV da Time-Warner, mas esta empresa preferiu optar pela tecnologia oferecida pela Silicon Graphics.
Depois de mais um fracasso de acordo com a 3DO a FirstPerson dissolveu-se, e metade do pessoal foi trabalhar para a Sun Interactive com servidores digitais de vídeo. Entretanto, a equipe restante continuou os trabalhos
do projeto na Sun. Como a equipe de desenvolvimento tomava muito café enquanto estava trabalhando, foram ingeridas centenas de chícaras de café2 até que o projeto estivesse pronto. Finalmente em maio de 1995 a Sun anunciou um ambiente denominado Java, homenagem às chícaras de café, que obteve sucesso graças a incorporação deste ambiente a browsers populares como o Netscape Navigator e padrões tridimensionais como o VRML (Virtual Reality Modeling Language - Linguagem de Modelagem para Realidade Virtual).
A Sun considera o sucesso do Java na Internet como sendo o primeiro passo para utilizá-lo em decodificadores da televisão interativa, em dispositivos portáteis e outros produtos eletrônicos de consumo - exatamente como o Java tinha começado em 1991. Sua natureza portátil e o projeto robusto permitem o desenvolvimento para múltiplas plataformas, em ambientes tão exigentes como os da eletrônica de consumo.
1.2 VANTAGENS DA LINGUAGEM JAVA
Além dessas vantagens, a linguagem Java está agora incorporando suporte a operações em Banco de Dados. O JDBC, que é uma biblioteca de classes para acesso a banco de dados, permite uma conexão remota a servidores SQL que possuam driver OBDC ou compatível. Transações no estilo de Compras, Vendas, Cadastramentos, Alteração de dados pessoais controlada por senha via Internet, são exemplos do que o JDBC permite que seja realizado.
1.3 CONFIGURAÇÃO
O Java é uma linguagem de programação feita para ser utilizada em um ambiente de 32 bits gráfico (portanto, não funciona no Windows 3.1/3.11 ou no MS-DOS puro). Possui um compilador muito pesado e torna-se lento demais quando aplicado a máquinas de processamento mais simples, como um 486 (que possui um processamento escalar de uma via ou uma instrução sendo executada por ciclo de clock). O ideal é utilizar, tanto para a compilação quanto para a execução de programas Java, uma máquina Pentium ou superior (possui um processamento superescalar de duas vias - paralelismo, duas instruções sendo executadas no mesmo ciclo de clock). Isto não significa que um programa feito em Java não funcione numa máquina 486.
Um outro contratempo do Java é com relação a suas versões existentes. Cada browser que tem suporte a Java possui, no meio de seus arquivos, um (ou alguns) arquivos especiais, que são arquivos compactados que contém as classes padrões do Java. O problema é que normalmente, pela lei de Murphi, a versão de Java que você utiliza para programar não é a mesma versão de Java que o browser usuário irá utilizar para visualizar o seu programa. Ou seja, você pode compilar os seus programas em uma versão do Java, usando classes e propriedades implementadas na versão que você está utilizando, ao mesmo tempo em que os arquivos de classes do browser do usuário podem ter sido implementados em uma versão anterior, tornando improvável a interpretação dos códigos do seu programa pelo browser do usuário.
1.3.1 Variável de ambiente CLASSPATH
Durante a configuração do Java, deve ser criada uma variável de ambiente com o nome de CLASSPATH, que deve conter o seguinte conteúdo:
<drive>:\<diretório do Java>\lib\classes.zip;
Isto faz com que o Java, quando estiver precisando de alguma classe que esteja dentro de algum pacote, procure a classe desejada dentro deste arquivo (classes.zip). Se a encontrar, o Java descompacta a classe e a utiliza. Este método de compactar os pacotes com as suas classes correspondentes faz com que se economize espaço em disco.
Exercício: Crie a variável CLASSPATH e arranje corretamente o seu conteúdo.
2 ORIENTAÇÃO A OBJETOS
Este capítulo destina-se àqueles que desejam ter alguma noção sobre o que é a orientação a objetos, descrevendo algumas de suas principais características.
2.1 CLASSE
Classe é a descrição de um grupo de objetos que possuam atributos e comportamentos iguais, e que relacione-se da mesma forma com os outros objetos.
Para uma rápida compreensão, a estrutura de uma classe pode ser comparada com uma estrutura em C (struct), sendo que, entre outras características, uma classe pode possuir métodos (funções) e implementações de segurança (níveis de acesso). Os atributos das classes seriam as variáveis da estrutura.
2.2 OBJETO
Um objeto não é nada mais do que uma instância de uma classe, ou seja, um exemplar da classe instanciada representado na memória.
Fazendo uma comparação com a estrutura da linguagem C (struct), podemos dizer que a classe seria a estrutura e o objeto seria a variável da estrutura.
2.3 IDENTIDADE
Embora os objetos da mesma classe tenham as mesmas características e funções, e talvez até os mesmos valores de atributos, cada nova instância da classe é representada separadamente na memória.
2.4 ENCAPSULAMENTO
Técnica que permite ocultar os atributos da classe, sendo que somente os métodos da classe própria podem ler ou alterar estes atributos. Isto faz com que não haja necessidade de saber como a classe foi implementada internamente, deixando que os métodos internos da classe se preocupem com isto.
Exemplo:

2.5 HERANÇA
A herança permite que as classes compartilhem os seus atributos e métodos com outras classes, utilizando para isto um relacionamento esquematizado de forma hierárquica.
Na herança há dois tipos de classes que devem ser levadas em consideração:
Exemplo:
java.lang.Object
|
+----java.awt.Component
|
+----java.awt.Container
|
+----java.awt.Window
|
+----java.awt.Dialog
|
+----java.awt.FileDialog
2.6 POLIMORFISMO
Uma subclasse pode implementar novamente um método ou atributo já implementado por uma classe da qual é herdeira.

3 A LINGUAGEM JAVA
3.1 PACOTES
O esquema de subdivisões de classes do Java é muito parecido com o esquema de subdiretórios de muitos sistemas operacionais, tais como o MS-DOS, Windows ou Unix. Cada subdiretório físico no disco corresponde a um pacote da linguagem. Assim, o pacote contendo a seguinte hierarquia:
java
|
+-----awt
|
+-------image
seria gravado em disco da seguinte forma:
java\awt\image\
Os pacotes estão organizados de uma maneira hierárquica, de forma que cada subpacote tenha uma função acertada dentro da linguagem e um conjunto de classes que realizam um trabalho específico.
3.2 TIPOS DE DADOS
O Java, como em C e C++, possui uma grande variedade de tipos de dados. A seguir estão os tipos primitivos de dados suportados pelo Java:
|
Descrição |
Designação Padrão |
Seqüência |
|
Continuação |
<newline> |
\ |
|
Nova linha |
NL (LF) |
\n |
|
Tabulação horizontal |
HT |
\t |
|
Retrocesso (backspace) |
BS |
\b |
|
Retorno de carro (carriage return) |
CR |
\r |
|
Avanço de página(form feed) |
FF |
\f |
|
Barra invertida |
\ |
\\ |
|
Aspas simples |
‘ |
\’ |
|
Aspas duplas |
" |
\" |
|
Padrão de bits para octal |
0ddd |
\ddd |
|
Padrão de bits para hexadecimal |
0xdd |
\xdd |
|
Caracter Unicode |
0xdddd |
\udddd |
3.3 OPERADORES
Eis alguns operadores importantes da linguagem Java:
3.3.1 Operador new
O operador new é utilizado sempre que é necessário criar uma nova instância de uma classe (objeto). Este operador tem um funcionamento parecido como o malloc() da linguagem C, alocando espaço em memória para a adequação do novo objeto.
3.3.2 Operador this
O operador this serve como uma referência para o próprio objeto que o está utilizando. Ele é utilizado, por exemplo, nos casos em que é necessário explicitar se uma variável faz parte da classe ou dos parâmetros do método.
Exemplo:
public class Exemplo{
private int Valor;
public void AlteraValor(int Valor){
// Para que o compilador saiba qual variável deve ser alterada
this.Valor = Valor;
}
}
3.3.3 Operador instanceof
O operador instanceof serve apenas para identificar se um dado objeto é uma instância da classe especificada.
Exemplo:
Button botao = new Button("Botão");
if (botao instanceof Object)
{
System.out.println("O objeto botao descende da classe Object!");
}
3.4 TIPOS DE MODIFICADORES
Além dos tipos de dados, na hora da declaração de um atributo (ou variável) deve ser declarado também o tipo de modificador que será utilizado para o atributo. Um modificador é usado para a identificação dos níveis de acesso de um atributo. Não só às variáveis, mas também aos métodos (ou funções) e às classes, o Java exige que seja declarado qual modificador deve ser aplicado.
3.4.1 Modificadores de atributos e métodos
Os atributos e métodos podem ser declarados com níveis de acesso do tipo: privado, protegido, público, estático e default. Veja abaixo a tabela:
|
private |
O método ou atributo pode ser acessado somente por métodos que estão dentro da própria classe na qual foi declarada |
|
protected |
Pode ser acessado pela própria classe e pelas classes que derivarem desta |
|
public |
Pode ser acessado de qualquer classe |
|
static |
Para os métodos ou atributos declarados como static, haverá apenas um desses para todos os objetos criados da classe |
|
<DEFAULT>(em branco) |
Pode ser acessado pela própria classe e por classes criadas dentro do pacote do qual esta classe pertence |
Estes são os tipos de modificadores mais utilizados. Os outros são:
|
final |
Não pode ser sobrecarregado |
|
synchronized |
O método não é reentrante |
|
native |
O método foi feito em outra linguagem (uma linguagem nativa da máquina) |
|
abstract |
O método não possui um corpo (não foi codificado). Quando um método é declarado como abstrato, a sua classe deve, obrigatoriamente, ser também declarada como abstrata |
3.4.1.1 Modificador static
O mais complicado dos modificadores mais utilizados é o static. Quando um método é declarado como static, diz-se que ele é um método da classe. Quando um método é declarado com outro modificador, diz-se que ele é um método do objeto.
Quando um objeto é declarado e inicializado, alguns passos são executados internamente:
Para os atributos, é reservado no objeto um espaço para os dados de cada atributo. Para os métodos, há somente uma área com os códigos de cada método, que é compartilhada com todos os objetos da classe.
O que acontece com os atributos estáticos é que quando um atributo é declarado como static, não é reservado no objeto um espaço para os dados deste atributo. Daí surgem algumas conseqüências para o programador:
Exemplo:
class Dinheiro{
private double Reais;
private static int nDecimais = 2;
public Dinheiro(double Reais)
{
this.Reais = Reais;
}
public double Valor()
{
return (Reais);
}
public static void MudaDecimais(int CasasDec)
{
nDecimais = CasasDec;
}
public static String paraString(double Valor, String Moeda, double Fator)
{
Valor = Valor*Fator;
String inteiro = Integer.toString((int)Valor);
int potencia = (int)Math.pow(10,nDecimais);
String decimal = Integer.toString((int)(((double)Valor-(int)Valor) *
potencia));
return (Moeda+inteiro+","+decimal);
}
}
Esta classe seria utilizada com as seguintes chamadas:
Dinheiro dinheiro = new Dinheiro(500.30);
// Imprime na saída padrão do sistema
System.out.println(Dinheiro.paraString(dinheiro.Valor(),"R$ ",1));
System.out.println(Dinheiro.paraString(dinheiro.Valor(),"URV ",.96));
Dinheiro.MudaDecimais(4);
System.out.println(Dinheiro.paraString(dinheiro.Valor(),"U$ ",1.112));
O atributo Reais da classe Dinheiro, por mais que esteja na mesma classe, está oculto para o método paraString(). Este método só enxerga o atributo nDecimais, que também é estático.
Exercício: Faça uma classe que armazene todos os pontos de um quadrado em 2D, e um método estático que receba um ponto e um comprimento e retorne um quadrado. Para isto crie a classe ponto e utilize vetores.
Exemplos de vetores: int x[] = {1,2,3};
Int y[3];
3.4.2 Modificadores de classes
As classes podem ser declaradas com níveis de acesso do tipo privado, publico, abstrato e final.
|
private |
Só pode ser acessada dentro do arquivo fonte no qual a classe foi codificada |
|
public |
Todos a acessam. Só pode haver uma classe pública por arquivo fonte |
|
abstract |
A classe não pode ser instanciada diretamente. |
|
final |
A classe não pode ser utilizada como superclasse (não pode possuir classes derivadas) |
3.4.2.1 Modificador abstract
Geralmente, uma classe é declarada como abstrata quando ela possui um método abstrato (que não tem corpo).
abstract class Abstrata{
public abstract void MetodoAbstrato();
}
Um método é declarado como abstrato quando deseja-se obrigar o programador, que irá utilizar a classe, a escrever o código deste método. Enquanto não for escrito o código deste método, não será permitida a instanciação desta classe. Para isto, cria-se uma classe derivada da classe abstrata, e inclui-se o código do método que foi declarado como abstrato.
public class NaoAbstrata extends Abstrata{
public void MetodoAbstrato()
{
//código do método
}
}
Uma classe pode também ser declarada como abstrata quando não se quer que a classe seja instanciada diretamente. Deve ser criada uma outra classe derivada desta, e somente esta última classe poderá ser instanciada.
abstract class Automovel{
public void Acelerar(int Acrescimo)
{
//código
}
public void Freiar(int Reducao)
{ //código}
}
public class BMW extends Automovel{
private long Preco$;
}
3.5 ACESSO A DADOS POR REFERÊNCIA
Uma das grandes vantagens de implementação do Java em relação ao C/C++ é a não utilização de ponteiros. Um dos grandes martírios dos programadores menos experientes em C é justamente a utilização de ponteiros, que costuma deixar rastros indesejáveis quando mal utilizado. O Java acaba com este problema ao eliminar o uso de ponteiros e adotar o uso de referências.
Acaba mesmo ? ! ?
Todos os dados que são manipulados em Java fazem parte de alguma classe, com exceção dos dados primitivos da linguagem (int, long, float, double, boolean, char). Toda instância de classe (ou objeto) criada é manipulada por alguém que referencie a ela. As variáveis que são declaradas no programa são as responsáveis pelas referências às instâncias de classes. As referências são feitas por meio do endereço da instância. Este endereço é atribuído a alguma variável declarada, que fica apontando para a instância; ou seja, resumindo, a variável declarada serve como um...ponteiro? Exatamente. Isto significa, então, que toda variável declarada para referenciar um objeto é um ponteiro. Parece confuso? Se isto não ficou claro, segue em baixo uma explicação mais detalhada:
No código:
String str = new String("Fala, Brasil!");
podemos distinguir três etapas. Na primeira etapa:
String str
foi declarada na memória uma variável para referenciar um instância da classe String. Na Segunda etapa:
new String("Fala, Brasil!")
foi criada na memória uma instância da classe String com o parâmetro de inicialização "Fala, Brasil!". E na terceira etapa:
String str = new String("Fala, Brasil!");
foi atribuído o endereço do objeto criado à variável str.
Se logo em seguida houvesse o código:
String prt = str;
poderíamos distinguir mais três etapas. Na primeira etapa:
String ptr
Seria criada a variável ou ponteiro. Na Segunda etapa:
str
seria capturado o conteúdo da variável str, ou seja, endereço da instância da classe String criada anteriormente. E na terceira etapa:
String ptr = str;
seria atribuído à variável ptr o endereço capturado.
Resumindo, nestas duas linhas:
String str = new String("Fala, Brasil!");
String ptr = str;
foram declaradas duas variáveis que apontam para o mesmo objeto criado na memória.
3.6 COLETOR DE LIXO (GARBAGE COLETOR)
Outra implementação muito útil do Java é o seu coletor de lixo. O coletor tem um conceito de funcionamento bem simples. Se não houver qualquer referência a um objeto que tenha sido criado na memória, o coletor de lixo destrói o objeto e libera a memória ocupada por ele.
O coletor de lixo é executado de tempos em tempos. Quando a JVM (Java Virtual Machine – Máquina Virtual Java) percebe que o sistema diminuiu a utilização do processador, ele libera o coletor de lixo, que vasculha a memória em busca de algum objeto criado e não referenciado.
Quando uma grande quantidade de objetos ou objetos muito grandes não são mais necessários, e você não quer esperar até que o coletor de lixo seja executado e libere toda esta memória, você pode chamá-lo explicitamente no programa, como no exemplo:
Runtime rt = java.lang.Runtime.getRuntime();
rt.gc();
Isto reduz a velocidade do programa por alguns instantes, mas evita a falta de memória.
3.7 SOBRECARGA DE MÉTODOS
Este tipo de sobrecarga é normalmente utilizada quando precisa-se fazer vários métodos com praticamente a mesma função, mas recebendo parâmetros diferentes para tipos de tratamentos diferentes.
Exemplo:
public class Pessoa{
private String Nome;
private boolean Vivo;
public Pessoa()
{
Vivo = true;
}
public Pessoa(String Nome)
{
Vivo = true;
This.Nome = Nome;
}
}
3.8 HERANÇA
A herança em Java é muito simples de ser implementada. Cada classe pode descender de uma outra classe utilizando-se apenas da palavra reservada extends no momento da declaração.
Uma classe que não descende de ninguém é implementada da seguinte forma:
public class SemDescendencia{
// declarações
}
Esta classe é chamada de classe pai ou superclasse quando alguma classe deriva-se dela da seguinte forma:
public class ComDescendencia extends SemDescendencia{
// declarações
}
Desta forma, a classe ComDescendencia torna-se uma classe filha da classe SemDescendencia, herdando todas as características desta.
A classe Object é a raiz da árvore hierárquica do Java. Todas as classes criadas no Java descendem dela, possuindo todos os métodos que ela possui. O programa a seguir prova isto:
public class Principal{
public static void main(String args[])
{
new SemDescendencia2().imprime();
}
}
class SemDescendencia2{
public void imprime()
{
System.out.println(getClass());
}
}
O método getClass() pertence à classe Object, mas a classe SemDescendencia2 não descende de Object diretamente. Esta descendência está implícita.
A herança em Java é implementada como uma herança simples, ou seja, cada classe pode descender de apenas uma única classe pai de cada vez. Quando se deseja implementar a herança múltipla, deve-se utilizar o que no Java é chamado de interface.
Exercício: Construa e codifique a herança das classes Moto, Bicicleta e Triciclo, tendo como base a classe Veículo. Considere as propriedades Motor e Rodas.
3.9 INTERFACE (ou HERANÇA MÚLTIPLA)
Quando é necessário que uma classe descenda de várias classes classes pais de uma só vez, devemos implementar aquilo que no Java chamamos de interface.
A interface tem a seguinte sintaxe:
public
interface NomeDaInterface implements interface1, interface2, ...interface-nUma interface consiste em uma classe contendo somente métodos abstratos e atributos finais e estáticos. Então qual é a utilidade da interface, se nada nela é implementado e, consequentemente, nada será herdado?
Imagine a seguinte situação: você tem uma classe de professores e uma de alunos, e deseja fazer um método que trate dos professores e alunos como seres humanos, com direitos e deveres iguais, ou seja, com tratamentos em comum. Você poderia fazer a seguinte codificação:
public class Pessoa{...}
public class Aluno extends Pessoa{...}
public class Professor extends Pessoa{...}
e no método prototipado desta forma:
public void TrataPessoa(Pessoa p);
uma chamada seria como esta:
Aluno aluno = new Aluno();
Professor professor = new Professor();
TrataPessoa(aluno);
TrataPessoa(professor);
Mas imagine que as classes Professor e Aluno são threads, ou seja, estas classes já descenderam de outra classe. Como solução imediata, este problema poderia ser resolvido da seguinte forma: fazer separadamente métodos que tratem dos direitos e deveres dos professores e dos alunos.
public class Aluno extends Thread {...}
public class Professor extends Thread {...}
e em métodos prototipados desta forma:
public void TrataPessoa(Aluno a);
public void TrataPessoa(Professor p);
as chamadas seriam como estas:
Aluno aluno = new Aluno();
Professor professor = new Professor();
TrataPessoa(aluno);
TrataPessoa(professor);
Desta maneira, todos os métodos que precisarem receber Pessoa deverão ser duplicados. Para evitar este trabalho todo, a interface resolve este problema da seguinte forma:
public interface Pessoa{...//
declarações abstratas de métodos e atributos de Pessoa}public class Aluno extends Thread implements Pessoa{...}
public class Professor extends Thread implements Pessoa{...}
e em métodos prototipados desta forma:
public void TrataPessoa(Pessoa p);
public void TrataThread(Thread t);
as chamadas seriam como estas:
Aluno aluno = new Aluno();
Professor professor = new Professor();
TrataPessoa(aluno);
TrataPessoa(professor);
// Professor e Aluno são ambos descendentes de Thread e Pessoa
TrataThread(aluno);
TrataThread(professor);
Outra vantagem é que a interface permite que o método que vai receber como parâmetro uma instância da interface (no exemplo, TrataPessoal(Pessoal)) trate somente com os métodos e atributos que foram definidos na própria interface, deixando todos as demais implementações do objeto invisíveis para o método.
3.10 MULTITHREAD
O Java é uma linguagem de 32 bits baseada em sistemas operacionais multitarefas. Por ser uma linguagem multithread, ou multitarefa, cada programa Java pode gerar várias tarefas, que serão executadas de forma totalmente independentes umas das outras.
Antes da classe principal ser carregada, a JVM cria uma thread simples que chama o método main() da classe a ser carregada. A JVM continua ativa enquanto há threads sendo processadas, ou até que o método exit() da classe Runtime seja chamado explicitamente.
Uma thread pode ser implementada da seguinte forma:
public class MINHASTHREADS implements runnable{
// declarações
public void run()
{
// código da thread
}
}
Quando o código abaixo é colocado em alguma outra classe:
MINHASTHREADS thread1 = new MINHASTHREADS();
MINHASTHREADS thread2 = new MINHASTHREADS ();
duas instâncias da classe MINHASTHREADS são criadas. O código a seguir cria duas novas instâncias da classe Thread e chama o método start() delas. Quando o método start() é chamado, a JVM procura e chama o método run() de Thread1 e Thread2.
new Thread(thread1).start();
new Thread(thread2).start();
Uma Segunda forma de se implementar uma thread pode ser feita da seguinte forma:
public class MINHASTHREADS extends Thread{
// declarações
public void run()
{
// código da thread
}
}
O código abaixo cria duas instâncias da classe MINHASTHREADS e chama, logo em seguida, o método start(). Esta chamada pode ser feita diretamente, pois a classe MINHASTHREADS descende da classe Thread, o que torna o código mais simples que o primeiro.
MINHASTHREADS thread1 = new MINHASTHREADS ();
MINHASTHREADS thread2 = new MINHASTHREADS ();
Thread1.start();
Thread1.start();
Quando é necessário que duas ou mais threads entrem em sincronismo, é necessário que haja uma pausa na thread que está sendo executada para que ela não tome todo o tempo do processador, dando chance para que outra thread seja processada. Isto é feito incluindo se a seguinte chamada de método:
yield();
Este método retira temporariamente a thread da linha de execução para que outras threads sejam executadas.
Exercício: Crie uma thread que imprima as horas a cada vez que os segundos mudarem, e outra thread que imprima quanto tempo falta para o dia seguinte (em segundos). A impressão deve ser feita na saída padrão do sistema.
3.11 TRATAMENTO DE EXCEÇÕES
A construção de um programa precisa ser feita de tal forma que ele sempre possa lidar com o inesperado. Nas linguagens de programação mais antigas, era necessário que você fizesse o tratamento das situações incorretas com enormes e complicados blocos if-then-else. A linguagem Java implementa o tratamento de exceções de uma maneira mais simplificada, através de blocos catch. Os blocos catch devem ser colocados em todos os códigos nos quais os resultados de certas operações possam ser duvidosos. A sintaxe para um bloco catch é a seguinte:
try
{*/ Operação duvidosa */}
catch (Exceção1)
{/* Tratamento da exceção 1*/}
...
catch (Exceção-n)
{/* Tratamento da exceção n*/}
Exemplo:
try{
String string = new String("0xaa");
Integer NovoInteiro = new Integer(string);
}catch(NumberFormatException e){
System.out.println("Não foi possível converter "+e.getMessage()+ " em Integer");
}
Se não for colocado um tratamento de exceção para este código no método onde ele está, a execução do programa retorna na pilha por todos os métodos até que se encontre um bloco catch em algum método que trate a exceção lançada. Se não for encontrado nenhum bloco, o programa retorna por toda a pilha e finaliza a sua execução. Se for encontrado, o bloco catch é executado e o programa retoma a sua execução normal.
4 APPLETS
4.1 O QUE SÃO APPLETS
Applets são programas em Java feitos especialmente para rodar em browsers na Internet. Uma applet possui vários recursos gráficos para a apresentação de dados na tela, sendo que os recursos mais comuns de apresentação de dados, as saídas padrões do Java, não funcionam no browser, pois são recursos não gráficos.
Uma applet possui várias implementações de segurança que um aplicativo Java não tem. Enquanto que em um aplicativo normal em Java você pode, por exemplo, ler, gravar, alterar arquivos e configurações do sistema, a linguagem Java impede que uma applet faça qualquer tipo de acesso a recursos físicos do sistema que está sendo utilizado. Mas há exceções: isto depende da versão do Java que está sendo utilizada, e versões mais antigas possuem menos recursos de proteção ao sistema.
4.2 COMO IMPLEMENTAR UMA APPLET
A applet básica tem uma implementação muito simples. Veja o exemplo:
import java.applet.*;
import java.awt.*;
public class Contador extends Applet{
int cont;
public void init()
{
System.out.println("Isto aqui não vai aparecer no browser!");
cont = 1;
}
public void start()
{
repaint();
}
public void stop()
{
cont++;
}
public void paint(Graphics g)
{
g.drawString("Isto apareceu no browser pela "+cont+" ª vez",10,10);
}
}
Podemos dividir este pequeno programa em algumas áreas de interesse. Primeiramente, nas linhas:
import java.applet.*;
import java.awt.*;
foi dito ao Java que considerasse, na hora de compilar, todas as classes que estão localizadas no pacote java.applet e no pacote java.awt.
O código:
public class Contador extends Applet{
diz que a classe Contador é uma classe pública que descende (ou estende) da classe Applet.
public void init()
public void start()
public void stop()
public void paint(Graphics g)
Os métodos acima, que foram implementados no programa, sobrecarregam (ou sobrepõem) os métodos init(), start(), stop() e paint() da classe Applet. O browser, antes de carregar uma applet, carrega uma classe chamada appletviewer, que é uma thread. A classe appletviewer recebe como parâmetro a applet a ser carregada e chama, logo em seguida, os métodos ditos anteriormente. Estes métodos são chamados na seguinte ordem:
init() – chamado apenas uma vez, logo após o carregamento da applet.
start() – chamado logo após a chamada do método init(), e toda vez que a applet torna-se visível na tela
stop() – chamado toda vez que a applet torna-se invisível.
paint() – chamado pelo Java toda vez que a applet precisa ser redesenhada. Pode ser chamado explicitamente através do método repaint(). O método paint() recebe como parâmetro uma instância da classe Graphics. A classe Graphics é utilizada para saídas gráficas no browser. Todos os métodos desta instância imprimem na área de visualização da applet. Tudo o que não for impressão gráfica não sairá na applet, mas ficará na área de saída padrão do sistema, como acontece com este código:
System.out.println("Isto aqui não vai aparecer no browser!");
Quando a applet é inicializada, é atribuído o valor 1 à variável cont. Toda vez que a applet fica invisível na tela, a variável cont é incrementada, e toda vez que o a applet fica visível, uma nova string é impressa na tela.
Exercício: Crie uma applet que imprima "Hello, world! Who’s talking?".
4.3 O MÉTODO ACTION
O método action é um método especial da applet que é utilizado pelo Java para avisar a applet que um evento ocorreu. Este método recebe dois parâmetros e retorna um boolean.
public boolean action(Event evt, Object o)
Cada tipo de evento é tratado de uma forma diferente. Para tratamento de eventos específicos, é necessário recorrer à manuais específicos. O valor de retorno deste método é importante, pois deve ser retornado false se ele não tratou o evento ocorrido. Se o método action retornar true, o evento deve ter sido tratado.
4.4 APPLETS EM PÁGINAS HTML
Para podermos implementar uma applet com os seus recursos gráficos, primeiro devemos aprender como utilizá-los.
Os recursos gráficos da applet estão organizados de forma hierárquica:
java.lang.Object
|
+----java.awt.Component
|
+----java.awt.Container
|
+----java.awt.Panel
|
+----java.applet.Applet
A classe Applet, por ser a classe que vai ser apresentada na tela, possui várias características gráficas de browser. A Applet é um Panel.
Por sua vez, a classe Panel possui as características da classe da qual descende, Container, com apenas algumas poucas alterações.
A classe Container é uma classe de organização de layout. Pode ser escolhido o tipo de layout a ser utilizado na montagem da tela (setLayout()). Objetos Component podem ser adicionados a sua estrutura de layout.
A classe Component é a classe da qual descende várias outras classes de objetos de tela, tais como: Button, Label, TextArea, TextField, Canvas, etc. Ela é uma das classes que contém o objeto Graphics, específico para desenhos em tela.
A classe Object é a classe da qual todas as outras classes do Java descendem, tanto implicitamente quanto explicitamente.
Exemplo de utilização dos recursos gráficos de uma Applet:
import java.awt.*;
import java.applet.*;
public class MinhaApplet extends Applet{
Canvas canvas;
Button botao;
Label label;
TextField tf;
public void init()
{
canvas = new Canvas(); // Cria uma área de desenho
canvas.resize(100,100); // Dimensiona esta área
label = new Label("Número da cor: ");
tf = new TextField("0",2);
botao = new Button("Alterar cor");
// Altera o layout para o layout de borda
setLayout(new BorderLayout(20,20));
// Adiciona os componentes em seus respectivos pontos cardeais
add(canvas,BorderLayout.NORTH);
add(label,BorderLayout.WEST);
add(tf,BorderLayout.EAST);
add(botao,BorderLayout.SOUTH);
}
public boolean action(Event evt, Object o)
{
// Sintaxe para obtenção de eventos de botão
if (evt.target instanceof Button)
if (o == "Alterar cor"){
int c = Integer.decode(tf.getText()).intValue();
Color cor = new Color(c,c,c);
canvas.setBackground(cor);
canvas.repaint();
}
return(true);
}
}
Exercício: Crie uma applet que imprima as horas do sistema e quantos segundos faltam para o dia seguinte. Para isto, utilize duas threads.
5 APLICATIVOS COM JAVA
5.1 CRIANDO APLICATIVOS COM JAVA
Um aplicativo em Java não serve para ser executado sob um browser, pois browsers entendem apenas applets. A JVM precisa ser executada explicitamente para podermos carregar um aplicativo. Uma das grandes vantagens do aplicativo feito em Java sobre as applets é que o JVM não impõe limites sobre as ações do aplicativo, ficando o programador livre para utilizar todos os recursos da linguagem. Do contrário, a vantagem das applets sobre os aplicativos é que já elas vêm com os recursos gráficos embutidos, o que torna a utilização deles relativamente simples, além de poderem ser visualizadas em browsers pela Internet.
Criar um aplicativo em Java é simples. Uma da poucas diferenças práticas iniciais que um aplicativo Java tem de uma applet Java é que os aplicativos devem implementar um método chamado de main(). Este método dever ser estático, de tal forma que todos os objetos instanciados da classe principal contenha apenas um método main(). Quando for necessário que os métodos a serem implementados estejam na mesma classe que o método main(), deve ser feito algo como as seguintes linhas de código:
public class menu {
int nOp;
String sOp;
public static void main(String args[])
{
menu n1 = new menu ("Pesquisar",0);
menu n2 = new menu ("Imprimir",1);
n1.Saida();
n2.Saida();
}
public menu(String sOp, int nOp)
{
System.out.print("Opção "+sOp+"|");
this.sOp = new String (sOp);
this.nOp = nOp;
}
void Saida()
{
System.out.println("\nEsta instância representa a opção "+nOp+" => "+sOp);
}
}
A JVM chama o método main() da classe menu. Como o método main() é estático e só pode acessar métodos que também sejam estáticos, não é possível chamar diretamente o método Saida(). Então, pode ser criada uma instância da classe menu de dentro de main(), que também é da classe menu. Isto assegurará que todos os atributos e métodos que não são estáticos na classe menu sejam visíveis dentro do método main(). Os atributos nOp e sOp declarados no início do programa não são atributos estáticos, ou seja, cada nova instância declarada da classe menu possui o seu próprio nOp e sOp.
Há outras maneiras de se fazer este programa, e uma maneira mais clara do do que a anterior é a seguinte:
public class menu{
public static void main(String args[])
{
Opcao n1 = new Opcao ("Pesquisar",0);
Opcao n2 = new Opcao ("Imprimir",1);
n1.Saida();
n2.Saida();
}
}
class Opcao {
int nOp;
String sOp;
public Opcao(String sOp, int nOp)
{
System.out.print("Opção "+sOp+"|");
this.sOp = new String (sOp);
this.nOp = nOp;
}
void Saida()
{
System.out.println("\nEsta instância representa a opção "+nOp+" => "+sOp);
}
}
Exercício: Faça um aplicativo que calcule e imprima na saída padrão o volume de um cubo. Para isto, crie uma classe Ponto3D, Cubo e um método estático, como já visto no capítulo sobre o "Modificador STATIC".
6 EXERCÍCIO
6.1 DIAGRAMA DE BLOCOS DO EXERCÍCIO






1 – Coloque os níveis de acesso corretos de maneira mais restringível possível. Faça isto para todas as classes do programa RiverRaid.
2 – Compile e execute as classes de RiverRaid. Utilize para isto o javac e o appletviewer, respectivamente.