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