1slide/pag

Propaganda
Introdução ao Java
FEUP>DEEC>MRSC>Programação em Comunicações
v1.4
Isidro Vila Verde <[email protected]>
Jaime Sousa Dias <[email protected]>
O que é o JAVA?
• É uma Linguagem de Programação
•
•
•
•
•
Orientada aos objectos ÆClass Based
Concorrente
High Level
Strongly Typed
Portável
• Um programa em JAVA é independente da arquitectura
• Em principio pode correr em qualquer plataforma
• Uma máquina virtual (JVM)
• Biblioteca de Classes
• API
2
Comparação com outras linguagens
Diferenças para o C++
• Cada classe (pública) é gravada num ficheiro respectivo
com o mesmo nome da classe* e extensão .java
• * Na realidade esta afirmação só se aplica a Top Level Classes
• O que existe em Java
• Run Time Type Check
• Array bounds
• Null pointers access
• Interfaces
• Concorrência (Multi-thread) nativa
• Garbage Collector
• Os recursos dos objectos são automaticamente libertados quando o
sistema detecta que já não são necessários (referenciados)
4
Diferenças para o C++ (2)
• O que não existe em Java
• Estruturas (struct)
• Uniões (union)
• Apontadores ou ponteiros (pointers)
• Apenas referências
• Apontadores para funções (Function Pointers)
• Funções globais
• Incluindo a função do C/C++ main Æ Em java o main é uma função
membro estática
• Variáveis/Objectos globais
• Malloc’s ou delete’s ÆA gestão de memória é automática
(Garbage Colector)
• Herança múltipla
5
Diferenças para o C++ (3)
• O que não existe em Java (cont.)
•
•
•
•
•
Sobrecarga de operadores (operator overloading)
Templates
Header Files (.h)
Directiva de pré-processamento (ex: #pragma)
Variáveis-objecto Æ Em java tudo o que não seja tipo primitivo é
manuseado como referência
6
Java vs. outras linguagens
• PERL, TCL, Python
•
•
•
•
São interpretadas
O código fonte é distribuído aos utilizadores
Obriga à instalação prévia do interpretador
Se fizer uso de primitivas/comandos do sistema terá de haver uma
versão de código para cada S.O.
• Execução lenta
7
Java vs. outras linguagens (2)
• C, C++, Pascal
• São linguagens compiladas
• O código fonte não é distribuído aos utilizadores, apenas o código
binário
• Se fizer uso de primitivas/comandos do sistema terá de haver uma
versão de código para cada S.O.
8
Java vs. outras linguagens (3)
• C, C++, Pascal (cont.)
• Necessita de uma versão binária por cada ambiente (S.O. + CPU)
• Windows
• Eventualmente: 95, NT, 2000
• Necessáriamente: Intel, Alpha, Mips
• Unix
• Eventualmente: BSD, Linux, AIX, HP-UX, SCO
• Necessariamente: Sparc, Intel, Alpha, Mips
• Execução Eficiente
• Em C ou C++ é possível controlar ao nível do assembly a eficiência
• O programador pode controlar/garantir eficiência
9
Java vs. outras linguagens (4)
• JAVA
• É compilado para uma máquina virtual
• O compilador gera Bytecodes
• O Código fonte não é distribuído
• Uma só versão de código independente da plataforma (CPU e/ou
S.O.)
• O código binário (Bytecodes) é carregado e interpretado na JVM
(Java Virtual Machine)
•
$> java codigodaclass
• Obriga à existência ou instalação prévia do JRE (Java RunTime
Enviroment)
• Incluí a JVM
• Execução lenta
10
Ambiente JAVA
WRITE
USE
JRE
Java Source
App.java
Class loader
bytecode verifier
Java
Libraries
JDK
System
Library classes
Compile
Java Byte Codes
App.class
Java
Interpreter
Just in Time
Compiler
Runtime System
J
V
M
Operating System
Hardware
11
Tipos de programas Java
• Aplicações
• programas “Standalone”
• Applets
• Componentes de código que correm num ambiente WEB
• Servlets
• São componentes de código que correm num servidor WEB por
oposição às Applets que correm no cliente (navegador)
• JSP
• Java Server Pages – Directivas embutidas em páginas HTML que
permitem executar código JAVA intercalado com HTML
12
Exemplo de Utilização
Executar uma aplicação escrita em Java
• O JRE
•
java, javaw, appletviewer
• O código da aplicação
•
App.class
• Executar
•
$> java App
• Omite-se a extensão “.class”
• Nota: o ficheiro App.class deve estar o directório corrente ou num
dos directórios incluídos na variável de ambiente CLASSPATH.
14
JRE instalado?
• Verificar se já está instalado
• Executar java -version
• Se corre então deve estar (devidamente?) instalado
• Nas distribuições recentes dos S.O.s já é fornecido e instalado por
omissão
• Se não encontrou o programa java
• http://java.sun.com
• Seleccionar o J2SE (última versão)
• Selecionar o JRE
• O SDK só é necessário para fazer desenvolvimento
• Fazer o download e instalar
15
Criar uma aplicação em Java
• Um editor de texto
• vi, pico, notepad, wordpad, etc.
• O java JDK (SDK)
• Verificar se já está instalado
• Executar javac -version
• Se corre então deve estar (devidamente?) instalado
• Nota: não é java é javac (Java Compiler)
• Se não encontrou o comando
• http://java.sun.com
• Seleccionar o J2SE (última versão)
• Seleccionar o SDK
• Fazer o download e instalar
16
Escrever a aplicação
• Criar um ficheiro com o nome da aplicação e extensão
.java
• Ex: App.java
• Editar o ficheiro App.java e criar uma classe (class) App
pública (public)
public class App {
}
17
Escrever a aplicação (2)
• Incluír na definição da classe um método estático (static)
público (public) e sem tipo (void), de nome main com um
argumento do tipo array de strings (String[])
public class App {
public static void main(String[] args) {
}
}
18
Escrever a aplicação (3)
• Definir o método main para executar o código pretendido
• Ex: Escrever “Hello World”
public class App {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
19
Compilar o código
• Gravar o ficheiro
• Compilar o código em linha de comando
• Usar o “comando” javac
• $> javac App.java
• Verificar que foi criado o ficheiro App.class
• Testar o código
•
$> java App
20
Análise do “Hello World”
O Hello World
public class App {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
• Componentes do “Hello world”
•
•
•
•
•
•
Declaração da classe (class)
método main
Classe String
System.out.println
Modificador de acesso public
Modificador static
22
Class
• O formato mais simples para definir uma classe é este:
[<acessibilidade>] class <Nomeclass> {
<declaração e definição dos membros aqui>
}
• No caso do exemplo “Hello World”:
•
Nomeclass é o nome que quiser, tendo em atenção que:
• Deve ter o mesmo nome que o ficheiro onde está
• É sensivel à capitulação dos caracteres
• A visibilidade tem de ser public para ser visível do exterior
23
Método
• Os métodos são funções ou procedimentos membros de
uma dada classe que permitem manusear o objecto
• Um caso especial dos métodos é o método
public static void main (String[] argv).
• Por se chamar main, ser estático (static) e público (public) é
invocado sempre que se carrega a classe (programa standalone)
• $> java App
24
Classe String
•
A classe String
• É uma classe do ‘core’ do Java
• Está definida na API
• Está incluída na package
java.lang
• Como o próprio nome indica
fornece um conjunto de
métodos para trabalhar com
cadeias de caracteres
25
System.out.println
•
•
•
A classe System está definida
na package java.lang
Tem uma variável membro out
do tipo PrintStream
out é o standard output e está
aberto e pronto a receber
caracteres
26
System.out.println
•
System.out
• É uma instância /objecto da
classe java.io.PrintStream
• A classe PrintStream está
definida na package java.io
• Tem um método membro
println(String)
27
Modificador public
• public é um modificador de acesso (visibilidade )
• permite que a classe App esteja acessível de fora da
package (neste caso o ficheiro)
• Além da classe ser acessível também é preciso dar
acessibilidade pública ao método main para poder ser
invocado a partir do exterior da package
28
Modificador static
• O modificar static permite que o método main seja
invocado sem haver ainda qualquer instância da classe já
criada
• Aplica-se à classe e não a um objecto em particular
29
A linguagem Java
Componentes da Linguagem Java
[<package>]
<Classe>*
<Membros>*
<Campos>*
<Métodos>*
<Classes>*
<Interfaces>*
<Interfaces>*
<IMembros>*
<Campos>*
<IMétodos>*
31
Java Keywords
abstract
boolean
break
byte
case
catch
char
class
const
Continue
default
do
double
else
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
null
package
private
protected
public
return
short
static
super
switch
synchronised
this
throw
throws
try
void
while
volatile
32
Class
Class
• A declaração de uma classe é a principal declaração em
JAVA
• Em Java tudo é implementado em Classes
• Uma classe é uma colecção de dados e/ou código que
define intrinsecamente as características e comportamento
de um certo conjunto de objectos.
• Uma classe está para os objectos como um esquema
electrónico está para um equipamento fabricado em série.
34
Class
• A declaração de uma classe define um novo tipo e
descreve as suas características e comportamento.
• O formato mínimo para declarar uma classe deve obedecer
à seguinte regra
<modificador>* class <ClassName>{
<membros>*
}
• Por convenção o nome da classe (<ClassName>) deve
começar por uma maiúscula
35
Class
Ex1\A.java
class A {
Membros
das Classes
int j = 6;
}
class B {
int j = 66;
}
Ex1\Ex0.java
public class Ex0 {
public static void main(String[] args) {
A a = new A();
B b = new B();
System.out.println(a.j);
System.out.println(b.j);
}
}
36
Membros da Classe
Membros da Classe
• Uma classe é composta por:
•
•
•
•
•
Campos
Métodos
Classes
Interfaces
Inicializadores
• Os campos são:
• Variáveis de tipos primitivos
• Ou referências para objectos
38
Tipos Primitivos
• Estes são os tipos primitivos do Java. Tudo o resto são
referências
• Inteiros
•
•
•
•
byte
short
int
long
(1 byte, -128 to 127)
(2 bytes)
(4 bytes)
(8 bytes)
• Vírgula flutuante
•
•
float
(4 bytes, 6-7 significant decimal digits)
double (8 bytes, 15 significant decimal digits)
39
Tipos Primitivos (2)
•
•
char
boolean
(2 byte, Unicode) (ASCII 1 byte)
(true or false)
• Não se pode converter booleanos em inteiros e vice-versa
40
Métodos
• Os métodos são funções ou procedimentos membros da
classe
• A declaração dos métodos obedece a esta regra
<modificador>* <tipo> <nome>(Arg*){
<codigo aqui>
}
• No caso dos construtores a regra muda para:
<modificador>* <nome>(Arg*){
<codigo aqui>
}
• O modificador pode assumir vários valores
41
Métodos – Exemplo
Ex2\Counter.java
public class Counter {
int n = 0; //campo membro
//método membro estático
public static void main(String[] argv) {
Counter c = new Counter();
c.print();
mark("v = " + c.n);
c.go(5);
mark("v = " + c.inc());
c.go(7);
}
//método membro que retorna um int
int inc(){
return n++;
}
Continua
42
Métodos – Exemplo (2)
Ex2\Counter.java (cont.)
//método membro estático
static void mark (String s){
System.out.println(s);
}
//método membro
void print (){
System.out.println ("Counter = " + n);
}
//método membro
void go (int k){
while (k-- > 0){
inc();
print();
}
}
}
43
Operador de acesso aos membros
• O acesso aos membros da classe é feito com o operador “.”
<Nome da instância>.<nome do membro>
• Acesso aos métodos membro
c.print();
• Acesso aos campos membro
c.n
• Dentro de um método (não static) o nome da instância
está implícito e como tal é desnecessário
int inc(){
return n++;
}
44
Construtor
• Dentro dos métodos há uma situação particular designada
por Constructor
• Os construtores são métodos mas com algumas
particularidades
• Têm o mesmo nome da classe e não têm um tipo definido
explicitamente
• São invocados quando se instancia um novo objecto (com o
operador new)
• Não podem ser invocados explicitamente com o operador “.”
• Racional para isto:
• Se o objecto ainda não foi criado não se pode invocar métodos sobre o
mesmo
• Se já foi criado então não faz sentido cria-lo novamente
45
Construtor – Exemplo
Ex3\Counter2.java
public class Counter2 {
int n = 0;
Counter2 (int x){
n = x;
}
public static void main(String[] argv) {
Counter2 c = new Counter2(5);
mark("v = " + c.n);
c.inc();
mark("v = " + c.n);
}
int inc(){ return n++;}
static void mark(String s){ System.out.println(s);}
void print(){System.out.println("Counter = " + n);}
}
46
Métodos especiais
• Há dois métodos que têm um tratamento especial derivado
do seu nome
• O método public static main (String[] argv)
• Se declarado dentro de uma classe publica é o primeiro a ser invocado
quando se carrega a classe
• $> java Counter2
•
O método protected void finalize()
• É invocado pelo sistema quando este detecta que o objecto já não é
usado
• Não é garantida a ordem de invocação deste método
47
Métodos especiais (por convenção)
• Convencionou-se que as seguintes regras de atribuição de
nome aos métodos traduzem acções bem definidas
• Métodos de atribuição de valores
void setQualquerCoisa(tipo1){
variavelQualquerCoisa = arg1;
}
• Métodos de inspecção de valores
tipo1 getQualquerCoisa(){
return variavelQualquerCoisa;
}
48
Classe vs. Objecto
Classe vs. Objecto
• Um objecto é uma instância de uma classe
• Num programa em Java cada classe é única mas pode
haver (e normalmente há) vários objectos da mesma classe
• A classe define as características e o comportamento do
conjunto de objectos do seu tipo
50
Classe vs. Objecto (2)
• Em Java não há variáveis-objecto.
• Todas as variáveis de algum tipo não primitivo são na
realidade referências para o objecto e não o objecto em si
mesmo
ClasseT a = new ClasseT;
• Consequências Æ A atribuição não copia o objecto
ClasseT b = a;
• Algumas análogias
• Esquema electrónico Ù Equipamento produzido
• Planta Ù Habitações (iguais) construídas
51
Herança
Herança
• A herança é uma técnica para derivar novas classes a partir
de classes já existentes
• As novas classes assim criadas são chamadas subclasses e
herdam das superclasses
• A subclasse herda os membros da superclasse e pode:
• Acrescentar mais membros
• Redefinir os métodos da superclasse (sobreposição)
53
Herança (2)
• Um objecto do tipo de uma subclasse é automaticamente
também do tipo da superclasse
• O inverso é falso
• Os objectos instanciados da subclasse formam um subconjunto dos
objectos da superclasse
• O formato base para declarar uma subclasse é este
<modificador>* class <SubClassName> extends <SuperClassName>{
<membros>*
}
54
Herança – Exemplo
Ex4\Comp.java
class Storage{
private int cap;
void setCap(int c){cap = c;};
int getCap(){return cap;}
int getCar(){return 0;}
}
//Disco é uma subclasse de Storage
class Disco extends Storage{
private int rpm = 7800;
int getCar(){return rpm;}//sobreposição do método
}
//Memoria é uma subclasse de Storage
class Memoria extends Storage{
private int vel = 233;
int getCar(){return vel;}// sobreposição do método
int getDataWidth(){return 64;}
}
Continua
55
Herança – Exemplo (2)
Ex4\Comp.java (cont.)
public class Comp{
static public void main(String[] s){
Disco d = new Disco();
Memoria m = new Memoria();
d.setCap(80); //setCap é membro de Disco por herança
m.setCap(512);
System.out.println("ds = " + d.getCap());
//Chama o membro getCar() de Disco porque foi sobreposto
//nesta classe ao getCar() de Storage
System.out.println("r = " + d.getCar());
System.out.println("ms = " + m.getCap());
System.out.println("v = " + m.getCar());
System.out.println(“dw = " + m.getDataWidth());
}
}
$>java Comp
ds = 80
r = 7800
ms = 512
v = 233
dw = 64
56
Polimorfismo
Polimorfismo
• Um nome, várias formas.
• Em Java o polimorfismo manifesta-se na forma de
múltiplos métodos (diferentes implementações) com o
mesmo nome.
• Dois tipos
• Polimorfismo por sobrecarga de métodos: múltiplos métodos com
o mesmo nome mas diferentes listas de parâmetros.
• Polimorfismo por sobreposição de métodos: múltiplos métodos
com o mesmo nome, a mesma lista de parâmetros e devolvem o
mesmo tipo.
58
Sobrecarga
• Os métodos são identificados pelo seu nome e pela sua
assinatura
• A assinatura é a combinação do tipo de argumentos com o seu
número e a sua ordem
• Algumas assinaturas possíveis para o método estenome
•
•
•
•
•
void
void
void
void
void
estenome
estenome
estenome
estenome
estenome
(String s)
(int n)
(Strint s, int n)
(int n, String s)
()
• A sobrecarga de um método é feita definindo um outro
método com o mesmo nome mas com assinatura distinta
59
Sobrecarga – Exemplo
Ex11\comp.java
public class Comp{
private int n;
private String nome;
/** A sobrecarga também se aplica aos Construtores.
/* Por omissão o Java fornece um construtor nulo se não houver qualquer construtor
/* definido. No entanto, se isso acontecer e quisermos continuar a ter um construtor
/* nulo, temos de o definir
public Comp(){}
public Comp(String s){nome = s;}
public Comp(String s, int x){nome = s; n = x;}
public Comp(int x){n = x; nome ="";}
public void setCaract(String s){nome = s;}
public void setCaract(String s,int x){nome = s; n = x;}
public void setCaract(int x){n = x;}
static public void main(String[] s){
Comp c0 = new Comp();
Comp c1 = new Comp(5);
Comp c2 = new Comp("garfield");
Comp c3 = new Comp("snoopy",6);
c0.setCaract(3);
c0.setCaract("alf",3);
c1.setCaract("bunny");
}
60
}
Sobreposição
• Quando a superclasse e a subclasse implementam um
método com o mesmo nome e a mesma assinatura.
• Com a sobreposição, a escolha do método a executar
baseia-se no tipo do objecto cuja referência está guardada
na variável de referência e não no tipo da variável de
referência através da qual o método é invocado.
• Ao contrário da sobrecarga, onde a decisão do método a
invocar é feita durante a compilação, na sobreposição a
decisão só pode ser feita em run-time (late binding ou
Dynamic Bind).
61
Sobreposição
• Permite que os métodos de objectos de subclasses
diferentes com uma superclasse comum sejam
uniformemente invocados
• resultando na invocação de diferentes métodos de acordo
com a sua subclasse de forma transparente para o
programador e para o compilador
• Permite o uso do mesmo código para manipular dados cujo
tipo (subclasse) ainda não é conhecido
62
Sobreposição – Exemplo
Ex5\Comp.java
class Storage{
private int cap;
void setCap(int c){cap = c;};
int getCap(){return cap;}
int getCar(){return 0;}
String getCarUnits(){return "desconhecidas";}
}
class Disco extends Storage{
private int rpm = 7800;
//métodos sobrepostos
int getCar(){return rpm;}
String getCarUnits(){return "Rpm";}
}
class Memoria extends Storage{
private int vel = 233;
int getDataWidth(){return 64;}
//métodos sobrepostos
int getCar(){return vel;}
String getCarUnits(){return "Mhz";}
}
Continua
63
Sobreposição – Exemplo (2)
Ex5\Comp.java (cont.)
public class Comp{
static public void main(String[] s){
Storage s0 = new Disco();
Storage s1 = new Memoria();
s0.setCap(80);
s1.setCap(512);
System.out.println("ds = " + s0.getCap());
System.out.print("r = " + s0.getCar());
System.out.println(" " + s0.getCarUnits());
System.out.println("ms = " + s1.getCap());
System.out.print("v = " + s1.getCar());
System.out.println(" " + s1.getCarUnits());
//System.out.println("dw = " + s1.getDataWidth());
/**Erro! s1 é do tipo Storage e esta classe não
*define qualquer membro getDataWidth()
System.out.println("dw = " + ((Memoria)s1).getDataWidth());
//OK: foi feito o downcasting da referência para o tipo Memoria
}
}
$>java Comp
ds = 80
r = 7800 Rpm
ms = 512
v = 233 Mhz
dw = 64
64
Package
Package
• Cada classe em Java é compilada para um ficheiro distinto
mesmo que tenha sido definida no mesmo ficheiro
• Ex.: no exemplo anterior (ficheiro fonte Comp.java) a
compilação produziu os seguintes ficheiros
$>dir
01-09-2003
01-09-2003
01-09-2003
01-09-2003
01-09-2003
13:45
13:45
13:45
13:45
13:45
1.140 Comp.class
1.348 Comp.java
454 Disco.class
532 Memoria.class
621 Storage.class
• Um só ficheiro .java, mas um ficheiro .class por cada classe
definida
66
Package
• Cada classe pública precisa de ser definida num ficheiro
independente
• Se várias classes públicas precisarem de partilhar entre si
determinadas características o elemento de armazenamento
(isto é, o ficheiro), não é uma solução
• Para atender a essa funcionalidade existe, em Java, o
conceito de Package
• Várias classes podem pertencer à mesma package se antes da
declaração de classe incluírem a identificação da package
package <nomedapackage>;
67
Package (2)
• As packages tem uma estrutura hierárquica e
reflectem uma árvore de directórios onde as
classes são armazenadas
• Para se usar uma classe de uma package é
necessário importá-la
• Alternativamente pode-se usar o nome
completo da classe (qualified name)
68
Package (3)
• A ordem de declaração tem de obedecer a esta regra
Package <Nomedapackage>
[Import <Nomedapackageimportada>]
Classe* | Interfaces*
• Qualquer classe (ou interface) declarada sem package
pertence a uma package especial designada por “unnamed”
• O import vai buscar as classes a partir das subdirectórias
definidos em CLASSPATH
69
Package – Exemplo
Ex6\info\componentes\abstractos\Storage.java
package info.componentes.abstractos;
public class Storage{
private int cap = 16;
public void setCap(int c){cap = c;};
public int getCap(){return cap;}
public int getCar(){return 0;}
public String getCarUnits(){return "desconhecidas";}
}
info\componentes\Disco.java
package info.componentes;
import info.componentes.abstractos.Storage; //Só importa a classe Storage
public class Disco extends Storage {
private int rpm = 7800;
public int getCar(){return rpm;}
public String getCarUnits(){return "Rpm";}
}
info\componentes\Memoria.java
package info.componentes;
import info.componentes.abstractos.*; //Importa tudo o que estiver declarado nesta package
public class Memoria extends Storage {
private int vel = 233;
public int getCar(){return vel;}
public int getDataWidth(){return 64;}
70
public String getCarUnits(){return "Mhz";}
}
Package – Exemplo (2)
Ex6\info\Comp.java
//declaração da package
package info;
//importação das classes definidas na subpackage
import info.componentes.*;
//declaração dos tipos
public class Comp{
private Disco d;
private Memoria m;
Comp(){
d = new Disco();
m = new Memoria();
}
//Esta classe não foi previamente importada
public info.componentes.abstractos.Storage getStor(){
return m;
}
public static void main(String[] s){
Comp c = new Comp();
int cap = c.getStor().getCap();
System.out.println("capaciade (memoria) = " + cap);
}
}
71
Operador this
Operador this
• Refere-se ao próprio objecto
• auto-referência
• Pode ser usada nos:
• métodos não estáticos
• Construtores
• Serve para aceder aos campos membros quando há
variáveis locais ou argumentos com o mesmo nome
• Nos construtores serve ainda para invocar outros
construtores da mesma classe (polimorfismo)
73
Operador this – Exemplo
Ex16\Counter.java
public class Counter{
private int n = 0;
private String nome;
public Counter(String nome){
this.nome = nome;
//Sem o this o campo nome ficava inacessível por
//causa do nome do argumento ser igual ao nome do campo
}
public Counter(int n){
this.n = n;
}
public Counter(int n, String nome){
this(n);
//chama o construtor Counter(int n)
//O this(...) só pode ser usado na 1ª instrução; e esta tem
//de pertencer a um construtor
//this(nome); //ERRO! só pode ser usado uma vez
this.nome = nome;
}
public Counter(){
this(100,"sem nome");
}
Continua
74
Operador this – Exemplo (2)
Ex16\Counter.java (cont.)
public void print(){
// Aqui é desnecessário porque não há qualquer outra variável com
// o mesmo nome
System.out.println("n = " + this.n);
System.out.println("nome = " + this.nome);
}
static public void main(String[] s){
Counter c0 = new Counter(), c1 = new Counter(20);
Counter c2 = new Counter("C2");
Counter c3 = new Counter(50,"C3");
c0.print(); c1.print(); c2.print(); c3.print();
}
}
75
Operador super
Operador super
• Refere-se à superclasse
• É uma referência para os membros da superclasse do
objecto
• Serve para aceder aos membros da superclass quando há
sobreposição (nos campos e nos métodos)
• Nos construtores serve ainda para seleccionar e invocar os
construtores da superclasse
77
Operador super – Exemplo
Ex17\Counter.java
public class Counter{
private int n = 0;
protected String nome;
public Counter(String nome){this.nome = nome;}
public Counter(int n){this.n = n;}
public Counter(int n, String nome){
this(n);
this.nome = nome;
}
public Counter(){}
public void inc(){++n;}
public int getVal(){return n;}
public void reset(){n = 0;}
}
78
Operador super – Exemplo (2)
Ex17\ModCounter.java
public class ModCounter extends Counter {
public int n;
public void inc(){
super.inc();
// acede/invoca o inc de Counter
if (getVal() > n){reset();}
}
ModCounter(String nome, int i, int n){
//chama o construtor Counter(int,String)
super(i,nome); //O super(...) só pode ser usado na 1ª instrução; e esta
//tem de pertencer a um construtor
this.n = n;
}
ModCounter(int n){
this.n = n;
}
}
79
Modificadores
Modificadores
• Um modificador é uma keyword que afecta o tempo de
vida (lifetime) ou a acessibilidade de uma classe, variável
ou método.
81
Modificadores de acesso
Modificadores de acesso
• public, protected e private
• Recorrendo aos modificadores de acesso é possível
controlar quem tem acesso a uma classe ou aos respectivos
membros.
• Este modificadores são mutuamente exclusivos
• É desejável e aconselhável que o acesso se restrinja apenas
ao necessário
83
Modificadores de acesso – Classes
Modificador Quem tem acesso
<omisso>
Classes na mesma package
public
Universo – classes de todas as packages
• Uma classe declarada sem package que não tenha modificador de
acesso (<omisso>) fica acessível apenas pelas classes também elas
declaradas sem package.
• Só pode haver uma classe pública por ficheiro.
84
Modificadores de acesso – Membros
• O controlo de acesso dos membros funciona como um
encapsulamento, onde é possível controlar que membros
estão acessíveis/visíveis para o exterior da classe
• Cada classe deve declarar privado/protegido o que não precisa de
ser visto pelo exterior
• Do exterior só deve ser visível o estritamente necessário,
escondendo os pormenores de implementação
85
Modificadores de acesso – Membros
• Uma classe pode ter como membros
•
•
•
•
Campo
Método
Classe
Interface
• No caso de uma classe ou interface estas são consideradas
inner class e inner interface respectivamente.
• Os modificadores aplicam-se à inner class ou inner
interface da mesma forma que se aplicam a qualquer outro
membro.
86
Modificadores de acesso – Membros
Modificador Quem tem acesso
<omisso>
Classes na mesma package
public
Universo – classes de todas as packages
protected
Subclasses e classes na mesma package
private
Só dentro da própria classe
87
Modificadores de acesso – Exemplo
Ex7\info\componentes\abstractos\Storage.java
package info.componentes.abstractos;
public class Storage{
int cap = 16;
public int base = 2;
protected String origem = "Portugal";
public void setCap(int c){cap = c;}
public int getCap(){return cap;}
int getCar(){return 0;}
public String getCarUnits(){return "desconhecidas";}
}
Ex7\info\componentes\Memoria.java
package info.componentes;
import info.componentes.abstractos.*;
public class Memoria extends Storage {
private int vel = 233;
int getCar(){return vel;}
public int getDataWidth(){return 64;}
public String getCarUnits(){return "Mhz";}
public String getOrigem(){return origem;} //tem acesso a origem por herança
}
88
Modificadores de acesso – Exemplo (2)
Ex7\info\componentes\Teste.java
package info.componentes;
import info.componentes.abstractos.*;
public class Teste{
static public void main(String[] args){
Storage s = new Storage();
Memoria m = new Memoria();
System.out.println("s.base: "+s.base);
//System.out.println(s.cap);
//Erro: cap não apresenta modificador de acesso (<omisso>)
//System.out.println(s.origem);
//Erro: origem é um campo protegido de Storage
System.out.println("m.getOrigem(): "+m.getOrigem());
//OK: Memoria tem acesso ao campo origem porque é
//uma subclasse de Storage
//System.out.println(m.vel);
//Erro: vel é um campo privado de Memoria
System.out.println("getCar(): "+m.getCar());
//OK: o método getcar está acessível às classes da mesma package
}
}
89
Modificador static
Modificador static
• Só se aplica aos membros da classe
• Permite que o método/campo seja invocado/acedido sem
haver qualquer instância criada do objecto
• Aplica-se à classe e não a um objecto em particular
• Dito de outro modo, aplica-se às características comuns ao
conjunto de objectos deste tipo, presentes ou futuros.
• Um membro estático é partilhado por todos os objectos
91
Modificador static – Exemplo 1
Ex10\Comp3.java
public class Comp3 {
private int n;
static private int ncomp = 0;
public Comp3(){
n = ++ncomp;
}
static public int getNumOfInstances(){
//isto produz um erro de compilação
//return n;
return ncomp; //OK: ncom é um campo estático
}
public int getInstanceNumber(){return n;}
public String getInstancesRel(){
String s = "Instance " + n + " of "+ ncomp + " Instances";
//OK! Os membros não estáticos podem aceder a membros estáticos
return s;
}
}
92
Modificador static – Exemplo 1 (2)
Ex10\Test3.java
public class Test3 {
private static Comp3 c0, c1, c2;
public static void showAndCreate(Comp3 c){
int n = Comp3.getNumOfInstances();
print("N Of I (antes) = " + n);
c = new Comp3();
//int i = Comp3.getInstanceNumber();
//Erro: Um método não estático só pode ser invocado para um objecto
int i = c.getInstanceNumber();
//int n = c.getNumOfInstances;
//Erro: Um método estático só pode ser invocado para uma Class
print("Instance Number = " + i);
print(c.getInstancesRel());
}
public static void main(String[] args) {
showAndCreate(c0); showAndCreate(c1);
showAndCreate(c2);
}
private static void print(String s){
System.out.println(s);
}
}
93
Modificador static – Exemplo 2
Ex10a\Comp3.java
public class Comp{
private int n;
static private int ncomp = 0;
public Comp(){n = ++ncomp;}
public static void main(String[] s){
Comp c1 = new Comp();
c1.printn("c1."); c1.printncomp("c1.");
Comp c2 = new Comp();
c2.printn("c2."); c2.printncomp("c2.");
c1.printn("c1.");
c1.printncomp("c1.");
}
void printn(String s){System.out.println(s + "n = " + n);}
void printncomp(String s){
System.out.println(s + "ncomp = " + ncomp);
}
}
//O campo ncomp é partilhado por c1 e c2. Se c2 alterar ncomp essa alteração reflecte-se em c1
$>java Comp
c1.n = 1
c1.ncomp = 1
c2.n = 2
c2.ncomp = 2
94
c1.n = 1
c1.ncomp = 2
Modificador final
Modificador final
• Quando usado na declaração da classe esta não pode ser
derivada (superclasse)
• Quando usado num método este não pode ser sobreposto
• Usado da declaração de um campo este não pode ser
actualizado (mas deve ser inicializado)
• Usando em conjunto com o static serve para implementar
constantes
96
Modificador final – Exemplo
Ex18\Counter.java
final public class Counter{
private int n = 0;
final protected String nome;
//o campo nome tem de ser inicializado no construtor
final protected String ID = "a0"; //inicialização do campo
void serveParaNada(String lixo){
//nome = lixo; //um campo final não pode ser alterado
//ID = lixo; //a atribuição a um campo final dá sempre erro
}
public Counter(int n){
this.n = n;
/* dentro do construtor a inicialização é possível e,
* no caso do nome, necessária*/
nome = "sem nome";
//ID = "zero"; // Erro: ID já foi inicializado
}
public Counter(int n, String nome){
this(n);
//chamado outro construtor
//this.nome = nome;
//Erro: nome já foi inicializado
}
final public void inc(){++n;} //não pode ser sobreposto
}
97
Modificador final – Exemplo (2)
Ex18\ModCounter.java
final public class ModCounter extends Counter {
public int n;
//public void inc(){}//ERRO! o inc é um método final em Counter
ModCounter(String nome, int i, int n){
super(i,nome);
this.n = n;
}
ModCounter(int n){
super(0);
this.n = n;
}
}
//class ExtModCounter extends ModCounter{}
//Erro: ModCounter é final
98
Modificador abstract
Modificador abstract
• Permite indicar que uma classe não foi totalmente
implementada.
• Quando usado na declaração da classe esta não pode ser
instanciada
• Uma classe abstract não tem instâncias (objectos)
• Uma classe abstract tem de ser derivada
• Quando usado num método este tem de ser
obrigatoriamente sobreposto na subclasse
•
•
•
•
Não tem corpo
Só existe a sua declaração
A implementação é deixada para a subclasse
Implica que a classe também seja declarada como abstract
100
Modificador abstract – Exemplo
Ex19\Counter.java
abstract public class Counter{
protected int c = 0;
final protected String nome;
public Counter(int n){
c = n;
nome = "";
}
public Counter(int n, String nome){
c = n;
this.nome = nome;
}
abstract public void inc(); //inc() não tem corpo
public int getVal(){return c;}
}
101
Modificador abstract – Exemplo (2)
Ex19\ModCounter.java
abstract class AbsModCounter extends Counter {
public int n;
//public void inc(){} //não precisa de ser implementada nesta classe
AbsModCounter(String nome, int i, int n){
super(i,nome);
this.n = n;
}
}
public class ModCounter extends AbsModCounter{
//nesta class é obrigatorio implementar o método inc()
public void inc(){c = ++c % n; }
public ModCounter(String nome, int i, int n){super(nome,i,n);}
public static void main(){
Counter c;
//c = new Counter(0,"teste"); //Erro: Counter é abstract
//c = new AbsMoCounter("teste",0,16); //Erro
c = new ModCounter("teste",0,16);
c.inc();
System.out.println("c = " + c.getVal());
}
}
102
Inicialização dos Campos
Inicialização
• A inicialização dos campos membro pode ser feita
de 4 modos:
•
•
•
•
Omissão
Explícita
Blocos de inicialização
Construtor
104
Inicialização
• Inicialização por omissão
• Declarando apenas as variáveis estas são inicializadas pelo java de
acordo com a tabela anexa
Tipo
Valor inicial
númerico
0
booleano
false
referência
null
105
Inicialização
• Explícita
• Ao declarar o campo atribui-se-lhe um valor fixo ou o resultado de
uma expressão
• Blocos de inicialização
• O Java permite definir blocos de código como membros da classe.
Estes blocos são executados quando:
• a classe é carregada (blocos estáticos)
• o objecto é criado (blocos não estáticos)
• Construtor
• A inicialização é feita no corpo do construtor
106
Inicialização omissa – Exemplo
Ex12\Comp.java
public class Comp{
private int n;
private String nome;
static private int ncomp;
private boolean activo;
static public void main(String[] s){
System.out.println("ncomp = " + ncomp);
Comp c = new Comp();
System.out.println("n = " + c.n);
System.out.println("nome = " + c.nome);
System.out.println("activo = " + c.activo);
}
}
$>java Comp
ncomp = 0
n = 0
nome = null
activo = false
107
Inicialização explicita – Exemplo
Ex14\Comp.java
public class Comp{
//pode ser o valor de um método membro estático
private int n = initN();
//pode ser uma constante
private String nome = "madrinha precisa-se";
//pode ser uma expressão
static private int ncomp = 100 * 2;
static private int initN(){
return ++ncomp;
}
static public void main(String[] s){
System.out.println("ncomp = " + ncomp);
Comp c = new Comp();
System.out.println("n = " + c.n);
System.out.println("nome = " + c.nome);
}
}
108
Inicialização por bloco – Exemplo
Ex13\Comp.java
public class Comp{
private int n;
private String nome;
{//bloco de inicialização para cada objecto
nome = "madrinha precisa-se";
n = initN();
/* A inicialização pode ser feita recorrendo a
* métodos membro mas estes têm de ser estáticos*/
}
static private int ncomp;
static private int initN(){return ++ncomp;}
static { //bloco de inicialização para a class
ncomp = 100;
}
static public void main(String[] s){
System.out.println("ncomp = " + ncomp);
Comp c = new Comp();
System.out.println("n = " + c.n);
System.out.println("nome = " + c.nome);
}
}
109
Inicialização por Construtor – Exemplo
Ex15\comp.java
public class Comp{
private int n;
private String nome;
static private int ncomp;
public Comp(int x){
n = x;
nome = "Madrinha precisa-se";
}
static public void main(String[] s){
System.out.println("ncomp = " + ncomp);
Comp c = new Comp(5);
System.out.println("n = " + c.n);
System.out.println("nome = " + c.nome);
}
}
110
Interfaces
Interfaces
• Uma interface é um conjunto de requisitos para as classes
que quiserem ser conformes
• Uma interfaces consiste numa colecção de constantes e
declarações de métodos com as respectivas assinaturas
• Os métodos não têm corpo (são apenas declarados mas não
implementados)
• As interfaces fornecem um mecanismo para impor à(s)
classe(s) determinados métodos.
• Assegura que os objectos disponibilizam certos métodos sem
impor à partida qual a acção resultante
112
Interfaces (2)
• As interfaces são similares às classes mas:
• Os campos são sempre public static final
• Na declaração dos campos pode-se omitir estes modificadores
• Obriga à inicialização explicita
• Os métodos são sempre public abstract
• Na declaração dos métodos pode-se omitir estes modificadores
• Uma interface nunca tem instâncias (tal como uma classe
abstracta)
• Uma interface não tem construtores
113
Interfaces (3)
• A declaração de um interface obedece a esta regra:
<modificador>* interface <InterfaceName> {
[public final satic] <camposestaticosfinaispublicos>*
[public abstract] <membrossemcorpo>*
}
• Uma interface também pode herdar de outra interface:
<modificador>* interface <SubInterfaceName> [extends<SuperInterfaceName>]{
[public final static] <camposestaticosfinaispublicos>*
[public abstract] <membrossemcorpo>*
}
114
Interfaces – Exemplo
Ex20\SO.java
public interface SO{
String getName();
String getVersion();
//String getVersion2(){};
//SO(){}
String WIN = "Windows";
String UNIX = "Unix";
}
//os métodos são sempre public abstract
//Não tem corpo
//Erro: os métodos são abstractos
//Erro: as interfaces não tem construtores
//os campos são sempre public static final
//logo tem de ser inicialização explicita
Ex20\Unix.java
//uma interface pode herdar de outra
public interface Unix extends SO {
String LINUX = "Linux";
String HPUX = "HP-UX";
String AIX = "AIX";
String getVariante();
}
115
Interfaces (4)
• Uma interface é implementada numa ou mais classes
• Uma classe, não abstracta, que implemente uma interface
tem sempre de implementar todos os métodos da interface
• A declaração de implementação de uma interface é feita na
declaração da classe
<modificador>* class <SubClassName> [extends <SuperClassName>]
implements <InterfaceName1>, InterfaceName2,... {
<membros>*
}
116
Interfaces – Exemplo (2)
Ex20\Windows.java
public class Windows implements SO {
private final String version;
public String getName() {return WIN;}
public String getVersion() {return version;}
Windows(String v){version = v;}
}
Ex20\Dist.java
public interface Dist {
String REDHAT = "RedHat";
String MANDRAKE = "Mandrake";
String getDist();
}
Ex20\Linux.java
//Como a classe é abstracta, pode mas não precisa de implementar os métodos das interfaces
abstract public class Linux implements Unix, Dist{
protected final String kernelversion;
Linux(String k){kernelversion = k;}
// dois métodos implementados. Um de Unix e outro de SO
public String getName(){return UNIX;}
public String getVariante(){return LINUX;}
// As subclasses já só precisam de implementar os restantes métodos
117
}
Interfaces – Exemplo (3)
Ex20\Mandrake.java
public class Mandrake extends Linux {
private final String version;
public String getVersion(){
return "dv = "+version+"\nkv = "+kernelversion;
}
Mandrake(String v, String kv){
super(kv);
version = v;
}
public String getDist(){return MANDRAKE;}
}
•
A class Mandrake implementa implicitamente as interfaces Unix e Dist, logo
tem de implementar os métodos :
•
•
•
•
getName() e getVersion() de SO;
getVariante() de Unix;
getDist() de Dist;
Visto que a superclasse Linux já implementou os métodos getName() e
getVariante() aqui é suficiente definir o getVersion() e o getDist()
118
Interfaces – Teste do Exemplo
Ex20\Teste.java
public class Teste {
static void print(String s){System.out.println(s);}
static void showSO(SO so){
print(so.getName());
print(so.getVersion());
}
static void showUnix(Unix u){
showSO(u);
print(u.getVariante());
}
static void showDist(Linux l){
showUnix(l);
print(l.getDist());
}
public static void main(String[] args) {
Mandrake m = new Mandrake("8.2","2.4");
Windows w = new Windows("XP");
showDist(m);
print("-----------");
showSO(w);
}
}
$>java Teste
Unix
dv = 8.2
kv = 2.4
Linux
Mandrake
----------Windows
XP
119
Interfaces (4)
• Em Java a herança múltipla é conseguida com o recurso a
interfaces
public class Linux implements Unix, Dist
• Diferenças entre as interfaces e as classes abstractas
• As interfaces não podem ter:
•
•
•
•
Métodos estáticos
Construtores
Os métodos não podem ter implementação
Membros não públicos
• Um classe pode herdar de múltiplas interfaces mas não de
múltiplas classes abstractas
120
Excepções
Excepções
• As Excepções permitem definir o comportamento dos
métodos em circunstâncias excepcionais
• Ocorrendo uma excepção o código abandona o percurso
normal do método e salta para o código de tratamento da
excepção
método(){
try{
código onde não ocorreu qualquer excepção
código onde ocorreu a excepção E
código que não chegou a ser corrido
}catch (Excepção E){
código que vai tratar a excepção E
}
}
122
Excepções (2)
• O segmento de código onde podem ocorrer excepções é
delimitado pela construção
try{código onde podem ocorrer excepções}
• Para apanhar as excepções usa-se a construção
catch(Excepção E){código para tratar a excepção}
• É possivel ter vários “catches” para tratar diferentes tipos
de Excepções
try{código onde ocorrem diversas excepções}
catch(Excepção E) {código para tratar a excepção}
catch(Excepção F) {código para tratar a excepção}
catch(Excepção G) {código para tratar a excepção}
finally{este código é executado sempre quer haja ou não
excepções}
123
Excepções (3)
• Após uma excepção os diversos “catchs” são percorridos
por ordem até ser encontrado um com uma excepção do
tipo da ocorrida
• Depois de encontrar o “catch” respectivo os restantes são
ignorados
• Se F é uma subclasse de E então o “catch” do F deve ser incluído
antes do “catch” de E
• Uma instância de F é uma instância de E logo ao passar pelo
“catch” E a condição é verificada e o código de E executado
• Uma técnica para evitar multiplos “catchs“ é colocar um “catch”
de uma superclasse de todas as possíveis excepções Æ Perde-se o
tratamento especializado de cada excepção mas pode ser uma
opção em estágios preliminares de desenvolvimento
124
Excepções (4)
• O finally é opcional.
• O código do finally é sempre executado
• Mesmo que seja encontrado um return no código do try ou do
catch
125
Classes para excepções
Object
Throwable
Checked
Unchecked
Não são verificadas pelo compilador
A inexistência de código de tratamento não
gera erros na compilação
...
Error
RuntimeException
...
São verificadas pelo compilador.
A inexistência de código de tratamento gera erros na
compilação
NullPointerException
Exception
...
IOException
EOFException ...
SocketException
... BindException
126
Excepções (4)
• Uma excepção é gerada por disparo de um objecto
“throwable”
if (cond) throw new Exception()
• Uma excepção é sempre um objecto de uma subclasse da classe
throwable
• Normalmente da classe Exception ou das suas derivadas
127
Excepções (5)
• Na compilação as excepções dividem-se em dois tipos:
• Checked
• É verificado na compilação se há tratamento, ou redisparo destas
excepções
• Numa aplicação Java as excepções checked tem de ser sempre
tratadas
• Unchecked
• Não é verificado pelo compilador. O que não implica que em runtime
não seja possível dar lugar à paragem da aplicação
128
Excepções – Exemplo 1
Ex21\ModCounter.java
public class ModCounter{
private int c = 0;
private int n;
public void inc(){c = ++c % n; }
public ModCounter(int i, int n){
try{
if (i > n) throw new Exception(i + " > "+ n);
if (i < 0) throw new Exception(i + " < 0");
c = i;
this.n = n;
}
catch(Exception e){
e.printStackTrace();
}
}
public int getVal(){return c;}
public void setVal(int i) throws Exception{
if (i > n) throw new Exception(i + " > " + n);
c = i;
}
}
129
Excepções (6)
• Um método no qual podem ocorrer excepções checked tem
duas opções
• Ou faz o tratamento com try e catch
• Ou redispara as excepções, declarando no método quais as
Excepções que podem ocorrer
<modificadores> <tipo> <nomedometodo>(Args) throws
Exception1, Exception2,...{ ... }
• É da responsabilidade de quem chama o método fazer o tratamento
das excepções
• Um método pode tratar algumas excepções e (re)disparar
outras
• Um “catch” pode redisparar a mesma excepção
130
Excepções – Exemplo 2
Ex22\ModCounter.java
public class ModCounter{
private int c = 0;
private int n;
public void inc(){c = ++c % n; }
public ModCounter(int i, int n) throws InitException {
if (i > n) throw new InitException(i + " > " + n);
if (i < 0) throw new InitException(i + " < 0");
c = i;
this.n = n;
}
public int getVal(){return c;}
public void setVal(int i) throws ModException{
if (i > n) throw new ModException(i + " > " + n);
c = i;
}
}
131
Excepções – Exemplo 2 (2)
Ex22\InitException.java
public class InitException extends Exception {
public final String s;
public InitException(String a){
s = "Erro na inicialização:\n\t" + a;
}
}
Ex22\ModException.java
public class ModException extends Exception {
public ModException(String s){super(s);}
}
132
Excepções – Exemplo 2 (3)
Ex22\Teste.java
class NegativeException extends ModException {
NegativeException(String s){super(s);}
String getMoreInfo(){
return "Erro:\n\tO argumento do setVal”+ “ tem de ser positivo";
}
}
public class Teste{
static ModCounter c;
static void setVal(int v) throws ModException, NegativeException{
if (v < 0) throw new NegativeException( v + " < 0");
c.setVal(v);
}
public static void print(String s){
System.out.println(s);
}
public static void print(int n){
System.out.println(n);
}
Continua
133
Excepções – Exemplo 2 (4)
Ex22\Teste.java (cont.)
}
$>java Teste
Erro na inicialização:
20 > 16
finally: Por aqui passo sempre,haja ou não erro
public static void main(String[] s){
try{
c = new ModCounter(0,16);
c = new ModCounter(20,16);
//as linhas que se seguem não serão processadas devido à
//ocorrência de uma excepção do tipo InitException
setVal(7); print(c.getVal());
c.setVal(18);
print(c.getVal());
setVal(-10);
print(c.getVal());
return;
}catch (NegativeException te){
// o Negative Exception tem de surgir antes do ModException
print(te.getMoreInfo());
}catch (ModException me){
print ("ERRO: " + me.getMessage());
//O getMessage é membro da superclass Trowable
me.printStackTrace(); //O printStackTrace é membro da
}catch(InitException ie){
// superclass trowable
print(ie.s);
}finally{print("finally: Por aqui passo sempre, haja ou não erro");}
}
134
Classes do Java
Classes Java
Java API
Object
Class ...
String
...
...
Throwable
Excepion
Number
Character
...
Servlet
PrinterWriter
Subclasse2
Applet
Minhaclasse
Subclasse2
Math
...
System
...
Integer
Socket
PrinterStream
Outraclasse
InputStream
Classes do utilizador
Subclasse1
Qualquer classe é automaticamente subclasse de Object
136
API do Java
•
•
A utilização de qualquer classe das packages obriga a utilizar o import
No entanto a package java.lang não precisa de ser explicitamente “importada”
Package
Classes
java.lang
Classes “core” do Java
java.util
Classes e Interfaces utilitárias
java.math
Matemáticas
java.io
Entrada e Saída – acesso a ficheiros, etc
java.awt
GUI
javax.swing
GUI usando swing
java.applet
Creates applets
java.net
Classes para acesso aos protocolos de rede
Etc…
Ver a API do Java
137
API do Java
• http://java.sun.com/j2se/1.4.2/docs/api/index.html
138
Arrays
Arrays
• Os arrays em Java são objectos mas são manipulados de
forma especial pelo programador
• Declaração
int v[];
Ou
int[] v;
• Alocação de espaço (memória)
v = new int[n];
• n não precisa de ser uma constante. Pode ser uma variável ou uma
expressão
• Ou numa só instrução
int[] v = new int[n];
140
Arrays – Exemplo
Ex23\Test.java
public class Test{
public static void main(String[] s){
print(s);
}
private static void print(String[] s){
for (int n = 0; n < s.length; n++){
System.out.println("s["+n+"]="+s[n]);
}
}
}
$>java Test primeiro argumento e, julgo eu, o segundo argumento
s[0]=primeiro
s[1]=argumento
s[2]=e,
s[3]=julgo
s[4]=eu,
s[5]=o
s[6]=segundo
s[7]=argumento
141
Arrays
• Inicialização
v[2] = 3;
• Declaração, reserva de espaço e inicialização
int[] v = {3,7,6,8};
• Podem ser multidimensionais
int[][] vv={{1,3},{7,4,5}};
int[][] vw= new int[5][3];
• Um arrays de arrays pode conter arrays de dimensão diferente
• Pode-se declarar arrays de objectos
Obj[] ov = new Obj[4];
ov[2] = new Obj();
142
Arrays – Exemplo 2
Ex24\Test.java
public class Test{
public static void main(String[] s){
int[][] v = {{3,4},{5,3,8}};
for(int n = v.length; n-- > 0;)
for(int k = v[n].length; k-- > 0;)
print("v[" + n + "][" + k + "]=" + v[n][k]);
}
private static void print(String s){
System.out.println(s);
}
}
$>java Test
v[1][2]=8
v[1][1]=3
v[1][0]=5
v[0][1]=4
v[0][0]=3
143
Arrays – Exemplo 2
Ex25\Test.java
class MeuObjecto{
private int k;
private int n;
MeuObjecto(int a, int b){k = a; n = b;}
int getProd(){return n * k;}
}
public class Test{
public static void main(String[] s){
int n = 2, k = 3;
MeuObjecto[][] mov = new MeuObjecto[n][k];
while (n-- > 0){
int j = k;
while(j-- > 0)
mov[n][j] = new MeuObjecto(n+1,j+1);
}
while(k-- > 0) print(mov[1][k].getProd());
}
$>java Test
private static void print(int i){
6
4
System.out.println(i);
2
}
}
144
Arrays
• Os arrays são implementados internamente com objectos
de uma classe “built-in” (não listada na API Java)
• São subclasses de Object e herdam, naturalmente, todos os
membros deste
•
•
•
•
clone
equals
finalize
...
• Adiciona aos métodos de Object o campo final length
145
Strings
Strings
• As Strings são objectos definidos na classe
java.lang.String mas tem algumas particularidades não
partilhadas por outros objectos
• Podem ser inicializados sem recurso ao operador new
String s = “Esta é uma String”;
• Tem definida a operação de concatenação com o operador +
String s1 = s + “ concatenada”;
• Como objectos que são, as variáveis do tipo String são
referências
• O teste s == s1 compara se s e s1 se referem ao mesmo objecto e
não se as strings são iguais
147
Entrada/Saída
Classe File
• Usada para representar o sistema de ficheiros
• É apenas uma abstracção: a existência de um objecto File
não significa a existência de um ficheiro ou uma directoria.
• Contém métodos para testar a existência de ficheiros, para
definir permissões (nos S.O.s onde for aplicável), para
apagar ficheiros, criar directorias, listar o conteúdo de
directorias, etc..
149
Classe File (2)
• Alguns métodos
•
•
•
•
•
•
•
•
•
String getAbsolutePath()
String getParent(): devolve a directoria (objecto File) superior
boolean exists()
boolean isFile()
boolean isDirectory()
boolean delete(): tenta apagar a directoria ou ficheiro
long length(): devolve o tamanho do ficheiro em bytes
boolean mkdir(): cria uma directoria
String[] list(): lista dos ficheiros contido na directoria
150
Classe File – Exemplo
Ex26\Fileteste.java
import java.io.*;
public class FileTeste {
public static void main(String[] args){
try {
File directoria = new File("teste");
directoria.mkdir(); // cria, se possível
File ficheiro = new File(directoria, "lixo.txt");
FileOutputStream out= new FileOutputStream(ficheiro);
// se ficheiro não existe, tenta criar
out.write( new byte[]{'l','i','x','o'} );
//escrever uma sequência de bytes
out.close();
Continua
151
Classe File – Exemplo (2)
Ex26\Fileteste.java (cont.)
File subdir = new File(directoria, "subdir");
subdir.mkdir();
String[] ficheiros = directoria.list();
for (int i = 0; i<ficheiros.length; i++) {
File filho = new File(directoria, ficheiros[i]);
System.out.println(filho.getAbsolutePath());
}
if (ficheiro.exists()) {
ficheiro.delete();
}
} catch (IOException e){
System.exit(1);
}
}
}
152
Fluxos de Entrada/Saída
• Um fluxo (stream) é um conceito abstracto. Representa
uma sequencia linear de bytes ou caracteres de uma
entrada ou para uma saída.
• Existem várias fontes de onde se deseja ler ou destinos
para onde se deseja escrever ou enviar dados
•
•
•
•
Ficheiros
Conexões de rede
Consola (teclado / Monitor)
Memória
• Existem várias formas diferentes de ler/escrever dados
• Sequencialmente / aleatoriamente
• Como bytes / como caracteres
• Linha por linha / palavra por palavra, ...
153
Classes e Interfaces para fluxos de E/S
• A package java.io fornece objectos que abstraem
• fontes/destinos (nós) e fluxos de bytes e caracteres
• Dois grupos
• orientado ao byte: InputStream e OutputStream
• orientado ao caractere (char): Reader e Writer
154
E/S orientada ao byte
•
InputStream
• Classe abstracta para lidar com fluxos de bytes de entrada e nós de
fonte (dados para leitura).
• Método principal: read()
•
OutputStream
• Classe abstracta para lidar com fluxos de bytes de saída e nós de
destino (dados para gravação).
• Método principal: write()
155
E/S orientada ao byte (2)
• Principais implementações
• Entrada/leitura no nó fonte:
• FileInputStream (ficheiros),
• ByteArrayInputStream (memória) e
• PipedInputStream (pipe).
• Entrada/tratamento de fluxo:
• FilterInputStream (abstract) e respectivas subclasses
• Saída/escrita no nó destino:
• FileOutputStream (ficheiros),
• ByteArrayOutputStream (memória) e
• PipedOutputStream (pipe).
• Saída/tratamento de fluxo:
• FilterOutputStream (abstract) e respectivas subclasses.
156
E/S orientada ao byte – Exemplo
Ex27\FileCopia.java
import java.io.*;
//Esta aplicação copia um ficheiro: fonte -> destino
public class FileCopia {
public static void main(String[] args){
if (args.length>1){
try {
String nomeFonte = args[0];
String nomeDestino = args[1];
File fonte = new File(nomeFonte);
File destino = new File(nomeDestino);
if (fonte.exists() && !destino.exists()) {
FileInputStream in = new FileInputStream(fonte);
FileOutputStream out = new FileOutputStream(destino);
byte[] buffer = new byte[8192]; //array de bytes
int length = in.read(buffer);
while ( length != -1) { // -1 sinaliza o EOF
//grava apenas os bytes lidos e não o buffer completo
out.write(buffer, 0, length);
length = in.read(buffer);
}
Continua
157
E/S orientada ao byte – Exemplo (2)
Ex27\FileCopia.java (cont.)
in.close();
out.flush();
out.close();
}
} catch (IOException e){System.exit(1);} //é necessário tratar as excepções
} else {System.out.println("java FileCopia ffonte fdestino");}
}
}
158
FilterInputStream
• Recebe fonte de bytes e oferece métodos para ler dados
filtrados. Implementações (subclasses):
•
DataInputStream:
• readInt(),
• readUTF(),
• readDouble()
•
BufferredInputStream:
• read() mais eficiente
•
ObjectInputStream:
• readObject() lê objectos serializados
159
FilterOutputStream
• Recebe destino de bytes e escreve dados via filtro.
Implementações:
•
DataOutputStream:
• writeUTF(),
• writeInt(), etc.
•
BufferedOutputStream:
• write() mais eficiente
•
ObjectOutputStream:
• writeObject() serializa objectos
•
PrintStream:
• classe que implementa println()
160
E/S orientada ao caractere
•
Reader
• Classe abstracta para lidar com fluxos de caracteres de entrada:
método read() lê um caractere (16 bits) de cada vez.
•
Writer
• Classe abstracta para lidar com fluxos de caracteres de saída:
método write() grava um caractere de cada vez.
161
E/S orientada ao caractere (2)
• Principais implementações
• Entrada/leitura no nó fonte:
•
•
•
•
FileReader (ficheiro),
CharArrayReader (memória),
PipedReader (pipe) e
StringReader (memória).
• Entrada/tratamento de fluxo:
•
•
•
•
FilterReader (abstract),
BufferedReader,
InputStreamReader (conversor de byte para char),
LineNumberReader
162
E/S orientada ao caractere (3)
• Principais implementações (cont.)
• Saída/escrita no nó destino:
•
•
•
•
FileWriter (ficheiro),
CharArrayWriter (memória),
PipedWriter (pipe) e
StringWriter (memória).
• Saída/tratamento de fluxo:
•
•
•
•
FilterWriter (abstract),
BufferedWriter,
OutputStreamWriter (conversor de char para byte),
PrintWriter
163
E/S orientada ao caractere – Exemplo
Ex28\InputCmd.java
import java.io.*;
//permite ler da consola. Faz echo para o monitor daquilo que lê
public class InputCmd {
public static String readCmd(String inputMsg){
System.out.print(inputMsg);
//InputStream/byteÆInputStreamReader/charÆBufferedReader/char
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input = null;
try {
input = br.readLine(); // lê uma linha
} catch (IOException ioe) {
System.out.println("IO error trying to read from the cmd!");
System.exit(1);
}
return input;
}
public static void main (String[] args) {
String s = readCmd("Input: ");
System.out.println("Echo input: "+s);
}
}
164
Concorrência
Threads
• Threads Æ dividem o problema em tarefas independentes
• Threads vs. Processos
• Processos: tarefas em espaços de endereços diferentes que
comunicam entre si através de pipes fornecidos pelo S.O.
• Threads: tarefas dentro do espaço de endereços da aplicação que
comunicam entre si através de pipes fornecidos pela JVM
• Em Java o suporte de threads é nativo
• Um thread é um objecto que parece e age como um programa
individual.
166
Como criar um thread
• Há duas estratégias
• Herdar da classe java.lang.Thread
• Implementar a interface java.lang.Runnable
• Herdar da classe Thread
• O objecto é um thread, e sobrepõe o comportamento associado à
classe Thread
• Implementar a interface Runnable
• O objecto, que define o comportamento da execução, é passado para
um objecto Thread que o executa.
• Em ambos os casos
• É necessário sobrepor o método run() que é o "main()" do Thread
• A invocação do método start() inicia o thread (invoca run())
167
• Quando o método run() termina, o thread morre.
Criação de threads – Exemplo
Ex29\EstThread.java
class EThread extends Thread {
int n;
EThread(int i){n=i;}
public void run(){
for (int i=0; i<5;i++){
System.out.println("Thread"+n+": "+i);
try{ Thread.sleep(10); //10ms
} catch(InterruptedException e){System.exit(1);}
}
$>java EstThread
}
Thread1: 0
}
Thread2: 0
Thread1: 1
public class EstThread{
Thread2: 1
public static void main(String[] args){
Thread1: 2
EThread t1 = new EThread(1);
Thread2: 2
EThread t2 = new EThread(2);
Thread1: 3
t1.start();
Thread2: 3
t2.start();
Thread1: 4
}
Thread2: 4
}
168
Criação de threads – Exemplo 2
Ex29\ImpRunnable.java
class IThread implements Runnable {
int n;
IThread(int i){n=i;}
public void run(){
for (int i=0; i<5;i++){
System.out.println("Thread"+n+": "+i);
try{Thread.sleep(10); //10ms
} catch(InterruptedException e){System.exit(1);}
}
}
$>java impRunnable
}
Thread1: 0
Thread2: 0
public class ImpRunnable {
Thread1: 1
public static void main(String[] args){
Thread2: 1
IThread it1 = new IThread(1);
Thread1: 2
IThread it2 = new IThread(2);
Thread2: 2
Thread t1 = new Thread(it1);
Thread1: 3
Thread t2 = new Thread(it2);
Thread2: 3
t1.start();
Thread1: 4
t2.start();
Thread2: 4
}
}
169
Ciclo de vida de um thread
wait()
sleep()
I/O blocking
start()
Thread t =
new Thread()
run() acaba
(stop())
Executável
Bloqueado
notify()
sleep time-out
I/O acabou
run() acaba
(stop())
run() acaba
(stop())
Morto
170
Classe Thread
• Principais métodos:
• Estáticos
•
Thread currentThread()
• Devolve a referência para o thread que está a executar no momento
•
void sleep(long tempo)
• Coloca o thread bloquado durante pelo menos tempo ms.
•
void yield()
• Faz com que o thread atual pare e permita que outros que estão na sua
fila de prioridades executem.
171
Classe Thread (2)
• Principais métodos (cont.):
• De instância (não estáticos)
•
void run()
• É o "main()" do Thread. Deve ser implementado no Thread ou no
objecto Runnable passado ao thread
•
void start()
• É um bootstrap. Faz o JVM chamar o run()
•
boolean isAlive()
• Verifica se thread está vivo
172
Monitor
• Permite proteger os recursos impedindo que mais do que
um thread os utilize em simultâneo.
• Recorre-se à keyword synchronized
• Por questões de desempenho deve-se limitar a sua
aplicação ao essencial.
173
Monitor (2)
• Aplica-se a blocos ou métodos.
• por bloco:
synchronized (this){
<codigo protegido aqui>
}
• por método
synchronized <outros modificadores>* <tipo> <nome>(Arg*){
<codigo protegido aqui>
}
174
Sem Monitor – Exemplo
Ex30a\SemMonitor.java
$>java SemMonitor
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
- 1000, Saldo= -1000
+ 1000, Saldo= 0
class Utilizador extends Thread {
Conta conta;
Utilizador (Conta c){ conta=c; }
public void run(){
for (int i=0;i<5;i++) conta.movimentar();
}
}
class Conta {
private int saldo=0;
void movimentar(){ //o saldo nunca deve ser inferior a 0
if (saldo>=1000) {
try { Thread.sleep((long)(Math.random()*1000));
//adormece durante alguns ms
} catch (InterruptedException e){ System.exit(1);}
saldo-=1000;
//levantamento
System.out.println("- 1000, Saldo= "+saldo);
} else {
saldo+=1000;
//depósito
System.out.println("+ 1000, Saldo= "+saldo);
}
}
}
continua
175
Sem Monitor – Exemplo (2)
Ex30a\SemMonitor.java (cont.)
public class SemMonitor {
public static void main(String[] args){
Conta c = new Conta();
new Utilizador(c).start();
new Utilizador(c).start();
}
}
176
Com Monitor – Exemplo
Ex30b\CemMonitor.java
$>java SemMonitor
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
+ 1000, Saldo= 1000
- 1000, Saldo= 0
class Utilizador extends Thread {
Conta conta;
Utilizador (Conta c){ conta=c; }
public void run(){
for (int i=0;i<5;i++) conta.movimentar();
}
}
class Conta {
private int saldo=0;
synchronized void movimentar(){ //o saldo nunca deve ser inferior a 0
if (saldo>=1000) {
try { Thread.sleep((long)(Math.random()*1000));
//adormece durante alguns ms
} catch (InterruptedException e){ System.exit(1);}
saldo-=1000;
//levantamento
System.out.println("- 1000, Saldo= "+saldo);
} else {
saldo+=1000;
//depósito
System.out.println("+ 500, Saldo= "+saldo);
}
}
}
continua
177
Com Monitor – Exemplo (2)
Ex30b\SemMonitor.java (cont.)
public class ComMonitor {
public static void main(String[] args){
Conta c = new Conta();
new Utilizador(c).start();
new Utilizador(c).start();
}
}
178
Comunicações TCP/IP
Pilha Protocolar TCP/IP
•
Rede
• IP (Internet protocol)
• ICMP (Internet Control
Message Protocol)
• IGMP (Internet Group
Management Protocol)
•
Transporte
• TCP (transmission Control Protocol) (orientado à conexão)
• UDP (User datagram Protocol) (orientado ao datagrama)
• Exemplo de outros protocolos (não suportados pelo Java):
• SCTP (Stream Control Transmission Protocol) (orientado à conexão)
• DCCP (Datagram Congestion Control Protocol) (orientado ao datagrama)
•
Aplicação
• HTTP, SMTP, POP3, FTP, etc.
180
Modelos de distribuição de dados
• Unicast
• De um ponto para um outro ponto
• Endereço destino identifica/localiza ponto destino
Æ endereço unicast
• Multicast
• De um ponto para um grupo de pontos
• Endereço destino identifica o grupo destino
• Nós destino associam os seus endereços (unicast) ao grupo destino
• Broadcast
• De um ponto para todos os pontos
• Endereço destino corresponde a um endereço universal
correspondido por todos os nós
181
TCP
• Transmission Control Protocol
• Protocolo de transporte orientado à conexão
• Antes de começar a enviar dados é necessário proceder ao
estabelecimento da conexão
• Depois dados são enviados/recebidos sob a forma de um fluxo de
bytes
• Unicamente unicast
• Não existe um limite para o tamanho das mensagens a enviar.
• Fiável Æ Implementa mecanismo de recuperação de dados
• Modelo cliente/servidor Æ servidor fica à espera que o cliente
inicie o estabelecimento da conexão.
182
UDP
• User Datagram Protocol
• Protocolo de transporte orientado ao datagrama
• Cada mensagem é enviada num datagrama independente dos
(possíveis) restantes.
• Não é necessária qualquer sinalização prévia.
• Cada datagrama contém toda a informação necessária para a
correcta comunicação (portos origem e destino) Æ necessário
especificar/verificar aquando do envio/recepção de cada datagrama
• Pode ser utilizado em todos os modelos de distribuição.
• Tamanho das mensagens limitado a 64 kbytes (cabeçalho IP
incluído)
• Não é fiável Æ Não implementa mecanismos de recuperação de
datagramas
183
java.net
• TCP é suportado pelas classes
•
•
Socket (permite a comunicação através de uma conexão TCP)
SeverSocket (permite ao servidor ficar à escuta de pedidos de
conexão)
• UDP é suportado pelas classes
•
•
•
DatagramSocket (permite a comunicação via UDP)
DatagramPacket (datagrama UDP)
MulticastSocket (permite a comunicação via UDP em multicast)
• Endereçamento
•
•
InetAddress (representa um endereços IP)
URL (representa um URL e oferece um conjunto de operações
para comunicação)
184
Classe Socket
• Ponto de contacto entre a aplicação e a conexão TCP
• Principais construtores
•
•
Socket()
Socket(InetAddress address, int port)
• Cria um socket e conecta-o a um socket em address/port.
•
Socket(String host, int port)
• Cria um socket e conecta-o a um socket em host/port.
• Principais métodos servem para obter fluxos de entrada,
saída
•
•
getInputStream(), getOutputStream()
close()
• Depois de obtido os fluxos, basta ler ou escrever dados
como se de um ficheiro se tratasse.
185
Classe ServerSocket
• Permite a um servidor TCP ficar à escuta num dado porto
(local), até receber um pedido, para depois devolver um
socket que fica associado à nova conexão
• Principais contrutores
•
ServerSocket(int port)
• Fica à escuta em no porto port de todas as interfaces (endereços IP)
locais
•
ServerSocket(int port, int backlog,
InetAddress bindAddr)
• Fica à escuta no porto port do endereço bindAddr
• Principal método
•
accept()
• Aceita a conexão e devolve um socket para acesso à mesma
186
Cliente TCP – Exemplo
Ex31\ClienteTcpHttp.java
//Esta aplicação é um cliente TCP que faz o pedido de uma página a um servidor HTTP
import java.io.*;
import java.net.*;
public class ClienteTcpHttp {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try{
//cria o socket e associa-o a um endereço
socket = new Socket("www.google.com",80);
out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()), true);
in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Host desconhecido");
System.exit(1);
} catch (IOException e) {
System.out.println("Não foi possível estabelecer uma conexão");
System.exit(1);
}
187
Continua
Cliente TCP – Exemplo (2)
Ex31\ClienteTcpHttp.java (cont.)
//
envia ao servidor o pedido da página por omissão (index.html...)
out.println("GET / HTTP/1.1\r\n"); //não esquecer o \r\n
String resp="";
while ((resp = in.readLine()) != null) {
System.out.println(resp); //imprime a resposta do servidor
}
out.close(); //fecha os fluxos e depois o socket
in.close();
socket.close();
}
}
188
Servidor TCP – Exemplo
Ex32\EchoServer.java
//Esta aplicação é um servidor TCP que devolve o que recebe (faz echo)
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) throws IOException{
//fica associado ao porto local 3000
ServerSocket serverSocket = new ServerSocket(3000);
Socket clienteSocket=null;
try {
//fica à espera (escuta) de uma conexão
clienteSocket = serverSocket.accept();
//o socket para escuta é diferente do socket para a conexão
} catch (IOException e) {
System.out.println("O accept falhou");
System.exit(-1);
}
Continua
189
Servidor TCP – Exemplo (2)
Ex32\EchoServer.java (cont.)
PrintWriter out = null;
BufferedReader in = null;
out = new PrintWriter(new OutputStreamWriter(
clienteSocket.getOutputStream()), true);
in = new BufferedReader(new InputStreamReader(
clienteSocket.getInputStream()));
String str="";
while ((str = in.readLine()) != null) {
//quando recebe uma string do cliente imprime-a no monitor e
//deveolve-a (echo)
System.out.println(str);
out.println(str);
}
out.close(); //primeiro fecham-se os fluxos e só depois os sockets
in.close();
clienteSocket.close();
serverSocket.close();
}
}
190
Servidor TCP com threads
Exemplo
Ex37\EchoServerThread.java
import java.net.*;
import java.io.*;
class Connection extends Thread
{
private Socket clienteSocket;
static int stConNum=1;
int ConNum=stConNum++;
public Connection(Socket cliente) { clienteSocket = cliente; }
public void run() {
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(new OutputStreamWriter(
clienteSocket.getOutputStream()), true);
in = new BufferedReader(new
InputStreamReader(clienteSocket.getInputStream()));
while ((str = in.readLine()) != null) {
System.out.println("Con"+ConNum+": "+str);
out.println(str);
}
out.close(); in.close(); clienteSocket.close();
}catch (IOException ioe) { System.out.println(ioe);}
}
}
Continua
191
Servidor TCP com threads
Exemplo (2)
Ex37\EchoServerThread.java (cont.)
public class EchoServerThread
{
public static final int PORT = 3000;
public static void main(String[] args) throws IOException {
ServerSocket sock = null;
try {
sock = new ServerSocket(PORT);
while (true) {
//Fica à escuta de conexões. Cada nova conexão é servida
//num thread separado
Thread worker = new Connection(sock.accept());
worker.start();
}
}
catch (IOException ioe) {
System.out.println(ioe);
}
finally {
if (sock != null) sock.close();
}
}
}
192
Classe InetAddress
• Representa um endereço IP
• Principais métodos estáticos
•
getLocalHost()
• Devolve um objecto InetAddress com um endereço do host local
•
getByName(String hostname)
• Devolve um objecto InetAddress com o endereço do host cujo nome
é hostname
• Principais métodos de instância
•
getHostAddress()
• Devolve uma string com o IP do host a que o objecto InetAddress se
refere
•
getHostName()
• Devolve uma string com o nome do host a que o objecto
InetAddress se refere
193
Classe InetAddress – Exemplo
Ex34\ResLocalhost.java
import java.net.*;
//Para descobrir o IP e nome da máquina local
public class ResLocalhost {
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
String nome = address.getHostName();
System.out.println("O seu computador chama-se "+nome+" e tem o
endereço IP "+ip);
}
}
194
Classe DatagramSocket
• Representa o ponto de acesso para envio e recepção de
datagramas UDP (unicast e broadcast)
• Principais métodos constructores
•
DatagramSocket()
• Cria um socket e associa-o a um porto local livre (>1024)
•
DatagramSocket(int port)
• Cria um socket e associa-o ao porto local port.
•
DatagramSocket (int port, InetAddress addr)
• Cria um socket e associa-o ao porto local port e endereço local addr.
195
Classe DatagramSocket (2)
• Principais métodos servem para enviar e receber
datagramas
•
send(DatagramPacket p)
• Envia um datagram a partir deste socket.
•
receive(DatagramPacket p)
• Recebe um datagrama por este socket.
•
int getLocalPort()
• Devolve o porto local ao qual o socket está associado.
•
close()
• Fecha o socket.
196
Classe DatagramPacket
• Representa um datagrama UDP.
• Principais construtores:
•
DatagramPacket(byte[] buf, int length)
• Cria um datagrama para enviar e receber mensagens com um tamanho
máximo de length bytes.
•
DatagramPacket(byte[] buf, int length, InetAddress
address, int port)
• Cria um datagrama e inicializa-o com o par endereço/porto destino.
197
Classe DatagramPacket (2)
• Principais métodos :
•
InetAddress getAddress()
• Devolve o endereço do socket remoto.
•
void setAddress(InetAddress addr)
• Altera o endereço destino para addr.
•
int getPort()
• Devolve o porto do socket remoto.
•
void setPort(int port)
• Altera o porto destino para port
•
byte[] getData()
• Devolve a mensagem contida no datagrama.
•
void setData(byte[] buf)
• Copia a mensagem contida em buf para o datagrama.
198
UDP envio – Exemplo
Ex35\UDPSend.java
import java.io.*;
import java.net.*;
// Envia um pacote para uma aplicação UDP, neste caso no localhost, no porto 3000
public class UDPSend {
static final int port = 3000; //porto destino
static final String host = “localhost”; //host destino
public static void main(String args[]) throws Exception {
//Obtem o endereço do host destino
InetAddress address = InetAddress.getByName(host);
String msg = "Isto é um teste";
int msglen = msg.length();
//Converte a string para um array de bytes
byte[] message = msg.getBytes();
// inicializa o datagrama com os dados a enviar e os endereços
DatagramPacket packet = new DatagramPacket(message, msglen, address, port);
// Cria um socket e envia o datagrama através dele
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
}
}
199
UDP recepção – Exemplo
Ex35\UDPReceive.java
import java.io.*;
import java.net.*;
//Fica à espera de datagramas no porto 3000. Imprime qual a sua origem e qual o seu conteúdo
public class UDPReceive {
static final int port = 3000;
public static void main(String args[]) throws Exception {
byte[] buffer = new byte[1024];
DatagramSocket socket = new DatagramSocket(port); //fica à escuta no porto 3000
while(true) {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Espera pela chegada de um datagrama
socket.receive(packet);
// Converte o buffer de bytes para uma string através
// do contrutor: String(byte[] bytes, int offset, int length)
String s = new String(packet.getData(), 0, packet.getLength());
System.out.println("UDPReceive: received from "
+packet.getAddress().getHostName()+ ":" +packet.getPort()
+ ": " + s);
}
}
}
200
Classe MulticastSocket
• Representa o ponto de acesso para envio e recepção de
datagramas UDP em multicast
• IPv4: 224.0.0.0 a 239.255.255.255
• IPv6: endereços começados por FF
• Principais construtores:
•
MulticastSocket()
• Cria um socket UDP para multicast.
•
MulticastSocket(int port)
• Cria um socket UDP associado ao porto port para multicast.
201
Classe MulticastSocket (2)
• Principais métodos:
•
void joinGroup(InetAddress mcastaddr)
• Associa o socket a um grupo (endereço) multicast mcastaddr.
•
void leaveGroup(InetAddress mcastaddr)
• Sai do grupo multicast mcastaddr.
•
void setLoopbackMode(boolean disable)
• Inibe/permite o loopback de datagramas multicast.
•
void setTimeToLive(int ttl)
• Altera o valor do TTL.
202
Multicast envio – Exemplo
Ex36\MulticastSender.java
import java.net.*;
public class MulticastSender {
public static void main(String[] args) throws Exception{
String addr = "230.0.0.1"; //endereço multicast
int port = 6000; //porto destino
InetAddress group = InetAddress.getByName(addr);
String msg = "Aqui vai alguma coisa via multicast\r\n";
DatagramPacket dp = new DatagramPacket(msg.getBytes(), msg.length(), group, port);
MulticastSocket ms = new MulticastSocket();
ms.send(dp);
ms.close();
}
}
203
Multicast recepção – Exemplo
Ex36\MulticastReceiver.java
import java.net.*;
public class MulticastReceiver {
public static void main(String[] args) throws Exception {
int port = 6000;
String addr= "230.0.0.1";
InetAddress group = InetAddress.getByName(addr);
MulticastSocket ms = new MulticastSocket(port);
ms.joinGroup(group);
byte[] buffer = new byte[8192];
int c=0;
while(c++<10){
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ms.receive(dp);
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println(s);
}
ms.leaveGroup(group);
ms.close();
}
}
204
Classe URL
• Representa um Uniform Resource Locator
• Ex: http://www.google.pt:80/index.html
•
•
•
•
protocol: http
host: www.google.pt
port: 80 (porto por omissão associado ao http)
file: index.html (ficheiro por omissão)
• Principais contrutores
•
•
•
URL(String spec)
URL(String protocol, String host, String file)
URL(String protocol, String host, int port, String file)
205
Classe URL
• Principais métodos
•
openStream()
• Obtém um InputStream para os dados
•
openConnection()
• Devolve um objecto URLConnection que contém métodos para ler
o cabeçalho dos dados
•
getContent()
• Devolve os dados directamente como Object se conteúdo for
conhecido (texto, imagens, etc.)
206
Classe URL – Exemplo
Ex33\GetPag.java
import java.net.*;
import java.io.*;
public class GetPag {
public static void main(String[] args) throws IOException {
try {
URL url = new URL("http://www.google.com");
InputStreamReader reader = new InputStreamReader(url.openStream());
BufferedReader br = new BufferedReader(reader);
String linha = "";
while ( (linha = br.readLine()) != null) {
System.out.println(linha);
}
} catch (MalformedURLException e) { System.out.println("URL mal formado");}
}
}
207
Download