+
Sviluppo Applicazioni Mobile – Lezione 13
Dr. Paolo Casoto, Ph.D - 2012
+
Credits
I lucidi di questa lezione sono stati preparati da:
Professor Stefano Mizzaro Professor Paolo Coppola
e sono stati modificati e completati dal Dr. Paolo Casoto nel 2011. Sono rilasciati con licenza Creative Commons
Attribuzione, non commerciale e non opere derivate.
Dr. Paolo Casoto, Ph.D - 2012
+
Package
Insieme di classi e interfacce raggruppate all’interno di una cartella in virtù di una similarità semantica
Analogo ai Namespace in .NET, ma con un vincolo di posizione reale dei file all’interno delle cartelle del FS
In .NET questo vincolo è limitato ad un posizionamento “logico” ma non fisico delle classi.
Struttura gerarchica basata sul filesystem
Nomi univoci grazie al dominio internet
Due istruzioni (parole riservate):
package
import Dr. Paolo Casoto, Ph.D - 2012
+
package
Definisce il package di destinazione delle classi (e delle interfacce) definite all’interno del file
package ;
Prima istruzione di un file Se l’istruzione non c’è (come finora) ⇒ package “di default”
Evitate di utilizzare i package di default quando possibile !!!
Dr. Paolo Casoto, Ph.D - 2012
+
import
Dice in quali package/classe cercare i nomi usati nelle classi di questo file
Esempi
import java.util.Calendar; import java.util.GregorianCalendar;
import java.util.*;
import .; import .*;
N.B.: si importa (tutte le classi di) un package o specifiche classi, non i “sottopackage”: import java.*; è sbagliato Dr. Paolo Casoto, Ph.D - 2012
+
Full qualified name
.
java.util.Calendar java.lang.String
javax.swing.JApplet
Quindi: l’import serve per evitare di scrivere i full qualified name ogni volta
In realtà non si importa nulla: si evita di scrivere
E’ necessario utilizzare il full qualified name quando vi può essere ambiguità nei nomi delle classi importate da package differenti.
E.g.: Date, presente sia nei tipi di Java sia in java.sql Dr. Paolo Casoto, Ph.D - 2012
+
Package e filesystem
La struttura gerarchica dei package corrisponde a quella del filesystem
Le classi del package a vanno nella directory a Le classi del package a.b vanno nella directory a/b
… I file del package xxx.yyy.zzz vanno nella directory xxx/yyy/zzz
E la radice deve essere in CLASSPATH
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio
Nel package p.a (directory ./p/a) ci sono 2 classi A e B (sottoclasse di A)
Nel package p.b (directory ./p/b) ci sono 3 classi C, D (sottoclasse di C) ed E (sottoclasse di B)
Nel package p (directory ./p) c’è la classe F (che usa tutte le altre classi)
Dr. Paolo Casoto, Ph.D - 2012
+
Diagramma dei package p a
b C
A
B
F
D
E
Dr. Paolo Casoto, Ph.D - 2012
+
Package, compilazione, esecuzione, javadoc
Bisogna risalire alla radice Per compilare (usare nomi di file)
>javac –d bin p/F.java >cd p; javac F.java (non trova i package)
Per eseguire (usare full qualified names)
>java p.F >cd p; java F (non trova la classe F, vuole p.F)
>cd p; java p.F (non va, cerca il package/dir p) Javadoc (creazione documentazione):
>javadoc -verbose -d doc p p.a p.b
(Sempre risalire alla radice)
Dr. Paolo Casoto, Ph.D - 2012
+
Nomi univoci di package
Nome di package: xxx.yyy.zzz (minuscole!)
Nomi che iniziano con java. sono riservati
java.lang, java.io, java.util, et al.
Dal nome del dominio internet: il nome di un package sviluppato in enaip.it inizia con it.enaip
(e prosegue con un nome esplicativo deciso dal programmatore: it.enaip.paolo, it.enaip.luca, …)
Dr. Paolo Casoto, Ph.D - 2012
+
Package e visibilità
Attributi e metodi possono avere visibilità:
public: ovunque, anche in altri package protected: solo nelle sottoclassi e nel package (niente) “package”: solo nel package private: solo nella classe
Classi e interfacce possono avere visibilità:
public: anche da altri package
(niente) “package”: solo nel package
Regola: un’unica classe public in un “.java”, e nome classe = nome file
Dr. Paolo Casoto, Ph.D - 2012
+
Importanza rassegna API
Rassegna API? Java 1.4.2: 2991 classi in 135 package! Gulp!! Java 5 (1.5): di più!!! Non riusciamo a vedere tutte le API in qs. corso ma
Da qualche parte bisogna pur cominciare
È importante capire il modo “giusto” di lavorare di un programmatore moderno (che cerca pezzi di codice e li “incolla”) È importante evitare di ri-inventare la ruota
Molto di quello che deve fare un programmatore è già fatto,
Si tratta “solo” di trovarlo… È anche importante capire come e perché è fatto… Dr. Paolo Casoto, Ph.D - 2012
+
Fonti utili
Documentazione in linea delle API Creata con javadoc
In formato HTML Navigabile con un browser
(…java/docs/)
Sorgenti (.java) delle API! File src.zip nell’SDK, da scompattare
(…java/src/…) Libri, manuali, altro
L’esperienza degli altri programmatori !!!
Dr. Paolo Casoto, Ph.D - 2012
+
Un po’ di package usati spesso
java.lang: (importato implicitamente) java.util: (date, contenitori di oggetti, …)
java.io: input/output, flussi, file, … java.awt, java.awt.event, javax.swing (GUI)
java.applet (applet in pagine Web)
java.sql (JDBC x accesso DB) java.rmi (Remote Method Invocation)
… Un po’ di java.lang:
Math, Object, System, String
Dr. Paolo Casoto, Ph.D - 2012
+
Dr. Paolo Casoto, Ph.D - 2012
+
Dr. Paolo Casoto, Ph.D - 2012
+
java.lang.Math public static double sin(double) public static double cos(double) public static double sqrt(double) Se vi serve una funzione matematica ==> documentazione API… public static double log(double) public static double abs(double) public static double exp(double, double) public static double floor(double) public static double ceil(double) public static double min(double, double) public static double max(double, double) ...
Dr. Paolo Casoto, Ph.D - 2012
+
java.lang.Object
Radice della gerarchia, superclasse di tutte le classi Se non c’è extends, è come se ci fosse extends Object
I suoi metodi sono ereditati da tutte le classi public String toString()
public boolean equals(Object o)
(protected Object clone()) …
Dr. Paolo Casoto, Ph.D - 2012
+
toString()
public String toString() Restituisce una rappresentazione testuale, visualizzabile dell’oggetto Chiamato implicitamente quando serve
Da sovrascrivere in ogni classe che definiamo
(vediamo com’è fatto…)
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio
class Punto { // ... public String toString () { return "Punto: (" + getX() + ", " + getY() + ")"; } } class ProvaPunto { // ... public static void main(String[] args) { Punto p = new Punto(2.3, 5.67); System.out.print(p); System.out.println(p); } >java ProvaPunto } Punto: (2.3, 5.67)…
Dr. Paolo Casoto, Ph.D - 2012
+
equals
public boolean equals(Object o) 2 tipi di uguaglianza fra x e y:
Essere lo stesso oggetto (x == y) Essere 2 oggetti uguali (x.equals(y))
== confronta i riferimenti
In realtà, l’equals di Object è come l’==… …ma equals() può essere sovrascritto
Da sovrascrivere in ogni classe che definiamo
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio (1/3)
class Punto { // ... Notate il downcast: devo sovrascrivere, e il parametro di equals è public boolean equals (Object o) { Object… return ((Punto)o.x == this.x && Si può fare di meglio… (Punto)o.y == this.y); } }
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio (2/3)
class Punto { // ... public boolean equals (Object o) { if(o instanceof Punto) return ((Punto)o.getX() == this.getX() && (Punto)o.getY() == this.getY()); else return false; } } Preferibile rispetto alla precedente
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio (3/3)
class Punto { // ... public boolean equals (Object o) { return (o instanceof Punto && ((Punto)o).getX() == this.getX() && ((Punto)o).getY() == this.getY() ); } }
Dr. Paolo Casoto, Ph.D - 2012
+
java.lang.System
Sveliamo un mistero: perché System.out.println (print)
System.in.read Classe System
Variabile di classe out (in)
public final static PrintStream out; Metodi d’istanza print, println, read
Metodo statico exit(int): consente di chiudere l’applicazione con un eventuale codice di errore.
Metodo statico currentTimeMillis: restituisce il tempo corrente in millisecondi. La granularità dipende dal sistema operativo utilizzato !!! Dr. Paolo Casoto, Ph.D - 2012
+
java.lang.String
Sequenza di caratteri String: sottoclasse final di Object “Zucchero sintattico”: Letterali stringa: "" (chiamata implicita del costruttore)
+: concatena stringhe
Dr. Paolo Casoto, Ph.D - 2012
+
java.lang.String
String: non modificabili (e StringBuffer: modificabili)
public int length() public int charAt(int)
public boolean equals(Object)
public String substring(int) public String substring(int,int)
public char[] toCharArray()
Dr. Paolo Casoto, Ph.D - 2012
+
Eccezioni
Quando si ha una situazione anomala in esecuzione… Divisione per 0, accesso ad array con indice errato (ArrayIndexOutOfBoundException), lettura oltre fine file, ecc. ecc.
…l’interprete Java:
sospende l’esecuzione normale lancia un’eccezione: crea un’istanza di (una sottoclasse di) java.lang.Exception (eventualmente) esegue codice per la gestione dell’eccezione
Dr. Paolo Casoto, Ph.D - 2012
+
Gettare, catturare, rimbalzare
Un’eccezione viene gettata Durante l’esecuzione di un certo metodo, che avrà il suo record di attivazione sullo stack… Se viene catturata: viene gestita
Altrimenti viene rimbalzata
al blocco più esterno (e al più esterno e…) al chiamante (e al chiamante del chiamante…)
Vediamole una alla volta…
Dr. Paolo Casoto, Ph.D - 2012
+
Gettare
Gettare = creare un’istanza di java.lang.Exception (o sottoclasse) Chi lo fa:
L’interprete Java al verificarsi di una situazione anomala
Esplicitamente il programmatore
throw Es.: throw new Exception();
Dr. Paolo Casoto, Ph.D - 2012
+
Catturare
Costrutto try/catch/finally Esegue
Se getta eccezione e, si interrompe viene eseguita la prima t.c. e instanceof
è come un parametro formale
sempre eseguita alla fine
Dr. Paolo Casoto, Ph.D - 2012
try { } catch ( ) { } catch ( ) { } ... } catch ( ) { } finally { }
+
Rimbalzare (throws)
Un’eccezione non catturata viene rimbalzata Al blocco esterno (ricorsivamente) Al metodo chiamante (ricorsivamente) Se un metodo m() rimbalza eccezioni va dichiarato: public void m() throws E1, E2 {
(se checked, ossia non RunTimeException) (se unchecked, non serve)
Regola generale: Meglio catturare che rimbalzare
Dr. Paolo Casoto, Ph.D - 2012
+
Eccezioni ed errori
Eccezioni predefinite Throwable (“oggetti gettabili”)
Exception Error: il programma termina
Non catturate gli Error
100+ classi predefinite Vediamo la documentazione…
Dr. Paolo Casoto, Ph.D - 2012
+
Eccezioni in java.lang
Dr. Paolo Casoto, Ph.D - 2012
+
Errori in java.lang
Dr. Paolo Casoto, Ph.D - 2012
+
Eccezioni definite da noi
class EccezioneMia extends Exception {} class EccezioneMia extends Exception { public EccezioneMia() {} public EccezioneMia(String s) { super(s); ... } }
Dr. Paolo Casoto, Ph.D - 2012
+
Utilità delle eccezioni
Separare codice “normale” da situazioni anomale Maggiore leggibilità
Meglio di “valore funzione = -1: ==> errore!” Ne riparlerete…
Usate nella gestione dei file
Dr. Paolo Casoto, Ph.D - 2012
+
Eccezioni di java.io
Dr. Paolo Casoto, Ph.D - 2012
+
Flussi e file
Flusso (stream) = sequenza di dati di input: da cui leggere di output: su cui scrivere I file sono visti come flussi di dati
Il package java.io definisce parecchie (>50) classi e interfacce per la gestione dei file (vediamo la documentazione) Vediamo le più semplici (e inefficienti…)
Tramite esempi
Dr. Paolo Casoto, Ph.D - 2012
+
Dr. Paolo Casoto, Ph.D - 2012
+
java.io.File (1/2)
Un’istanza di File rappresenta un file/pathname all’interno di un programma
I metodi (d'istanza) di File vedono un file come oggetto atomico (non vedono il contenuto)
Associare l’istanza di File a un pathname (con il costruttore): public File(String) Creare un File vuoto:
public boolean createNewFile() (il “costruttore” non è un “creatore”; con solo il costruttore, il file fisico sul file system NON viene creato!!)
Dr. Paolo Casoto, Ph.D - 2012
+
java.io.File (2/2)
Verificare se un file esiste public boolean exists()
Cancellare un file public boolean delete()
Verificare se l’istanza rappresenta un file o una directory:
public boolean isFile() public boolean isDirectory()
Cfr. documentazione API
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio
import java.io.*; class ProvaFile { public static void main (String[] args) throws IOException { File f = new File("pippo.txt"); System.out.println(f.exists()); f.createNewFile(); System.out.println(f.exists()); System.out.println(f.isFile()); System.out.println(f.isDirectory()); System.in.read(); f.delete(); >java ProvaFile } }
Dr. Paolo Casoto, Ph.D - 2012
false true true false
+
Esempio
Dr. Paolo Casoto, Ph.D - 2012
+
Come si lavora sul contenuto di un file
3 passi Apertura
Operazioni lettura/scrittura Chiusura
Gestione diversa per lettura e scrittura
Vediamo prima la lettura
Dr. Paolo Casoto, Ph.D - 2012
+
Stefano Mizzaro - API 2
Dr. Paolo Casoto, Ph.D - 2012
+
InputStream
Classe astratta public abstract int read():
legge un byte dal flusso, ritorna il codice ASCII Sovraccarico (public int read(byte b[])) e può leggere anche un array di byte
Restituisce -1 a fine file public void close(): chiude il flusso
public long skip(long n): salta il numero di byte specificato dal parametro
Dr. Paolo Casoto, Ph.D - 2012
+
FileInputStream
Sottoclasse di InputStream È quella da usare, i suoi oggetti sono flussi di input. Non definisce altri metodi; ovviamente: implementa read e definisce il costruttore, da usare per l’apertura (lo vediamo subito) Quindi si può leggere il contenuto di un file, carattere per carattere, uno dopo l’altro sequenzialmente
Dr. Paolo Casoto, Ph.D - 2012
+
Stefano Mizzaro - API 2
Dr. Paolo Casoto, Ph.D - 2012
+
OutputStream
Simmetria con InputStream Classe astratta
public abstract void write(int b): scrive un byte sul flusso (8 bit meno significativi) sovraccarico (public void write(byte b[])) e può scrivere anche un array di byte alla volta public void close(): chiude il flusso. È molto importante chiudere i flussi di output per non perdere i dati non ancora salvati
Dr. Paolo Casoto, Ph.D - 2012
+
FileOutputStream
Sottoclasse di OutputStream È quella da usare, i suoi oggetti sono flussi di output. Non definisce altri metodi; ovviamente: implementa write e definisce il costruttore, da usare per l’apertura (lo vediamo subito) Quindi si può scrivere il contenuto di un file, carattere per carattere, uno dopo l’altro sequenzialmente
Dr. Paolo Casoto, Ph.D - 2012
+
Apertura file
I costruttori di FileInputStream e FileOutputStream aprono un file (lo “preparano”) in lettura e scrittura
Parametro: un oggetto della classe File:
FileInputStream f; f = new FileInputStream(new File("pippo/pluto.txt"));
oppure una stringa (pathname del file): FileInputStream f; f=new FileInputStream("pippo/pluto.txt");
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio 1: VediFile.java
Scriviamo un programma per visualizzare il contenuto di un file di testo
Uso:
>java VediFile pippo.txt
Dr. Paolo Casoto, Ph.D - 2012
+
VediFile.java (1/2)
import java.io.*; public class VediFile { public static void main(String args[]) { FileInputStream f; int c; if (args.length != 1) System.out.println( "Uso: java VediFile "); else { try { f = new FileInputStream(args[0]); } catch (FileNotFoundException e) { System.out.println( "Errore in apertura file"); return; } Dr. Paolo Casoto, Ph.D - 2012
+
VediFile.java (2/2)
} }
try { c = f.read(); while (c > 0) { System.out.print((char) c); c = f.read(); } } catch (IOException e) { System.out.println( "Errore in lettura file"); } try { f.close(); } catch (IOException e) { System.out.println( "Errore in chiusura file"); }
}
Dr. Paolo Casoto, Ph.D - 2012
+
Commenti
Leggiamo carattere per carattere dal file e scriviamo su standard output
Cast perché read restituisce un int Esercizio: cosa viene visualizzato se tolgo il cast?
A fine file la read restituisce -1
Le eccezioni vanno gestite/catturate try/catch per gestire tutte le possibili eccezioni
Dr. Paolo Casoto, Ph.D - 2012
+
Es. 2 : CopiaFile.java
Programma che copia un file in un altro Legge, carattere per carattere, da un (File)InputStream e… … scrive, carattere per carattere, su un (File)OutputStream Uso:
>java CopiaFile pippo.txt pluto.txt Dr. Paolo Casoto, Ph.D - 2012
+
CopiaFile.java
import java.io.*; public class CopiaFile { public static void main(String args[]) throws FileNotFoundException, IOException { FileInputStream in; FileOutputStream out; int c; if (args.length != 2) System.out.println( "Uso: java CopiaFile "); else { in = new FileInputStream(args[0]); out = new FileOutputStream(args[1]); c = in.read(); while (c > 0) { out.write((char) c); c = in.read(); } in.close(); out.close(); } } } Dr. Paolo Casoto, Ph.D - 2012
+
Commenti
Non abbiamo catturato le eccezioni (male! ==> Ex.) Il file di output viene creato dal costruttore di FileOutputStream Ex.: verificare che è proprio così Il corpo del ciclo ha la stessa struttura di VediFile
Dr. Paolo Casoto, Ph.D - 2012
+
I file e i tipi primitivi
Finora: lettura/scrittura byte per byte, carattere per carattere Spesso è comodo usare i tipi primitivi (leggere e scrivere double, int, boolean, …). Si usano:
DataInputStream (che implementa DataInput)
DataOutputStream (che implementa DataOutput)
Dr. Paolo Casoto, Ph.D - 2012
+
Stefano Mizzaro - API 2
Dr. Paolo Casoto, Ph.D - 2012
+
DataInput(Stream) e DataOutput (Stream)
Le interfacce DataInput e DataOutput contengono metodi del tipo readBoolean(), readByte(), writeDouble(), writeShort(), . . .
DataInputStream e DataOutputStream simili alle classi viste finora
però i costruttori non sono sovraccarichi e vogliono come parametro un oggetto di tipo, rispettivamente, InputStream e OutputStream (non una stringa)
Dr. Paolo Casoto, Ph.D - 2012
+ import java.io.*; I/O di tipi primitivi Esempio: public class DataFile {
}
public static void main (String[] args) throws IOException { DataOutputStream out; DataInputStream in; out = new DataOutputStream(new FileOutputStream("tmp")); out.writeBoolean(false); out.writeDouble(12.34); out.writeChar('q'); out.close(); in = new DataInputStream(new FileInputStream("tmp")); System.out.println(in.readBoolean()); System.out.println(in.readDouble()); System.out.println(in.readChar()); in.close(); }
Dr. Paolo Casoto, Ph.D - 2012
+
Commenti
Proviamo a eseguirlo Proviamo a visualizzare il file creato… Notate che non “parliamo alla classe (interfaccia) base” DataOutputStream non DataOutput
DataInputStream non DataInput
… perché le due interfacce non hanno il metodo close() Avremmo errore in compilazione -> provare (Ex.)
No eccezioni… -> Ex.
Dr. Paolo Casoto, Ph.D - 2012
+
I file ad accesso casuale (diretto)
Finora solo accesso sequenziale Impossibile “tornare indietro” (solo chiudendo e riaprendo il flusso) Accesso diretto, non sequenziale
“come un array” (però su disco)
java.io.RandomAccessFile implementa DataInput e DataOutput
ha un metodo seek(int) per posizionarsi all'n-esimo byte del file (1° è zero)
Ha anche altri metodi (tutti quelli di DataInput e DataOutput)
Dr. Paolo Casoto, Ph.D - 2012
+
Stefano Mizzaro - API 2
Dr. Paolo Casoto, Ph.D - 2012
+
Esempio: lettura da file ad accesso casuale
Scriviamo 6 caratteri su un file Poi li leggiamo usando l’accesso casuale
in ordine inverso dal quinto al primo
Dr. Paolo Casoto, Ph.D - 2012
+
FileAccessoCasuale.java
import java.io.*; class FileAccessoCasuale { public static void main (String[] args) throws IOException, EOFException { FileOutputStream out = new FileOutputStream("tmp"); for (char c = 'a'; c <= 'f'; c++) out.write(c); out.close(); RandomAccessFile f = new RandomAccessFile("tmp", "r"); for (int i = 4; i >= 0; i--) { f.seek(i); System.out.println((char)f.readByte()); } } } Dr. Paolo Casoto, Ph.D - 2012
+
Commenti
Eccezioni… Costruttore con 2 parametri:
"r" indica lettura (read) "rw" indicherebbe lettura & scrittura (read & write)
Evitare operazioni continue in memoria secondaria (es.: ordinamento di file)… … ma evitare anche di caricare file enormi in memoria centrale…
Stefano Mizzaro - API 2
Dr. Paolo Casoto, Ph.D - 2012
+
Classi per la lettura di dati UNICODE
In aggiunta ai flussi che operano su dati in modalità byte, è possibile in Java disporre di una gerarchia di oggetti che leggono/scrivono dati come flussi di caratteri UNICODE a 16 bit:
Writer Reader
Tutte le medesime varianti viste per i flussi dati standard
Possibilità di far interagire le due tipologie di flussi di dati mediante gli oggetti InputStreamReader. Ed OutputStreamWriter
Dr. Paolo Casoto, Ph.D - 2012
+
Riassunto
Eccezioni Gettare, catturare, rimbalzare
try/catch/finally throw, throws
Flussi e file File, InputStream, FileInputStream, OutputStream, FileOutputStream, DataInputStream, DataOutputStream, RandomAccessFile Prox. lezione: API x GUI (AWT)
Dr. Paolo Casoto, Ph.D - 2012
+
Domande ??? Grazie a tutti per l’attenzione Dr. Paolo Casoto, Ph.D - 2012