Elementi di JAVA
Tommaso Di Noia
[email protected]
Distribuzioni (java.com)
●
●
●
JSE (Java Standard Edition):
– Mette a disposizione un compilatore, vari tool per la
gestione del codice, un appletviewer ed un ricco set di
API per lo sviluppo di applicazioni e applet.
JEE (Java Enterprise Edition):
– Orientata allo sviluppo di applicazioni distribuite. Mette
a disposizione un insieme di semplici tool per la
gestione di un application server ed un semplice DBMS
(cloudscape) ed un ricco set di API per lo sviluppo di
servlet e di tutte le tecnologie che ruotano attorno ad
esse.
JME (Java Micro Edition):
– Un ambiente altamente ottimizzato per i dispositivi con
scarsa disponibilità di risorse hardware (smart card,
telefonini, palmari). Mette a disposizione un ricco set di
API per lo sviluppo di midlet ed alcuni tool di gestione
(tra i quali vari simulatori di dispositivi di telefonini).
Java Stack
Documentazione su java
Ambienti di sviluppo integrato (IDE):
●
●
●
NetBeans IDE
Eclipse
IntelliJ IDEA
Documentazione su tutte le librerie presenti
nelle distribuzioni:
●
Java Doc – documentazione in formato ipertestuale
http://docs.oracle.com/javase/7/docs/api/
Java - Caratteristiche
●
Portabile: non prevede aspetti dipendenti dalla
implementazione
es. le dimensioni dei tipi predefiniti sono fisse
●
●
●
●
Indipendente dall’architettura: il compilatore
genera un bytecode interpretabile in processori
diversi (Java è sia compilato che interpretato)
Robusto: il compilatore riscontra molti errori che in
altri linguaggi sono riscontrabili solo in esecuzione
Sicuro: è destinato all’uso in ambienti distribuiti e di
rete
Altamente versatile: grazie ad un ricco set di API è
possibile scrivere qualsiasi tipo di applicazione.
Il bytecode
file HW.java
public class HW {
public HW() {
}
public static void
main(String[] args)
{
file HW.class
compilatore
javac
codice sorgente
System.out.println(“
Hello, WORLD!");
}
bytecode
0 0:getstatic
#2 <Field
PrintStream System.out>
1 3:ldc1
#3 <String "Io ne
ho viste di cose che voi umani\n non
potreste nemmeno immaginarvi.">
2 5:invokevirtual #4 <Method
void PrintStream.println(String)>
3 8:return
}
Hello, WORLD!
interprete
java
Java Virtual Machine
In the Java programming language, all source code is first written in
plain text files ending with the .java extension. Those source files are
then compiled into .class files by the javac compiler.
A .class file contains bytecodes — the machine language of the Java
Virtual Machine (JVM).
The java launcher tool then runs your application with an instance of the
Java Virtual Machine.
http://docs.oracle.com/javase/tutorial/getStarted/intro/definition.html
Portabilità
Because the JVM is available on many different operating systems,
the same .class files are capable of running on Linux OS, Microsoft
Windows, Solaris OS or Mac OS.
http://docs.oracle.com/javase/tutorial/getStarted/intro/definition.html
Object-Oriented Programming
●
What Is an Object?
Software objects are conceptually similar to real-world objects: they
too consist of state and relative behavior. An object stores its state
in fields (variables in some programming languages) and exposes
its behavior through methods (functions in some programming
languages).
●
What Is a Class?
In the real world, you'll often find many individual objects all of the
same kind. The structure and behavior of an object are defined by a
class, which is a definition, or blueprint, of all objects of a specific
type. An object must be explicitly created based on a class and an
object thus created is considered to be an instance of that class.
OOP's benefits
●
●
●
●
Modularity: The source code for an object can be written and
maintained independently of the source code for other objects. Once
created, an object can be easily passed around inside the system.
Information-hiding: By interacting only with an object's methods,
the details of its internal implementation remain hidden from the
outside world.
Code re-use: If an object already exists, you can use that object in
your program.
Pluggability and debugging ease: If a particular object turns out to
be problematic, you can simply remove it from your application and
plug in a different object as its replacement.
Classi e Oggetti in java
●
Classe è l’unità fondamentale dei programmi
java
–
–
●
●
●
definisce la struttura degli oggetti
contiene campi e metodi
Creazione di un oggetto  creazione di
un’istanza della classe
Per ogni classe è possibile istanziare un
numero indefinito di oggetti
Sintassi per la creazione di un oggetto
●
NomeClasse oggetto = new CostruttoreClasse();
Metodo costruttore
Esempio: Persona.java
public class Persona {
String nome;
String cognome;
public Persona(String nome, String cognome)
{
this.nome = nome;
this.cognome = cognome;
}
public String getNomeCognome()
{
return this.nome + this.cognome;
}
}
Esempio: istanza di Persona
Persona pippo = new Persona(“Pippo”, “Super”);
String nomeCognome = pippo.getNomeCognome();
// nomeCognome adesso è “Pippo Super”
Metodi in java
●
Sintassi per definire un metodo
–
●
Sintassi per chiamare un metodo:
–
●
ModificatoreAccesso tipo_restituito nome_metodo (Lista argomenti)
{ // dichiarazioni e statement}
oggetto.metodo(argomenti)
Metodi costruttori
–
–
–
–
usati per inizializzare gli oggetti di una classe
new costruttore permette di creare un nuovo oggetto
nella classe
hanno lo stesso nome della classe
se il codice della classe non specifica alcun costruttore
java fornisce costruttori predefiniti - senza argomenti che inizializzano i valori a quelli predefinti
Esempio (1) :
Prima.java
public class Prima {
private String modificata;
private String originale;
public Prima(String org) {
originale = org;
modificata = originale+"QUESTA E' LA STRINGA
modificata";
System.out.println("E' stato creato un nuovo
oggetto appartenente alla classe Useless \n");
}
public void showModificata(){
System.out.println(modificata);
}
public void showOriginale(){
System.out.println(originale);
}
}
Esempio (2) :
UsaPrima.java
public class UsaPrima {
public UsaPrima() {
}
public static void main(String[] args) {
Prima oggetto1 = new Prima("primo
oggetto inutile creato \n");
oggetto1.showOriginale();
Prima oggetto2 = new Prima("secondo
oggetto inutile creato \n");
oggetto2.showModificata();
}
}
Esempio (3) : UsaPrima
java UsaPrima
UsaPrima oggetto1 = new UsaPrima("primo oggetto inutile creato\n");
oggetto1.showOriginale();
oggetto1:
Prima
originale = “primo oggetto
inutile creato \n”
E' stato creato un nuovo oggetto appartenente
alla classe Prima
primo oggetto inutile creato
Prima oggetto2 = new Prima("secondo oggetto inutile creato \n");
oggetto2.showModificata();
oggetto2:
Prima
originale = “secondo oggetto
inutile creato \n”
E' stato creato un nuovo oggetto appartenente
alla classe Prima
secondo oggetto inutile creato
QUESTA E' LA STRINGA modificata
Metodi in java
●
Sintassi per definire un metodo
modificatore_accesso tipo_restituito nome_metodo (Lista argomenti)
{
codice del metodo
}
Modificatori: private, public, e altri
Tipi: void, int, float, String, e altri
●
Sintassi per chiamare un metodo:
– oggetto.metodo(argomenti)
Metodi costruttori in java
●
Sintassi per definire un costruttore
modificatore_accesso nome_CLASSE (Lista argomenti)
{
codice del costruttore
}
Va definito con lo stesso nome della classe
Il valore di ritorno è l'indirizzo dell'oggetto che è stato
appena creato
Il costruttore si usa solitamente per inizializzare le
componenti degli oggetti
Esempio: Persona.java
public class Persona {
String nome;
String cognome;
public Persona()
{
}
public Persona(String nome, String cognome)
{
this.nome = nome;
this.cognome = cognome;
}
.
.
}
Esempio: Persona.java
public class Persona {
String nome;
String cognome;
Costruttore vuoto
public Persona()
{
}
public Persona(String nome, String cognome)
{
this.nome = nome;
this.cognome = cognome;
}
.
.
}
Costruttore con corpo
Gli Oggetti in Java (ed altri
particolari) (1)
●
●
A differenza di altri linguaggi di
programmazione orientati agli oggetti (es:
C++, SmallTalk, Object Pascal) in Java
l’allocazione degli oggetti è sempre
dinamica, tutto viene caricato nella
memoria heap.
Non esiste un metodo distruttore. Il
garbage collector della JVM si occupa di
distruggere gli oggetti che non sono più
referenziati. (La chiamata al garbage
collector può essere forzata dall’utente)
Gli Oggetti in Java (ed altri
particolari) (2)
●
Poiché non sono disponibili i puntatori
(croce e delizia di ogni programmatore)
per creare le strutture dati dinamiche
(alberi, liste, code,…) sono messe a
disposizione delle classi container che si
occupano di gestire tali strutture (List,
Map, Set).
–
Per gestire tali strutture esistono le classi
iterator che permettono di separare la
struttura dai metodi per accedervi.
I tipi e i Wrapper
●
int
Integer
●
byte
Byte
●
short
Short
●
long
Long
●
double
Double
●
float
Float
●
char
Char
●
boolean
Boolean
I tipi e i Wrapper
EsempioWrapper.java
Java PACKAGE
●
È possibile raggruppare gruppi di classi in
raccolte per organizzare il codice.
–
●
●
Può essere visto come l’equivalente di una libreria negli
altri linguaggi di programmazione (C, Pascal, …)
Il nome del package rispetta la struttura del
file system (directory e subdirectory)
I package possono essere raggruppati in
file compressi (.zip, .jar). Tali file devono
rispettare al loro interno la gerarchia delle
directory.
Java PACKAGE. Ex.
PACKAGE: java.awt
Classi apparteneti a
java.awt
PACKAGE: javax.swing
Classi apparteneti a
javax.swing
La variabile d’ambiente
CLASSPATH (1)
•
E’ una variabile di sistema che specifica
dove è possibile collocare le classi.
1. In fase di compilazione indica le classi,
appartenenti a package esterni, che si
vogliono importare.
2. In fase di esecuzione indica dove è
possibile posizionare le classi che devono
essere utilizzate.
• OSS. La variabile CLASSPATH deve:
– sempre indicare la directory nella quale è
installata la JDK
– Puntare alla directory di livello direttamente
superiore a quella indicante un package che si
intende utilizzare.
Importare un package. Ex.
import java.net.*;
public class WhoAmI {
public static void main(String[] args) throws Exception {
if(args.length != 1) {
System.err.println(
"Usage: WhoAmI MachineName");
System.exit(1);
}
InetAddress a = InetAddress.getByName(args[0]);
System.out.println(a.getHostAddress());
}
}
La classe InetAddress appartiene al package java.net.
Se tale package non fosse stato importato avremmo potuto
scrivere in maniera equivalente:
java.net.InetAddress a =
java.net.InetAddress.getByName(args[0]);
Creare un package Ex.
FILE Useless.java
package use;
public class Useless {
private String modificata;
public String originale;
public Useless(String org) {
…
}
FILE UseUseless.java
package use;
public class UseUseless {
public UseUseless() {
}
…
}
I due file
devono
trovarsi
nella
directory
use
Modificatori d'accesso
• public : elementi (metodi, attributi) visibili
dall’esterno e “applicabili” all’oggetto che istanzia la
classe.
• private : elementi non visibili dall’esterno. Possono
essere occupati solo all’interno della stessa classe.
• static : elementi che appartengono alla classe, non
all’oggetto che la istanzia. Tutte le istanze della
classe condividono un’unica copia del campo.
–
Ex.:
• System.out  out è un campo statico della classe System
• double x = Math.pow(3,0.1)  pow è un metodo statico della classe Math
●
Se non è specificato nessun modificatore, i metodi
sono visibili solo all’interno del package.
public & private. Ex.
public class Prima {
private String modificata;
public String originale;
public Prima(String org) {
…
●
●
public class UsaPrima2 {
…
public static void main(String[] args)
{
Prima oggetto1 = new Prima(
"primo oggetto inutile creato“
);
…
System.out.println(oggetto1.originale);
La variabile modificata è
dichiarata di tipo private
La variabile originale è
dichiarata di tipo public
GIUSTO
System.out.println(oggetto1.modificata)
;
…
}
}
SBAGLIATO
viene segnalato come
errore in fase di
compilazione
Ereditarietà (1)
●
Utilizzando la parola chiave extends è
possibile creare delle sotto-classi di una
classe padre.
–
–
la parte dichiarata come public nella classe
Padre viene ereditata dalla classe Figlio e
diventa parte integrante della sezione public
della nuova classe creata.
la parte dichiarata come private nella classe
Padre non viene ereditata. Resta una
“esclusiva” della classe Padre.
Ereditarietà. Ex.1
public class FiglioPrima extends Prima {
private String messaggio;
public String utilizzabile;
public FiglioPrima (String msg) {
super(msg);
System.out.println(“Questo è il valore passato
al costruttore di FiglioPrima” + msg);
messaggio = msg;
}
public void showChild(int i){
for(int j=0; j<i; j++){
System.out.println(“Ripetizione di ”+
messaggio + “ numero ” + j);
}
}
}
Ereditarietà. Ex.1
package persona;
public class Lavoratore extends Persona {
String lavoro = "disoccupato";
public Lavoratore(String lavoro)
{
this.lavoro = lavoro;
}
public Lavoratore(String nome, String cognome, String lavoro)
{
super(nome, cognome);
this.lavoro = lavoro;
}
public String getLavoro()
{
return lavoro;
}
public void setLavoro(String lavoro)
{
this.lavoro = lavoro;
}
}
Ereditarietà – costruttori
●
Ogni costruttore di una sotto-classe deve
chiamare il costruttore della super-classe.
–
●
Il passaggio dei parametri alla classe padre
avviene con la chiamata
super(lista di parametri)
Se non viene fatta una chiamata esplicita
al costruttore, viene richiamato il
costruttore di default.
Ereditarietà. Ex.2 (1)
public class UsaFiglioPrima {
public UsaFiglioPrima() {
}
public static void main(String[] args) {
FiglioPrima child1 = new FiglioPrima(
"primo figlio inutile creato \n");
child1.showOriginale();
FiglioPrima child2 = new FiglioPrima(
“secondo figlio inutile creato \n");
child2.showModificata();
child1.showChild(10);
child2.showChild(3);
}
}
Ereditarietà. Ex.2 (2)
public class UsaFiglioPrima {
public UsaFiglioPrima() {
}
public static void main(String[] args) {
FiglioPrima child1 = new FiglioPrima(
"primo figlio inutile creato \n");
child1.showOriginale();
FiglioPrima child2 = new FiglioPrima(
“secondo figlio inutile creato \n");
child2.showModificata();
child1.showChild(10);
child2.showChild(3);
}
Metodi ereditati dalla
}
Metodi propri della
classe FiglioPrima
classe padre Prima
Esempio - UsaFiglioPrima
E' stato creato un nuovo oggetto appartenente
Valore passato al costruttore di FiglioPrima:
primo figlio inutile creato
E' stato creato un nuovo oggetto appartenente
Valore passato al costruttore di FiglioPrima:
secondo figlio inutile creato
QUESTA E' LA STRINGA modificata
Ripetizione di primo figlio inutile creato
numero 0
Ripetizione di primo figlio inutile creato
numero 1
Ripetizione di primo figlio inutile creato
numero 2
Ripetizione di primo figlio inutile creato
numero 3
Ripetizione di primo figlio inutile creato
numero 4
Ripetizione di primo figlio inutile creato
numero 5
Ripetizione di primo figlio inutile creato
numero 6
Ripetizione di primo figlio inutile creato
numero 7
Ripetizione di primo figlio inutile creato
numero 8
Ripetizione di primo figlio inutile creato
numero 9
Ripetizione di secondo figlio inutile creato
numero 0
Ripetizione di secondo figlio inutile creato
numero 1
Ripetizione di secondo figlio inutile creato
numero 2
alla classe Prima
primo figlio inutile creato
alla classe Prima
secondo figlio inutile creato
FiglioPrima child1 = new FiglioPrima(
"primo figlio inutile creato \n");
child2.showModificata();
child1.showChild(10);
child2.showChild(3);
Interfacce (1)
•
●
Le interfacce permettono di gestire e controllare gli oggetti in
maniera più sofisticata [Bruce Eckel]
Una classe potrebbe trovarsi nella condizione di dover
ereditare metodi provenienti da diverse super-classi
–
●
In Java non è possibile avere più di una super-classe. Non è
permesso dal linguaggio.
–
●
●
●
●
Si potrebbe presentare la necessità di trovarsi nel caso di
ereditarietà multipla.
Le motivazioni sono da ricercarsi nella elevata complessità ed a
volte inefficienza dei compilatori che gestiscono la ereditarietà
multipla.
Le interfacce permettono di “raggruppare” i metodi.
Contengono solo le firme dei metodi.
Una classe può implementare più interfacce (proprio perché
ci sono solo le firme dei metodi, non l’implementazione)
Se una classe implementa una interfaccia “promette” che
implementerà tale metodo.
Interfacce (2)
●
Le interfacce possono essere utilizzate da una
classe con la keyword implements.
public class NomeClasse implements NomeInterfaccia
●
●
●
Tutte le classi che implementano una interfaccia
devono implementare i metodi in essa presenti.
Se una classe implementa una interfaccia,
“promette” al compilatore che implementerà tali
metodi.
OSS: Come per le classi, il file che contiene
l’interfaccia ha lo stesso nome dell’interfaccia
stessa.
Creare una Interfaccia Ex.
MonsterActions.java
public interface MonsterActions {
void menace();
void destroy();
String chat(String sentence);
}
DragonActions.java
public interface DragonActions {
Flame spit();
void fly();
}
Implementare una Interfaccia
Ex. (1)
class Ogre implements MonsterActions {
…
public Ogre(String breed){
…
}
public void menace(){
…
}
public void destroy(){
…
}
public String chat(String sentence){
return “BURP!”;
}
}
Implementare una Interfaccia
Ex. (2)
class FrenchDragon implements MonsterActions, DragonActions{
…
public FrenchDragon(Color clr){
…
}
public void menace(){
…
}
public void destroy(){
…
}
public String chat(String sentence){
return sentence.replace(‘r’, ‘v’);
}
public Flame split(){
…
}
public void fly(){
…
}
}
Polimorfismo
• Con il polimorfismo è possibile separare il
cosa dal come. [Bruce Eckel]
●
Permette di dare più forme ad uno stesso
metodo.
●
E’ possibile ridefinire il comportamento di
un metodo mantenendo la stessa firma
(overriding)
●
E’ possibile dare una firma diversa, e
quindi anche un comportamento, ad un
metodo mantenendo lo stesso nome
(overloading)
Polimorfismo
• Con il polimorfismo è possibile separare il cosa
dal come. [Bruce Eckel]
●
Permette di dare più forme ad uno stesso
metodo.
●
E’ possibile ridefinire il comportamento di un
metodo mantenendo la stessa firma
(overriding)
●
E’ possibile dare una firma diversa, e quindi
anche un comportamento, ad un metodo
mantenendo lo stesso nome (overloading)
Overriding
●
●
In una sotto-classe, viene ridefinito un
metodo già implementato nella
super-classe.
Dal lato del compilatore, nel caso di
metodo overrided, viene sempre preso in
considerazione quello appartenente alla
classe gerarchicamente più interna.
Overriding Ex.
Shape
public Shape draw(Point[] coord)
public Shape move(Point displacement)
for(i=o; i<points.length; i++){
points[i].x += displacement.x;
points[i].y += displacement.y;
}
Circle
public Shape move(Point displacement)
center.x += displacement.x;
center.y += displacement.y;
Overloading
●
●
●
●
Vengono definiti metodi con lo stesso nome
ma firma diversa.
In una sotto-classe può essere ridefinito un
metodo già presente nella super-classe
All’interno di una stessa classe si possono
avere più overload dello stesso metodo.
Dal lato del compilatore, il metodo con la
firma specificata viene prima ricercato nella
classe a cui appartiene l’oggetto che lo
richiama, e se non presente nelle sue
super-classi.
Oveloading Ex. (1)
Shape
public Shape draw(Point[] coord)
public Shape move(Point displacement)
public Shape rotate(double rad_angle)
Circle
public Shape move(Point displacement)
public Circle rotate()
Oveloading Ex. (2)
Shape
public Shape draw(Point[] coord)
public Shape move(Point displacement)
public Shape rotate(double rad_angle )
public Shape rotate(int deg_angle )
L'interfaccia Cloneable (1)
class TestClone implements Cloneable {
int a;
double b;
TestClone cloneTest() {
try {
return (TestClone) super.clone();
}
catch(CloneNotSupportedException e) {
System.out.println("Clonaggio non permesso");
return this;
}
}
}
class CloneDemo {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
x2 = x1.cloneTest(); // clone x1
System.out.println("x1: " + x1.a + " " + x1.b);
System.out.println("x2: " + x2.a + " " + x2.b);
}
}
L'interfaccia Cloneable (2)
class TestClone implements Cloneable {
int a;
double b;
public Object clone() {
try {
return super.clone();
}
catch(CloneNotSupportedException e) {
System.out.println("Clonaggio non permesso");
return this;
}
}
}
class CloneDemo2 {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
x2 = (TestClone) x1.clone();
System.out.println("x1: " + x1.a + " " + x1.b);
System.out.println("x2: " + x2.a + " " + x2.b);
}
}
Le eccezioni
●
●
●
Un’eccezione indica che si è verificato un errore
durante l’esecuzione di un programma.
Il sistema di gestione delle eccezioni in Java è
basato sull’assunzione che il metodo che si
accorge dell’errore non è in grado di gestirlo, ma
lancia (throw) un’eccezione.
Ci può essere un’altra porzione di codice che
cattura(catch) l’eccezione e la gestisce.
Blocco try-catch
●
●
●
Si racchiude in un blocco try il codice che può
lanciare eccezioni.
Ci possono essere uno o più blocchi catch,
che specificano il tipo di eccezione che
possono gestire e contengono il codice per
gestirla.
Ci può essere un blocco finally che viene
sempre eseguito, indipendentemente dal
verificarsi dell’eccezione.
Esempio
try {
int n = a/b;
}
catch(ArithmeticException e) {
System.out.println(“Errore: divisione per
zero.”);
}
Lanciare un'eccezione
●
●
●
Quando, in un proprio metodo, si vuole lanciare
un’eccezione, si usa la keyword throw, seguita da un
oggetto di una classe derivata da Throwable.
Quando un’eccezione viene lanciata, il controllo esce
dal blocco try e passa alla prima clausola catch.
I metodi che possono lanciare eccezioni, devono
dichiararlo esplicitamente nella loro signature, usando
la keyword throws, seguita dalla classe di eccezione
che possono lanciare.
Esempio di throw
public class DivideByZeroException extend
ArithmeticException{
};
public DivideByZeroException(){
super(“Tentativo di divisione per zero.”);
}
__________________________________________________
public double quoziente(double num,double den)
throws DivideByZeroException{
if(den == 0){
throw new DivideByZeroException();
}
return num / den;
}
Ancora sulle eccezioni
●
Checked e Unchecked exception
EccezioniDemo.java
●
Stack delle eccezioni
StackEccezioni.java
Multi-threading
●
●
●
●
Un thread è un singolo flusso sequenziale
di controllo all'interno di un processo.
Un singolo processo può avere diversi
thread eseguiti in maniera concorrente.
Ci sono molti usi possibli dei thread. In
generale si usano quando non vogliamo
che il flusso di esecuzione di un programma
resti bloccato fino al termine di un evento o
al rilascio di una risorsa(Es. Web crawling).
Creiamo un thread associato a quell'evento
o a quella risorsa e lo facciamo eseguire in
maniera indipendente dal resto del
programma.
Multi-threading in Java (1)
●
●
●
Il modo più semplice per creare un Thread è quello
di estendere la classe java.lang.Thread
Il metodo più importante per la classe Thread è
run(), che va sovrascritto per farlo comportare
esattamente come vogliamo.
run( ) contiente il codice che sarà eseguito
“simultaneamente” con gli altri thread in un
programma.
Multi-threading in Java (2)
●
●
Il metodo start( ) nella classe Thread
esegue delle operazioni di inizializzazione
per il thread e poi chiama run( ).
Quindi i passi da eseguire sono:
●
●
●
●
il costruttore è invocato per costruire
l'oggetto;
successivamente chiama il metodo start( )
per configurare il thread;
il meccanismo di esecuzione del thread
chiama run( ).
Se non richiamiamo start( ) sull'oggetto, il
thread non partirà mai
Esempio (1)
public void run() {
int count = (int)Math.round(Math.random()*1000);
while(true) {
System.out.println(count);
if(--count==0)
return;
}
}
Multi-threading in Java (2)
●
●
●
Se sappiamo di aver eseguito quello che
era necessario fare nel nostro metodo
run(), possiamo mandare un segnale allo
scheduler dei thread ed avvisarlo che un
altro thread può essere eseguito.
Questo segnale prende la forma del
metodo yield( )
Un altro modo in cui è possibile controllare i
comportamento dei thread è attraverso la
chiamata del metodo sleep( ) per un certo
numero di millisecondi.
Esempio (2)
public void run() {
int count = (int)Math.round(Math.random()*1000);
while(true) {
System.out.println(count);
if(--count>=10)
yield();
else
return;
}
}
Esempio (3)
public void run() {
int count = (int)Math.round(Math.random()*1000);
while(true) {
System.out.println(count);
if(--count <= 10)
return;
try {
sleep(100);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Multi-threading in Java (3)
●
●
La priorità di un thread avvisa lo
scheduler di quanto è importante il thread.
Le prioritò possono essere impostate
usando il metodo setPriority( ) della
classe Thread.
Mluti-threading in Java (3)
●
●
●
In Java non è possibile implementare
l'ereditarietà multipla
Come fare se una classe è già
sotto-classe di un'altra?
L'interfaccia Runnable
I/O
●
●
●
InputStream e OutputStream (sottoclassi
di Object) definiscono i metodi per le
operazioni di I/O basate su byte
L'I/O su file è fatto per mezzo delle classi
FileInputStream e FileOutputStream.
È possibile bufferizzare l'input e l'output
attraverso le classi BufferedInputStream e
BufferedOutputStream.
I/O
●
●
●
Reader e Writer servono per la gestione
di flussi di caratteri.
BufferedReader e BufferedWriter sono la
loro versione bufferizzata.
FileReader e FileWriter leggono e
scrivono su file.
La classe File
●
Quattro costruttori:
–
public File(String nome)
–
public File(String path, String nome)
–
public File(File directory, String nome)
–
public File(URI uri)
Esempio di lettura da file
EsempioLetturaDaFile.java
EsempioIOcompleto.java
Strutture dati
●
●
●
In java non ci sono i puntatori
Necessità di struttura dinamiche (liste,
alberi,...)
Definizione di Nodo
Nodo di una lista
public class Nodo {
private Object data; private Nodo nextNode;
public Nodo( );
public Nodo( Object object );
public Nodo( Object object, Nodo node );
public Object getData();
public void setData(Object data)
public Nodo getNext();
public void setNext( Node next );
}
Lista
Lista.java
Classi utili per la manipolazione
dei dati
●
Vector (EsempioVector.java)
●
Stack
●
Hashtable (EsempioHashtable.java)
●
Properties
(EsempioScritturaFileProperty.java
EsempioLetturaFileProperty.java)
La programmazione generica
●
●
●
Per le strutture dati (ArrayList, Vector,
Map, Hashmap, etc) tutti gli oggetti
vengono considerati di tipo Object
Questo potrebbe creare dei problemi in
caso di manipolazione degli elementi
Con la programmazione generica questi
problemi vengono superati
La programmazione generica
EsempioVectorGenerics.java
EsempioHashtableGenerics.java
Coppia.java
Database e JDBC
●
●
●
●
JDBC e' composto da varie classi che "cooperano" per fornire
l'accesso ai dati del database.
In prima linea viene il Driver, che interpreta tutte le funzioni
richiamate e le 'traduce' per il database, il Driver deve essere
caricato in memoria, una volta fatto questo è possibile utilizzarne le
funzioni per creare una Connection, che incapsula il vero e proprio
collegamento al database. Una Connection è necessaria per poter
fare qualunque altra cosa.
Una volta ottenuta la Connection siamo in grado di usare
quest'ultima per produrre Statement, che verranno a loro volta usati
per ottenere ResultSet, i quali contengono i dati.
Non è sempre necessario l'uso di un ResultSet. Se vogliamo
semplicemente eseguire delle modifiche sui dati (usando una
UPDATE, INSERT o DELETE), possiamo usare il metodo
executeUpdate() direttamente sullo Statement.
Database e JDBC
DatabaseUtil.java
EsempioUsaDB.java
Elementi di programmazione
grafica
●
Per mantenere la “promessa” di
indipendenza dalla piattaforma, una
applicazione Java, che presenta una
Graphical User Interface, deve poter
essere eseguita su piattaforme diverse
senza dover modificare nulla nel
bytecode.
AWT
●
●
●
●
AWT (Abstract Window Toolkit) è stata la prima libreria
di classi presente in Java per la gestione di elementi
grafici.
Gestisce gli elementi grafici, delegandone la creazione
e il comportamento alla piattaforma su cui sta girando
l’applicazione.
Vengono gestiti gli elementi propri della piattaforma
(peer).
PROBLEMI di portabilità
–
gli elementi grafici nativi delle diverse piattaforme hanno
comportamenti differenti.
–
alcune piattaforme possono essere più ricche di
componenti di altre
SWING
●
●
Con la libreria di classi Swing, tutti gli elementi vengono
“dipinti” all’interno delle finestre create.
L’unica funzionalità peer richiesta è la modalità di costruzione
di una finestra ed il modo in cui disegnare in essa.
●
Eredità alcune funzionalità di AWT.
●
PROBLEMI:
–
●
L’esecuzione di una applicazione che utilizza una interfaccia
Swing è molto più “pesante”.
OSS: Nel seguito si farà riferimento alle classi Swing per la
costruzione degli elementi grafici.
JFrame
●
●
●
Finestra top-level. Ossia una finestra non
contenuta in altre finestre.
E’ uno dei pochi elementi non disegnati.
Le decorazioni (pulsanti, barra del titolo,
icone, …) non sono disegnata da Swing
ma dal sistema di gestione delle finestre
proprio della piattaforma.
Jframe Ex.
import javax.swing.*;
import java.awt.*;
public class JustAFrame extends JFrame{
public JustAFrame(){
super();
System.out.println("Creazione di
JustAFrame");
setTitle("Semplice Frame");
Image icn = Toolkit.getDefaultToolkit().getImage("dee3.jpg");
setIconImage(icn);
}
public static void main(String[] args){
JustAFrame jaf = new JustAFrame();
jaf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
jaf.setVisible(true);
}
}
Altri elementi di SWING
• JButton
• JFileChooser
• JLabel
• JPanel
• JScrollPane
• JTextArea
• JTextField
• JToolTip
Gerarchia degli elementi grafici
Object
Component
Container
JComponent
Window
Frame
JToolTip
JPanel
JButton
JFrame
Disegnare i componenti in un
JFrame
…
Container cp = getContentPane();
JButton but = new JButton();
cp.add(but);
…
Un Frame è strutturato in più “pannelli”
Nel pannello dei contenuti - ContentPane –
vengono disegnati i vari componenti
Layout
Permettono di impostare il posizionamento
dei componenti grafici all’interno del
Container (per esempio un JFrame o un
JPanel).
FlowLayout
I componenti all’interno del contenitore vengono aggiunti
orizzontalmente fino a quando non c’è più spazio.
Dopo di che viene iniziata una nuova riga
BorderLayout
Il Container viene diviso in cinque aree:
North, South, East, West, Center
Semplice esempio di interfaccia
NoEventFrame.java
NoEventFrame2.java
Gestione degli Eventi
●
In una GUI, per poter rispondere ad una “azione” è
necessario modellare il comportamento di tale
evento.
event-driven programming
●
In Java il componente grafico, gli eventi ad esso
associati ed il comportamento scaturito dal
verificarsi dell’evento sono mantenuti separati.
oggettoSorgenteEvento.addEventoListener(oggettoListenerEvento)
●
oggettoListenerEvento istanzia una classe che
implementa una interfaccia Listener
L'interfaccia ActionListener
●
E’ un’interfaccia della libreria standard
●
Contiene solo il metodo
actionPerformed(ActionEvent e)
●
Viene richiamato quando si verifica un
“evento di interesse” su un componente:
–
click del mouse su un JButton
–
pressione del tasto INVIO in un
componente di testo
–
selezione di una voce in un menù
ActionListener Ex.
EventFrame.java
EventFrameInnerClass.java
EventFrameGestioneImplicita.java
Window Builder Pro
●
●
●
●
Plug-in di Eclipse
WYSIWYG tool per la realizzazione di
layout grafici
Sviluppato da Google e rilasciato come
prodotto Open Source
Permette di sviluppare interfacce Swing,
AWT, GWT ed SWT
JEE
Application server
●
Si occupa della gestione delle applicazioni
sviluppate con JEE
●
Implementa le specifiche JEE
●
Esempi:
–
Tomcat (Apache Software Foundation)
–
Jboss (Red Hat)
–
GlassFish (Oracle)
–
WebSphere (IBM)
Servlet
●
●
Devono implementare l'interfaccia Servlet
I metodi dell'interfaccia servlet vengono
invocati automaticamente dal servlet
container
–
void init(ServletConfig config)
–
ServletConfig getServletConfig()
–
String getServletInfo()
–
void service(ServletRequest request, ServletResponse response)
–
void destroy()
GenericServlet e HttpServlet
●
Sono due classi astratte che
implementano l'interfaccia Servlet
●
javax.servlet.GenericServlet
●
javax.servelt.http.HttpServlet
–
doGet(HttpServletRequest request, HttpServletResponse response)
–
doPost(HttpServletRequest request, HttpServletResponse response)
Struttura di una applicazione JEE
●
Radice
–
META-INF
●
–
MANIFEST.MF
WEB-INF
●
●
●
web.xml
classes
–
File.class
–
Librerie.jar
lib
web.xml
●
Contiene le informazioni relative
all'applicazione:
–
Descrizione generale (display-name)
–
Descrizione (description)
–
Nome della servlet (servlet/servlet-name)
–
Descrizione della servlet
(servlet/description)
–
Classe che deve essere eseguita
(servlet/servlet-class)
–
Corrispondenza tra servlet e URL
(servlet-mapping)
Deploy di una applicazione
●
●
Le applicazioni possono essere esportate
ed importate come file compressi .war
(Web Archive)
L'application server si occupa di
scompattare e fare il deploy
dell'applicazione