PROGRAMMAZIONE JAVA
G. Frosini "PROGRAMMARE IN JAVA"
Volume I
Costrutti di Base - Programmazione a Oggetti - Ingresso/Uscita - Generici - Thread
Edizioni ETS
G. Frosini, A. Vecchio "PROGRAMMARE IN JAVA"
Volume II
Programmazione di Rete - Interfacce Grafiche - Strutture Dati
Edizioni ETS
G. Frosini, G. Lettieri, A. Vecchio "PROGRAMMARE IN JAVA"
Volume III
Esercizi
Edizioni ETS
Lucidi delle lezioni del corso Java disponibili all’indirizzo Internet:
http://www.iet.unipi.it/g.frosini/master/CorsoJava
G. Frosini
Slide 1
INTRODUZIONE
G. Frosini
Slide 2
PROGRAMMA JAVA (1)
•
Programma: costituito da una o più classi;
–
una classe per file:
•
–
più classi per file:
•
•
•
al più una può essere pubblica;
l’estensione del file deve essere java e, e se vi è una classe pubblica, il nome del file
deve essere uguale a quello di tale classe.
Classe principale:
–
–
quella da cui inizia l'esecuzione (specificata nel comando apposito);
comunemente è pubblica e deve possedere un metodo (una funzione) di nome
main():
•
•
•
•
l’estensione del file deve essere java e, se la classe è pubblica, il nome del file deve
essere uguale a quello della classe ;
deve essere statico e pubblico ed avere come argomento formale un array di stringhe;
viene eseguito per primo;
richiama altri eventuali metodi della stessa classe e utilizza altre eventuali classi.
Altre classi:
–
–
dette anche classi secondarie;
possono avere un metodo main(), per scopi di debugging.
G. Frosini
Slide 3
PROGRAMMA JAVA (2)
•
Convenzioni sui nomi
– i nomi devono rispettare la loro sintassi;
– inoltre, per convenzione:
• i nomi delle classi iniziano per lettera maiuscola;
• i nomi dei membri delle classi iniziano per lettera minuscola;
• quando un nome è composto, le componenti non vengono separate da caratteri
particolari, e quelle successive alla prima iniziano tutte con lettera maiuscola.
•
Esempio di programma:
// file ClassePrincipale.java
class ClasseSecondaria
{
void membroA()
{
/* … */ }
// …
}
// …
public class ClassePrincipale
{
// …
public static void main(String[] args)
{
/* … */
}
}
G. Frosini
Slide 4
COMPILAZIONE (1)
•
Ipotesi semplificativa:
– utilizzo del prompt dei comandi;
– tutti i file di un programma in un’unica cartella;
– comandi emessi dalla cartella contenente il programma.
•
Compilazione (comando javac):
– occorre specificare il nome e l’estensione del file sorgente contenente la
classe principale;
– poiché la classe principale è (in genere) pubblica, il nome della classe
principale è uguale a quello del file:
javac ClassePrincipale.java
– traduce il file sorgente e produce tanti file oggetto quante sono le classi
contenute nel file sorgente, ciascuno avente il nome della classe ed
estensione class;
• se vi sono classi riferite per cui non esiste il file oggetto, compila anche il
corrispondente file sorgente, purché abbia il nome di tale classe, e produce tanti file
oggetto quante sono le classi contenute nel file sorgente.
G. Frosini
Slide 5
COMPILAZIONE (2)
// file ClasseSecondaria1.java
class ClasseSecondaria1
{
}
class ClasseSecondaria2
{
}
// file ClasseSecondaria1.java
class ClasseSecondaria1
{
}
class ClasseSecondaria2
{
}
// file ClassePrincipale.java
public class ClassePrincipale
{
public static void main(String[] args)
{ ClasseSecondaria1 cs1;
ClasseSecondaria2 cs2;
// …
}
}
// file ClassePrincipale.java
public class ClassePrincipale
{
public static void main(String[] args)
{ ClasseSecondaria2 cs2;
ClasseSecondaria1 cs1;
// …
}
}
–
–
•
primo caso: compila, con generazione del file ClassePrincipale.class,
ClasseSecondaria1.class, ClasseSecondaria2.class
secondo caso (rispetto al primo caso, nel metodo main() sono invertite le due istruzioni):
non compila, in quanto non trova nessun file di nome ClasseSecondaria2.
Soluzione sicura:
– classe principale: contenuta in un file avente lo stesso nome della classe principale;
– classe secondarie: contenute o nel file della classe principale, o ciascuna in un
proprio file avente il nome della classe secondaria stessa.
G. Frosini
Slide 6
INTERPRETAZIONE
•
File oggetto:
– contiene il cosiddetto bytecode, simile al linguaggio macchina, ma indipendente
dalla piattaforma;
•
Esecuzione del bytecode (comando java):
– utilizzo di un interprete, la Java Virtual Machine (Java VM o più
semplicemente JVM);
– il comando deve indicare la classe principale (contenuta nel file oggetto avente
il nome della classe ed estensione class):
java ClassePrincipale
•
Portabilità:
– un programma compilato può essere eseguito su qualunque piattaforma su cui
sia installata una JVM.
•
Sicurezza:
– in esecuzione, viene utilizzato un “bytecode verifier”, che controlla che non ci
sia codice che viola la sicurezza del sistema.
•
Linguaggio progettato per le reti informatiche.
G. Frosini
Slide 7
ARGOMENTO DEL METODO MAIN()
•
Il metodo main() ha per argomento formale un array di stringhe:
public static void main(String[] args)
•
Argomenti attuali:
–
•
stringhe (anche nessuna) specificate con il comando di esecuzione java.
Esempio:
// file ProvaArg.java
public class ProvaArg
{ public static void main(String[] args)
{
// stampa di args[0] e di args[1])
}
}
•
Comandi:
javac ProvaArg.java
java ProvaArg uno due // vengono stampate le stringhe uno due
G. Frosini
Slide 8
INDIPENDENZA DALL’ARCHITETTURA
•
Indipendenza dall’architettura del bytecode:
– ogni architettura ha una sua propria JVM.
•
Indipendenza dall’architettura del programma sorgente:
– il linguaggio specifica che i caratteri devono essere rappresentati in unicode (16 bit),
con la possibilità di utilizzare i simboli delle più importanti lingue del mondo;
– il linguaggio specifica come e con quanti bit vengono rappresentati i numeri (per
esempio, il tipo int è rappresentato in complemento a 2 su 32 bit, eccetera);
– le java API (Application Programming Interface) sono le stesse per tutte le
piattaforme:
•
•
•
Piattaforma java:
–
–
–
•
le API sono un vasto insieme di componenti software (tipicamente, di classi) già scritte che
forniscono funzionalità assai utili, come l’interfaccia grafica (GUI: Graphical User Interface);
le API sono raggruppate in librerie, note come packages.
Java Compiler;
Java VM;
Java API.
Inclusione di package API:
– in un programma, viene incluso automaticamente il package java.lang;
– per includere un altro package pp, occorre la direttiva: import java.pp.*;
G. Frosini
Slide 9
CODIFICA UNICODE
•
Caratteri unicode:
– codificati su su 16 bit;
– i primi 128 caratteri (al più 7 bit significativi, numeri 0 – 127) coincidono
con i caratteri ASCII, anche se le loro codifiche usano un numero diverso
di bit.
– i primi 256 caratteri (al più 8 bit significativi, numeri 0 – 255) coincidono
con i caratteri latin-1, anche se le loro codifiche usano un numero diverso
di bit.
– un carattere unicode può anche essere espresso con una sequenza di
escape, che usa solo caratteri ASCII:
\uaaaa con a cifra ASCII esadecimale
•
Commenti, identificatori, letterali carattere e letterali stringa:
– utilizzano caratteri unicode (o sequenze di escape).
•
Altri elementi di un programma:
– utilizzano caratteri ASCII.
G. Frosini
Slide 10
TIPI
•
•
Tipo: insieme di valori e insieme di operazioni su quei valori
Linguaggio Java:
–
•
strongly typed: costanti, variabili, espressioni hanno tutte un tipo noto a tempo di
compilazione.
Tipi primitivi:
–
–
tipo boolean;
tipi numerici:
•
•
•
Tipi riferimento:
–
–
–
–
•
tipi “integral”:
– byte (interi 8 bit), short (interi 16 bit), int (interi 32 bit), long (interi 64 bit), char (caratteri in
codifica unicode, o naturali su 16 bit);
tipi “floating”:
– float (32 bit: 24 mantissa, 8 esponente), double (64 bit: 53 mantissa, 11 esponente);
tipi enumerazione (non trattati);
tipi array;
tipi classe;
tipi interfaccia.
Nota: fra i tipi classe, è compreso il tipo String (che rappresenta stringhe
costanti).
G. Frosini
Slide 11
LETTERALI
•
Letterali:
– operandi immediati che si scrivono direttamente in un programma.
•
•
Letterali booleani: true, false
Letterali carattere:
– caratteri (simboli o codifiche unicode) racchiusi fra apici (esempi: 'a', '\u3abc');
– caratteri di controllo (barra invertita seguita da un simbolo):
•
•
tabulazione orizzontale ' \t ', nuova riga (LF) '\n ', ritorno carrello (CR) ' \r ', barra invertita ' \\ ',
apice ' \' ', virgolette ' \" ', eccetera.
Letterali stringa:
– sequenze di caratteri racchiuse fra virgolette (esempio: "ciao").
•
Letterali interi (int: suffisso assente; long: suffisso l (o L)):
•
•
•
•
base dieci: cifra 0, oppure sequenza di cifre decimali che inizia con 1 ..9 (esempi: 0, 127)
base otto: sequenza di cifre ottali che inizia con 0 (esempio: 0127)
base sedici: sequenza di cifre esadecimali che inizia con 0x (esempio: 0x127)
Letterali floating (float: suffisso f (o F); double: suffisso assente o d (o D)):
– costituiti da parte intera, punto decimale, parte frazionaria, esponente preceduto da
e o E;
•
•
alcuni elementi possono mancare;
deve esserci almeno una cifra nella parte intera o in quella frazionaria, e almeno un elemento fra
punto decimale, esponente, suffisso;
– esempi: 2.5f, 2.5, 2d, 2e2f, 2e2, 2., .2, 0f, 0.0.
G. Frosini
Slide 12
VARIABILI DI UN TIPO PRIMITIVO
•
Forma di una definizione:
int n; boolean b, bb = true; char cc = '\t'; double dd = 10.0;
– una definizione può comparire ovunque nel programma.
•
Variabile di un tipo primitivo:
– ha un nome e un contenuto:
• nel caso più semplice, un nome è un identificatore (nome semplice);
• il contenuto viene specificato mediante un assegnamento (valore di un’espressione).
nome
•
contenuto
Variabile final:
– il suo contenuto, una volta determinato mediante un assegnamento, non
può essere più modificato;
final int n; boolean b = true; n = 10;
n = 20; // errore
G. Frosini
Slide 13
ESPRESSIONI
•
Espressione:
–
–
–
costituita da operatori e operandi;
operandi: letterali, costanti, variabili, espressioni racchiuse fra parentesi tonde;
produce un valore che viene assegnato (come nuovo contenuto) a una variabile:
int r, a, b, c;
…
r = (a+b)*c;
•
Conversione di tipo:
–
–
•
Conversione automatica di tipo (widening conversion):
–
–
•
valore di un operando (esempio: renderlo dello stesso tipo dell’altro operando);
valore prodotto da un’espressione (esempio: renderlo dello stesso tipo di quello della
variabile cui viene assegnato).
nell’ambito degli interi e dei floating, verso quelli che usano un maggior numero di bit per
la rappresentazione, con nessuna perdita di informazione;
da intero a floating (non viceversa), con nessuna perdita sull’ordine di grandezza, ma con
una eventuale perdita di precisione.
Conversione esplicita di tipo o Casting (il nuovo tipo fra parentesi tonde):
–
da un tipo numerico a un altro qualunque tipo numerico:
int i; double d;
…
i = (int)d;
G. Frosini
Slide 14
CONVERSIONI AUTOMATICHE: GRAFICO
•
Senza perdita di informazione:
– linea unita.
•
Con nessuna perdita sull’ordine di grandezza, ma una eventuale perdita
di precisione:
– linea tratteggiata.
char
byte
short
int
long
float
double
G. Frosini
Slide 15
OPERATORI (1)
•
Operatori per i booleani
•
•
•
•
•
operatori di relazione: ==, !=
operatore di complemento logico: !
operatori logici: & (and), | (or), ^ (or esclusivo)
operatori and_condizionale e or_condizionale (corto circuito): &&, ||
(valutano l’operando destro solo se quello sinistro vale true o false, rispettivamente
Operatori per gli interi:
– Operatori di confronto, che producono un risultato di tipo boolean:
•
•
confronto numerico: <, <=, >, >=
uguaglianza numerica: ==, !=
– Operatori numerici, che producono un risultato di tipo int o long:
•
•
•
•
•
•
•
più e meno unari: +, incremento (unario), prefisso e postfisso: ++, decremento (unario), prefisso e postfisso: -(si applicano a una variabile e restituiscono un valore, quello della variabile modificata o meno)
complemento (unario) bit a bit: ~
operatori moltiplicativi: *, /, %
operatori additivi: +, shift a sinistra: <<; shift a destra replicando il segno: >>; shift a destra inserendo 0: >>>
operatori bit a bit: & (and), | (or), ^ (or esclusivo)
G. Frosini
Slide 16
OPERAZIONI (2)
•
Operatori per i floating
– Operatori di confronto, che producono un risultato boolean:
• come per gli interi
– Operatori numerici, che producono un risultato float o double:
•
•
•
•
•
più e meno unari: +, incremento (unario), prefisso e postfisso: ++, decremento (unario), prefisso e postfisso: -operatori moltiplicativi: *, /, %
operatori additivi: +, -
Operatore di assegnamento =:
– operandi: valore a destra, variabile a sinistra;
– produce un risultato (valore dell’espressione a destra dell’operatore)
– ha un effetto collaterale (assegnamento del risultato alla variabile a sinistra
dell’operatore);
– può comparire all’interno di un’espressione:
int a, b, c, d; …
a = (b = c + d);
•
Altri operatori di assegnamento:
+=
-=
a = a+b si può scrivere a +=b
…
G. Frosini
Slide 17
PRECEDENZA E ASSOCIATIVITÀ
•
Precedenza (decrescente)
unari postfissi: ++ -unari prefissi: ! ~ ++ -- + (unario) - (unario)
moltiplicativi: * / %
additivi: + di relazione: < <= > >=
di uguaglianza: == !=
and: &
or esclusivo: ^
or: |
and-condizionale: &&
or-condizionale: ||
assegnamento: = += -= …
•
Associatività
non significativa
da destra a sinistra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da sinistra a destra
da destra a sinistra
Nota:
–
nel calcolo di una espressione, le sub-espressioni racchiuse fra parentesi tonde hanno
precedenza maggiore.
G. Frosini
Slide 18
CLASSE MATH
•
Classe Math (package java.lang, incluso automaticamente):
– comprende le più comuni funzioni matematiche:
int Math.abs(int n)
double Math abs(double x)
valore assoluto di intero
valore assoluto di reale
double Math.sqrt(double x)
double Math.pow(double x, double a)
double Math.sin(double x)
…
double Math.asin(double a)
…
double Math.exp(double x)
double Math.log(double x)
double Math.PI
double Math.E
double Math.random()
int Math.round(float f)
radice quadrata
x elevato ad a
seno di x
…
arco seno di a
…
e elevato ad x
logaritmo in base e di x
costante pigreco
costante e
numero casuale r, 0.0 <= r < 1.0
arrotondamento all’intero più vicino
G. Frosini
Slide 19
CLASSE CONSOLE (1)
•
Classe di lavoro, scritta appositamente per questo corso:
–
–
•
si trova all'indirizzo Internet http://www.iet.unipi.it/g.frosini/CorsoJava;
va ricopiata nella cartella contenente il programma.
Scopo della classe:
–
–
leggere da tastiera e scrivere su video singoli caratteri;
leggere da tastiera e scrivere su video valori dei seguenti tipi primitivi (costituiti da
token (parole) separati tra loro):
char
boolean
int
double
–
•
leggere da tastiera e scrivere su video valori di tipo String (costituiti da token (parole)
separati tra loro.
Nota:
–
–
non confondere valori letti o scritti con i lettrali;
in particolare:
•
•
•
i caratteri non vanno racchiusi fra apici;
le stringhe non vanno racchiuse fra doppi apici;
i numeri interi positivi vanno scritti senza il segno +.
G. Frosini
Slide 20
CLASSE CONSOLE (2)
•
Letture/scritture di singoli caratteri:
char Console.leggiUnCarattere(); void Console.scriviUnCarattere(char c):
•
Letture da tastiera di token separati da spazi bianchi:
char Console.leggiCarattere(); boolean Console.leggiBooleano();
int Console.leggiIntero(); double Console.leggiReale();
String Console.leggiStringa();
•
Scrittura su video di un singolo valore e di un fine linea:
void Console.scriviCarattere(char c); void Console.scriviBooleano(boolean b);
void Console.scriviIntero(int i); void Console.scriviReale(double r);
void Console.scriviStringa(String s);
•
Scrittura su video di un fine linea:
void Console.nuovaLinea();
•
Scrittura su video di token separati da un carattere spazio:
void Console. scriviChar(char c); void Console. scriviBool(boolean b);
void Console. scriviInt(int i);
void Console. scriviReal(double r); void Console. scrivi Str(String s )
–
è necessario che l’ultima scrittura contenga un fine linea .
G. Frosini
Slide 21