Sei sulla pagina 1di 151

Java

Il linguaggio Java
Denito dalla Sun Microsystems (ora Oracle) nel
1995/96
Useremo la Standard EdiBon (versione 7)
SenBrete parlare anche di jdk e di jre

Esistono anche Java PlaIorm Enterprise EdiBon


costruita sopra Java SE, ore servlets e JSP, EJB
per sviluppare applicazioni "server side"

Java PlaIorm Micro EdiBon


per piccoli disposiBvi (soPware embedded)

CaraTerisBche
Object-oriented (OO)
Distribuito
RMI e altri strumenB di distribuzione

Indipendente dalla piaTaforma


Bytecode e Java Virtual Machine

Sicuro
Esecuzione in una "sandbox" che garanBsce che
non si possa danneggiare l'host

Sorpresa!
Non esistono i "tradizionali" conce] di
"programma"
"soToprogramma" (funzione o procedura)

Esistono le classi, che raggruppano (tra le altre


cose) daB privaB e metodi
i metodi sono il termine OO usato per i
soToprogrammi
hanno sintassi analoga alle funzioni C

Classi come astrazioni

La struTura di un programma Java


Un programma Java organizzato come un
insieme di classi
Ogni classe corrisponde a una dichiarazione di Bpo
o a una collezione di funzioni
Una classe conBene dichiarazioni di variabili
(aTribuB) e di funzioni (metodi)

Il programma principale rappresentato da


un metodo speciale di una classe, deTo main

Il primo programma Java


le: HelloWorld.java

public class HelloWorld {


public static void main(String[] args){

System.out.println("Hello world!");
}
}

Esempio di classe in Java


public class Data {
private int giorno;
private int mese;
private int anno;

// restituisce il giorno
public int leggiGiorno(){}

// restituisce il mese
public int leggiMese(){}

// restituisce lanno
public int leggiAnno(){}
}

Il costruTo class
Una classe pu essere vista come un Bpo denito
dallutente che specica le operazioni uBlizzabili
sul Bpo stesso
Il Bpo pu essere usato per dichiarare altre
variabili
int a, b;

dichiara due variabili a e b sulle quali possibile fare tuTe le


operazioni predenite per il Bpo int

Data d;

dichiara una variabile d sulla quale possibile fare tuTe le


operazioni denite nella classe Data

Denisce un Bpo di dato astraTo

Ogge]
Tu] gli ogge] della stessa classe hanno la stessa
struTura
Il numero e Bpo dei loro aTribuB lo stesso
Ad esempio, la classe Data denisce tuTe le date
possibili, tramite gli aTribuB giorno, mese, anno

Ogni oggeTo, in ogni istante dellesecuzione del


programma, caraTerizzato da uno stato, che
dato dal valore degli aTribuB delloggeTo
Lo stato delloggeTo oggi di Bpo Data denito dal
valore degli aTribuB giorno, mese, anno

Accesso ad aTribuB e metodi


Tramite la "notazione punto"
Esempio:
Data d;
int x;
//codice che inizializza d
x = d.leggiGiorno();

Esegue leggiGiorno() su oggeTo d: resBtuisce valore


del giorno della data d
come se leggiGiorno() avesse come argomento
implicito d: in C scriveremmo: leggiGiorno(d);
Si dice anche che alloggeTo d inviamo il messaggio
leggiGiorno

CambiamenB di stato
Lo stato degli ogge] (mutabili) pu cambiare nel tempo,
chiamando metodi opportuni
data1

data1

Data

Data

giorno = 30
mese = 12
anno = 2010

data1.giornoDopo()

giorno = 31
mese = 12
anno = 2010

Esistono alcuni casi in cui gli ogge] sono immutabili (cio


non possono essere modicaB)
Ad es. la classe predenita String

metodo giornoDopo()

Per modicare lo stato, il metodo deve potere accedere ai campi delloggeTo su


cui stato chiamato
Nella denizione di un metodo ci si pu riferire direTamente (senza notazione
punto) ad aTribuB e metodi delloggeTo sul quale si sta lavorando
public void giornoDopo() {
giorno++;
if (giorno > 31) {

giorno = 1;

mese++;
}
if (mese > 12) {

mese = 1;

anno++;
}
}

Data d;

d.giornoDopo(); //modifica lo stato

Private e public
ATraverso i metodi "public" di una classe
possibile vedere qual lo stato di un oggeTo ...

Data d;
int x;

x = d.leggiGiorno();

ma non accedere ai daB "private" (al di fuori del


codice di Data):
if (d.mese == 12) //Errore di compilazione!

Programmazione
"in the small"

Tipi primiBvi e variabili


Tipi numerici:
byte: 8 bit
short: 16 bit
int: 32 bit
long: 64 bit
oat: 32 bit
double: 64 bit

Altri Bpi:
boolean: true, false
char: 16 bit, caraTere
Unicode

Dichiarazione
byte unByte;
int a, b=3, c;
char c=h, car;
boolean trovato=false;

Variabili e Bpi riferimento


Le variabili di Bpo primiBvo (numerico, char, bool) contengono il valore
TuTe le altre contengono riferimenB a valori (ecco perch si dicono essere
"di Bpo riferimento")
I Bpi riferimento sono:
Tipi deniB dallutente (classi, interfacce)
Tipi array
Enumerazioni

Tipi riferimento possono essere uBlizzaB ovunque si usi un Bpo:

Dichiarazioni di variabili e parametri, Bpo del valore resBtuito da un metodo

Le variabili

Consentono di accedere agli ogge]


Sono allocate nello stack a run-Bme quando si chiama il metodo in cui sono
dichiarate
Gli ogge] referenziaB dalle variabili sono invece allocaB sullo heap
Sono deallocate quando il soToprogramma ritorna al chiamante

Ancora su Bpo riferimento


Ogni variabile dichiarata con una classe conBene un
riferimento a un oggeTo: un indirizzo di memoria

il valore ee]vo dellindirizzo non noto e non interessa

Un oggeTo memorizzato in unopportuna area di


memoria

d, di Bpo Data, conBene lindirizzo della prima cella delloggeTo


d

xxx

3
11
2010

giorno
mese
anno

Dichiarazione e inizializzazione
La dichiarazione di una variabile di Bpo riferimento non
alloca spazio per un oggeTo, ma solo per il riferimento ad
un oggeTo
A una variabile di Bpo riferimento assegnato inizialmente
il riferimento null, per indicare che la variabile non ancora
associata ad alcun oggeTo
Data d;

d vale null, non esiste ancora un oggeTo di Bpo Data

Un parametro o una variabile locale non possono essere


usaB senza essere inizializzaB

Il compilatore rileva staBcamente mancanza di inizializzazione

In entrambi i casi occorre costruire un oggeTo e


inizializzarlo esplicitamente

New
La costruzione di un oggeTo si realizza dinamicamente
tramite loperatore new
Esempio:
Data d = new Data();

EeTo di new:

Costruisce un nuovo oggeTo di Bpo Data


ResBtuisce il riferimento alloggeTo appena creato

Il riferimento viene conservato nella variabile d per potere usare


loggeTo

Data() un metodo parBcolare chiamato COSTRUTTORE


Ha lo stesso nome della classe, si riconosce come metodo dalle
parentesi ()

Dichiarazione e creazione
Data data;
data = new Data( );
data = new Data( );

data

Creato con la seconda new. Il riferimento al primo


oggeTo Data perso.
Non c pi modo di accedere alloggeTo.
LoggeTo verr distruTo dal garbage collector.

Creato con la prima


new

Data

Data

Esempio di costruTore
public Data(int g, int m, int a){
giorno = g;
mese = m;
anno =a;
}

Data d = new Data(20,3,2007);

Crea un oggeTo d di Bpo Data e lo inizializza al 20/03/2007


Unimplementazione pi sosBcata potrebbe controllare che la data
proposta sia legale, riutando il 31/2/2007

Inizializzazione e accesso
public class Persona {
private String nome;
private Persona padre;
private int eta;
public Persona(String n) {
nome = n; padre = null; eta = 0;}
public void setPadre(Persona p) {
padre = p; }
public void setEta(int e) { eta = e; }
}
public class Esempio {
public static void main(String[] args) {
Persona paolo, pietro;
int i = 20;
paolo = new Persona("Paolo");
paolo.setEta(i);
i = 30; // quanto vale paolo.eta?
pietro = new Persona("Pietro");
pietro.setEta(i);
paolo.setPadre(pietro);
// quanto vale paolo.padre.eta?
pietro.setEta(i+1);
// quanto vale paolo.padre.eta ?
}
}

Persona
String nome
Persona padre
int eta

setEta
setPadre
paolo

pietro

i
30
20
Persona

Persona

nome = Paolo

nome =Pietro

padre =
setEta
setPadre

padre =
eta = 020

setEta
setPadre

30
eta = 031

CostruTori di default
Se non si denisce nessun costruTore, il compilatore
fornisce il costruTore di default (senza parametri), che
svolge le seguenB funzioni:
Alloca lo spazio per gli aTribuB di Bpo primiBvo
Alloca lo spazio per i riferimenB agli aTribuB di Bpo
denito dallutente
Inizializza a null tu] i riferimenB, a 0 tuTe le variabili
numeriche, a false tu] i boolean

Il costruTore di default (senza parametri) viene fornito


dal compilatore a meno che non si deniscano altri
costruTori

I costruTori: esempio
public class C {
private int i1;
private int i2;
}
public class Esempio {
public static void main(String args[]) { CorreTo perch il compilatore ha
inserito automaBcamente il
C x = new C();
costruTore di default
x = new C(5,7);
}
}
Sbagliato, non esiste nessun
costruTore che prenda due
parametri

MolB costruTori

public class C {
private int i1;
private int i2;
public C(int a1, int a2) {
i1 = a1; i2 = a2;}
public C(int a) {
i1 = a; i2 = a;}
}

z
y

public class Esempio {


x
public static void main(String args[]) {
C x, y, z;

x = new C();
y = new C(1);

C

i1 = 1

i2 = 1

C

i1 = 1

i2 = 4

Sbagliato, visto che il programmatore ha denito un costruTore, il


compilatore non aggiunge quello di default
CorreTo, esiste un costruTore che prende un parametro intero

z = new C(1,4);
CorreTo, esiste un costruTore che prende due parametri interi

Creazione e distruzione
Se limplementazione deve essere private, lunico modo per
inizializzare un oggeTo specicare uno o pi metodi parBcolari,
chiamaB costruTori
La creazione di un oggeTo comporta sempre linvocazione di un
costruTore

Il costruTore svolge due operazioni fondamentali, obbligandoci a


denirle insieme:
Lallocazione della memoria necessaria a contenere loggeTo
Linizializzazione dello spazio allocato, assegnando opportuni valori

A dierenza del C, in Java non necessario deallocare


esplicitamente gli ogge]

Il garbage collector si occupa di questo: una rouBne di sistema che


provvede automaBcamente a liberare memoria quando serve (invece
in C/C++)

Condivisione (sharing)
Un oggeTo condiviso tra due variabili se
entrambe accedono a esso
L'assegnamento di variabili di Bpo riferimento
genera condivisione
Se ogge] condivisi sono modicabili, le
modiche apportate aTraverso una variabile
sono visibili anche aTraverso l'altra

Allocazione stack vs. heap


Quando un metodo termina, tuTe le variabili del
corrispondente record di a]vazione sono distruTe
per gli ogge] creaB sullo heap NON sono
necessariamente distru]

public

static Data foo() {


d xxx
Data d = new Data(1,1,2005);
return d;
}
public static void main(String[] args) {
Data x = foo();
x xxx
}

1
1
2010

d esiste solo sullo stack durante lesecuzione di foo(),


ma viene deallocata quando foo() termina
LoggeTo costruito conBnua a vivere sullo heap!!!

Tipi array
Dato un Bpo T (predenito o denito
dallutente) un array di T denito come
T[]

Similmente sono dichiaraB gli array


mulBdimensionali
T[][] T[][][]

Esempi
int[] float[] Persona[]

Dichiarazione e inizializzazione
Dichiarazione
int[] ai1, ai2;
float[] af1;
double ad[];
Persona[][] ap;

Inizializzazione
int[] ai={1,2,3};
double[][] ad={{1.2, 2.5}, {1.0, 1.5}};

Il caso degli array


In mancanza di inizializzazione, la dichiarazione di un
array non alloca spazio per gli elemenB dellarray
Lallocazione si realizza dinamicamente tramite
loperatore:
new <Bpo> [<dimensione>]

int[] i=new int[10];


i={10,11,12};
float[][] f=new float[10][10];
Persona[] p=new Persona[30];

Se gli elemenB non sono di un Bpo primiBvo,


loperatore new alloca solo lo spazio per i riferimenB

Array di ogge]: Denizione


A

Person[ ] person;
person = new Person[20];
person[0] = new Person( );

person

E denita solo la variabile


person. Larray vero e
proprio non esiste

Array di ogge]: Denizione


Person[ ] person;

Ora larray stato creato ma i


diversi ogge] di Bpo Person
non esistono ancora.

person = new Person[20];


person[0] = new Person( );

person
0

16 17 18 19

Array di ogge]: Denizione


Person[ ] person;
Un oggeTo di Bpo persona stato creato e
un riferimento a tale oggeTo stato
inserito in posizione 0.

person = new Person[20];

person[0] = new Person( );

person
0

Person

16 17 18 19

Array di ogge] vs. array di Bpi base


Listruzione: oat f[] = new oat[10];
crea un oggeTo di Bpo array di oat e alloca spazio per 10 oat
f
0 1 2 3 4 5 6 7 8 9
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Listruzione: Person p[] = new Person[10];
crea un oggeTo di Bpo array di Person e alloca spazio per 10 riferimenB
a ogge] di Bpo Person
f
Non viene allocato
spazio per gli oggeF
veri e propri

Loop generalizzato per collezioni


Se abbiamo una collezione C di elemenB di Bpo T, possiamo iterare
su di essi scrivendo

for (T x: C) { //si legge for each x in C
// esegui azioni su x
}

equivalente a scrivere
for (int i = 0; i < C.size(); i++) {
T x = C.get(i);
// esegui azioni su x
}

Anche gli array sono collezioni, quindi

Esempio per array


int sum(int[] a) {
int result = 0;
for (int n : a)
result += n;
return result;
}

n indica il generico elemento dell'array, non l'indice!


Un esempio pi chiaro: array di Person

int sumAge(Person[] a) {
int result = 0;
for (Person p: a)
result += p.getAge();
return result;
}

Programmazione
in the large

Automobile
public class Automobile {
private String colore, marca, modello;
private int cilindrata, numPorte;
private boolean accesa;

public void accendi(){
accesa=true;
}

public boolean puoPartire(){
return accesa;
}

public void dipingi(String col){
colore=col;
}

public void trasforma(String ma, String mo){
marca=ma;
modello=mo;
}
}

Chiamata di metodi
Vengono valutaB i parametri aTuali
Viene creato il record di a]vazione sullo stack
spazio per i parametri formali
spazio per le variabili locali

Esecuzione del corpo


Regola per il passaggio parametri
I parametri il cui Bpo uno dei Bpi semplici sono
passaB per copia
I parametri il cui Bpo un Bpo riferimento sono
passaB per riferimento

Passaggio parametri e reference


public class Data {
Quando copiaIn termina d2
3/2/1984
private int giorno;
private int mese;
private int anno;
xxx
1
d

1
public void copiaIn(Data d){
d2
xxx
1990
d.giorno = giorno;
d.mese = mese;
d.anno = anno;
}
3

d1 yyy
public static void main(String[] args){
2
Data d1 = new Data(3,2,1984);
1984
Data d2 = new Data(1,1,1990);
d1.copiaIn(d2);
}
}

Visibilit dei nomi


Le variabili locali ad un metodo (o i parametri
formali) possono mascherare gli aTribuB della
classe
Soluzione:
La pseudo-variabile this conBene un riferimento
alloggeTo corrente e pu essere uBlizzata per
aggirare eventuali mascheramenB

this per aggirare mascheramenB


La pseudo-variabile this conBene un riferimento
alloggeTo corrente e pu essere uBlizzata per aggirare
eventuali mascheramenB

public class Automobile {


private String colore, marca, modello;

public void trasforma(String marca, String modello){

this.marca=marca;

this.modello=modello;
}

public static void main(String[] args){

Automobile a = new Automobile();

a.trasforma("Ford", "T4");
}
}

a.marca diventa "Ford", a.modello diventa "T4"

Un altro esempio
public class Data {
private int giorno;
private int mese;
private int anno;

public void giornoDopo(){
this.giorno++;
if (this.giorno > 31){

this.giorno = 1;

this.mese++;
}

}

public static void main(String[] args){
Data d1, d2; //d1 e d2 inizializzate qui
d1.giornoDopo(); //In giornoDopo this e lo stesso riferimento di d1
d2.giornoDopo(); //In giornoDopo this e lo stesso riferimento di d2
}
}

this per resBtuire un riferimento


La pseudo-variabile this pu essere uBlizzata per resBtuire un
riferimento all'oggeTo corrente
public class InsiemeDiInteri {

public InsiemeDiInteri inserisci(int i){

//modifica this inserendovi lelemento i

return this; //restituisce linsieme modificato
}

}

InsiemeDiInteri x,y,z;
//qui x e y sono inizializzati opportunamente
z = (x.inserisci(2)).unione(y)

//utile che inserisci restituisca un insieme

Metodi e aTribuB di classe


Sintassi: staBc <denizione dellaTributo o metodo>
Un aTributo di classe condiviso da tu] gli ogge] della
classe
Si pu accedere a un aTributo di classe senza bisogno di
creare un oggeTo tramite la notazione:
<nome classe>.<nome aTributo>

Un metodo di classe pu essere invocato senza bisogno di


creare un oggeTo tramite la notazione:
<nome classe>.<nome metodo>(<par. aTuali>)

Un metodo di classe pu essere comunque invocato su un


oggeTo della classe
Il nome di classe pu essere omesso se non ci sono
problemi di ambiguit

Metodi e aTribuB di classe: vincoli


Un metodo staBc pu accedere ai soli aTribuB
e metodi staBc
Un metodo convenzionale pu accedere
liberamente a metodi e aTribuB staBc

Metodi e aTribuB di classe


public class Shape {
static Screen screen=new Screen(); // si noti linizializzazione
static void setScreen(Screen s) {screen=s;}
void show(Screen s) {setScreen(s);}

public static void main(String[] args) {
Shape.setScreen(new Screen()); // corretto
Shape.show(); // errato, show e un metodo normale
Shape s1=new Shape(), s2=new Shape();
Screen s=new Screen();
s1.setScreen(s);
// corretto, si possono chiamare metodi static su oggetti

// in questo punto s2.screen==s1.screen==s
}
}

Metodi e aTribuB di classe


public class Disc {
private static int counter;
private int discNumber;

Disc(){discNumber = counter++;}
public int getDiscNumber(){return discNumber;}
public static int getTotalNoOfDiscs(){ return counter;}

public static void main(String[] args) {

System.out.println(Disc.getTotalNoOfDiscs()); // 0

Disc d1 = new Disc();

Disc d2 = new Disc();

System.out.println(d1.discNumber); // 0

System.out.println(d2.discNumber); // 1

System.out.println(Disc.getDiscNumber()); // errore!!!

System.out.println(Disc.getTotalNoOfDiscs()); // 2
}
}

ATribuB costanB
possibile denire aTribuB costanB tramite la notazione:
nal <denizione di aTributo>=<valore>

public class Automobile {


int colore;
final int BLU=0, GIALLO=1; // e altri
void dipingi(int colore) {this.colore=colore;}

public static void main(String[] args) {

Automobile a=new Automobile();

a.BLU=128; // errato

System.out.println("BLU="+a.BLU); // corretto
}
}

Overloading di metodi
Allinterno di una stessa classe possono esservi
pi metodi con lo stesso nome purch si
disBnguano per numero e/o Bpo dei parametri
ATenzione: Il Bpo del valore resBtuito non basta a
disBnguere due metodi

In Java lintestazione di un metodo comprende il


numero, il Bpo e la posizione dei parametri; non
include il Bpo del valore resBtuito

Metodi overloaded devono avere intestazioni diverse

UBle per denire funzioni con codice dierente


ma con ee] simili su Bpi diversi

Esempio
public class Prova {
public int max(int a, int b, int c) {...}
public double max(double a, double b) {...}
public int max(int a, int b) {...}
}

Ogni volta viene chiamata la funzione "giusta


public static void main(String[] args){
Prova p = new Prova();

p.max(2,3,5);
p.max(2.3, 3.14);
p.max(2,3);
}

Ulteriore esempio
public class Automobile {
private String colore, marca, modello;
private int cilindrata, numPorte;
private boolean accesa;
public Automobile(String col, String mar, String mod) {
colore=col;
marca=mar;
modello =mod;
}
public Automobile() {
// se serve e necessario definirlo anche se e come quello di
// default, perche ce un altro costruttore
colore=marca=modello=null;
cilindrata=numPorte=0;
}
public void accendi() {accesa=true;}
public boolean puoPartire() {return accesa;}
public void dipingi(String col) {colore=col;}
}

Ancora sui costruttori


possibile invocare un costruttore dallinterno di un altro
tramite la notazione
this(<elenco di parametri attuali>);

Tuttavia il this deve essere la prima istruzione. Esempio:


import java.util.Calendar;
public Data(int g, int m, int a){
if (dataValida(g,m,a)) {// dataValida e' un metodo statico

giorno = g;

mese = m;

anno = a;
}
else ...
}

public Data(int g, int m) { //giorno e mese + anno corrente
this(g,m,Calendar.getInstance().get(Calendar.YEAR));
}

Reference e operatore ==
Loperatore di confronto == confronta i valori dei riferimenB e non
gli ogge]!
d1

Data d1 = new Data(1,12,2001);


Data d2= new Data(1,12,2001);
if (d1==d2) {
...

giorno

12

mese

2001

anno

giorno

12

mese

2001

anno

xxx

d2
yyy

false: d1 e d2 sono riferimenB a ogge] diversi

d1=d2; (anche se hanno gli stessi valori per gli aTribuB) e


quindi hanno indirizzi diversi

d1 == d2 diventa true: lindirizzo contenuto in d1 diventa uguale


allindirizzo contenuto in d1 (diventano idenBci)

Confronto di uguaglianza
Metodo equals( ) consente di vericare se due
ogge] sono uguali (nel senso che hanno lo
stesso valore dello stato)
per String: contengono la stessa sequenza di caraTeri

Dice se due ogge] sono equivalenB


Che cosa ci esaTamente signichi dipende dal Bpo
dell'oggeTo
per esempio, due insiemi sono equivalenB se contengono gli
stessi elemenB, indipendentemente dall'ordine di
inserimento
va pertanto spesso ridenita

Uso
String stringa1 = "Luciano;
String stringa2 = "Giovanni;

Stringa1.equals(stringa2); //false
String b = new String("Ciao");
String c = new String("Ciao");
if (b.equals(c)); //true

Enumerazioni

Si possono dichiarare Bpi enumeraB, per modellare insiemi con cardinalit ridoTa

enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};


Size s = Size.MEDIUM;

Size una vera classe: ha esaTamente quaTro istanze


Non se ne possono costruire altre
Non c bisogno di usare equal per confrontare i valori, basta ==
s pu essere solo null o uno dei valori enumeraB
A una classe enumerata si possono aggiungere costruTore, metodi e aTribuB
PermeTono di associare qualsiasi informazione alle costanB enumerate
I costruTori sono invocaB solo quando vengono costruite le costanB

public enum Size {
SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");
private String abbreviation;
private Size(String abbreviation) {
this.abbreviation=abbreviation;
}
public String getAbbreviation(){
return abbreviation;
}
}

Enumerazioni

TuTe le classi enumerate sono eredi della classe Enum che ore i seguenB metodi
// resBtuisce la costante enumerata della classe indicata che ha quel nome
staBc Enum valueOf(String name)
// resBtuisce il nome della costante enumerata
String toString()

import java.util.Scanner;

public class ProvaString {
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
String str = in.next();
Size siz = Enum.valueOf(Size.class, str);
System.out.println(siz.toString());
}
}

Ogni classe enumerata ha un metodo che resBtuisce un array contenente tu] i valori
della classe
Size[] valori = Size.values();

Altri metodi
name() resBtuisce il nome della costante
enumeraBva
ordinal() resBtuisce la posizione (partendo da 0)
compareTo() confronta loggeTo corrente C con
la variabile enumeraBva passata come parametro
e resBtuisce
Un valore negaBvo se C minore del parametro
Zero se C uguale al parametro
Un valore posiBvo se C maggiore del parametro

Loop generalizzato
enum Color {Red, White, Blue}
for (Color c: Color.values()) { . . . }

Esempio

Un esempio pi ricco: pianeB del sistema solare, associaB alla propria massa e
raggio; si pu calcolare il peso di un oggeTo su ogni pianeta

public enum Planet {


MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24,
6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e
+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7), PLUTO
(1.27e+22, 1.137e6);

private final double mass; // in kilograms
private final double radius; // in meters

Planet(double mass, double radius) {
this.mass = mass; this.radius = radius;
}
public double mass() {return mass;}
public double radius() {return radius;}

// universal gravitational constant (m^3 kg^-1 s^-2)
public static final double G = 6.67300E-11;

public double surfaceGravity() {return G * mass / (radius * radius);}
public double surfaceWeight(double otherMass) {return otherMass * surfaceGravity();}
}

Esempio

A parBre dal peso di un corpo sulla terra, calcola


e stampa il peso su tu] gli altri pianeB
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p,p.surfaceWeight(mass));
}

65

Tipi riferimento per i Bpi primiBvi


I Bpi primiBvi sono comodi, ma a volte si
preferirebbe usarli come riferimento, per
omogeneit
Java fornisce classi predenite
Integer, Character, Float, Long, Short, Double
(sono in java.lang)
Un oggeTo Integer conBene un int, ma viene
inizializzato solo con i costruTori
Il Bpo Integer immutabile

Esempi
Integer i; // qui i vale null!
i = new Integer(5); //i e un rif. a oggetto che
contiene 5
Integer x = i; // sharing: x e i stesso oggetto
int y = x.intValue(); // vecchio modo
i = y; // boxing automatico
y = i; // unboxing automatico
i = 3; // come sopra

Catene puntate
Un oggeTo pu avere aTribuB che sono
ancora ogge] o metodi che resBtuiscono
ogge]: accesso a metodi e aTribuB avviene a
catena

Esempi
System.out.println();

out aTributo pubblico (staBco) di classe System


La classe di out fornisce il metodo println()
String b = new String("Ciao");
String a = b.substring(1).substring(2);
System.out.println(a); //che oggetto e a?

Operatore . associativo a sinistra:


(b.substring(1)).substring(2);
(System.out).println();

Ereditariet
possibile stabilire una relazione
soToclasse_di () fra le classi di un
programma Java
relazione dordine parziale (riessiva e transiBva)
public class B extends A {}

A classe base, o antenato, o padre, o


superclasse,
B classe derivata, o discendente, o glio, o
erede, o soToclasse,

Relazione di ereditariet
La soToclasse eredita tuTa limplementazione
(aTribuB e metodi) della superclasse
Gli aTribuB e metodi della superclasse sono
implicitamente deniB anche nella soToclasse
(ma con alcune dierenze che vedremo fra poco)

Una soToclasse pu aggiungere nuovi aTribuB


e metodi ma anche ridenire i metodi delle
sue superclassi
Lasciando invariato numero e Bpo dei
parametri(overriding)

Un semplice esempio
public class Automobile {
private String modello;
private boolean accesa;
public Automobile(String modello) {
this.modello=modello;
this.accesa = false;
}
public void accendi() {accesa=true;}
public boolean puoPartire() {return accesa;}
}

public class AutomobileElettrica extends Automobile {
private boolean batterieCariche;
public void ricarica() {batterieCariche=true;}
...
}
}

Gerarchia a pi livelli
Figure
perimeter
area

OpenFigure

ClosedFigure

numberOfSides
Polygon

Rectangle

pixel
width
color
scale()
rotate()
draw()

Ellipse

Overriding
Una soToclasse pu ridenire limplementazione di un metodo

Lintestazione del metodo non deve cambiare


Lintestazione non include il Bpo resBtuito, che quindi pu cambiare
secondo le regole della covarianza
public class AutomobileElettrica extends Automobile{
private boolean batterieCariche;
public void ricarica() {batterieCariche = true;}

...
}

public void accendi() {// OVERRIDING

// accensione auto elettrica e diversa da quella
// di auto a benzina la reimplementiamo
}
}

Pseudo variabile super


Allinterno di un metodo della soToclasse ci si
pu riferire ai metodi della superclasse:
super.<nome metodo>(<lista par. aTuali>)

public class AutomobileElettrica extends Automobile{

private boolean batterieCariche;
public void ricarica() {batterieCariche=true;}

public void accendi() {// OVERRIDING

if(batterieCariche) super.accendi();

else System.out.println("Batterie scariche");
}
}

CostruTori
I costruTori non sono ereditaB perch occorre inizializzare anche i nuovi
aTribuB
Per inizializzare gli aTribuB private ereditaB, allinterno di un costruTore
possibile richiamare il costruTore della superclasse tramite:
super(<lista di par. aTuali>) posta come prima istruzione del costruTore

Se il programmatore non chiama esplicitamente un costruTore della


superclasse, il compilatore inserisce automaBcamente il codice che invoca
il costruTore di default della superclasse (che potrebbe non esistere!)
In AutomobileEleTrica:

public AutomobileElettrica(String modello) {



super(modello); //qui inizializza modello e accesa

batterieCariche=false;
}

Object
In mancanza di unindicazione dierente, una
classe Java estende la classe Object
La classe Object fornisce alcuni metodi tra i
quali:
public boolean equals(Object);
public String toString();
public Object clone();

String
Le stringhe sono immutabili (non si possono aggiungere o
togliere caraTeri a una stringa, ma occorre costruirne una
nuova)
CostruTori:
String()
String(String s)

Operatore di concatenamento +
Metodi pubblici:

int length() resBtuisce la lunghezza di una stringa


char charAt(int index) resBtuisce il char alla posizione index
il primo ha posizione 0

String substring(int beginIndex) (parte da 0)

Esempio
public class ProvaString {
public static void main (String[] args) {

String a = new String(); //a e una ref a stringa vuota

String b = new String("Ciao"); //b e una ref a Ciao:

//abbreviazione: String b = Ciao;

String c = new String(b); //Ora c e copia di b

String d = b; //d e b sono alias

System.out.println(b + " " + c + " " + d);
}
}

Lassegnamento d=b un assegnamento dei riferimenB


Non si copia loggeTo!

InformaBon Hiding

Package
Le classi sono raggruppate in package
Un package raggruppa classi denendo regole di
visibilit

Se una classe C visibile nel package A, ma


dichiarata nel package B, questa viene
denotata come B.C
quindi si possono usare liberamente gli stessi
nomi in package diversi, senza generare
confusione

Package
Una directory che conBene una o pi compilaBon
unit
Introduce un nuovo ambito di visibilit dei nomi:
unit con lo stesso nome possono stare in package
diversi

ConBene un insieme di classi pubbliche ed un


insieme di classi private al package (friendly)
Le classi pubbliche si possono importare in altri
package

CompilaBon unit
Un le che conBene la dichiarazione di una o
pi classi (o interfacce)
Una sola dichiarata pubblica (public class) e
avente lo stesso nome del le

C al pi un solo metodo main


Si pu specicare il package di appartenenza
(lo stesso per tuTe)
se non si specica, si assume un package senza
nome di default

Visibilit delle classi


public
sono visibili a tu] con import del package
Il le deve avere lo stesso nome
al pi una public class per ogni le

"friendly
sono visibili solo allinterno dello stesso package/
compilaBon unit
possono stare in un le con altre classi

Esempio
package myTools.text;
public class TextComponent {
. . .Zzz z;
}

package myTools.text;
public class yyy {
. . .
}
class Zzz{
. . .
}

package myFigs.planar;
public class DrawableElement {
. . .
}
class xxx {
. . .
}

compilaBon units

Visibilit di aTribuB e metodi


ATribuB e metodi di una classe vengono sempre
ereditaB e possono essere:
public

sono visibili a tu]

private

sono visibili solo allinterno della classe


non sono visibili nelle soToclassi

protected

sono visibili alle classi nello stesso package


sono visibili anche alle soToclassi

friendly
sono visibili alle classi nello stesso package
sono visibili solo alle soToclassi nello stesso package

InformaBon hiding
Una propriet public una promessa agli uBlizzatori
della classe:

La propriet sar disponibile e non cambier, perlomeno


dal punto di vista degli uBlizzatori della classe

La promessa molto vincolante


Meglio promeTere poco!

TuTe le propriet per cui ci si vuole garanBre la


possibilit di modica o eliminazione devono essere
private
Al massimo, ma solo se indispensabile, friendly

meglio private per le propriet helper di una classe


Se un aTributo friendly e qualcuno lo usa non possiamo pi
cambiarlo!!!

InformaBon hiding
fortemente consigliato che gli aTribuB di una classe
public siano private o friendly
Usare metodi per accedervi!

I metodi che possono essere usaB dagli uBlizzatori


"esterni" della classe dovrebbero essere public
Gli aTribuB friendly sono usaB solo quando le classi
all'interno dello stesso package devono avere accesso
privilegiato
p. es. Una classe Lista deve usare una classe Nodo che implementa
i nodi della Lista: uBle che Lista possa accedere ai campi di Nodo,
ma gli uBlizzatori di Lista non devono potere accedere a Nodo

Accesso ai membri private


Le soToclassi non possono accedere agli
aTribuB (e metodi) private delle superclassi!
sbagliato scrivere:
public void accendi() {
if (batterieCariche) accesa = true;
}

perch accesa private nella superclasse!

Polimorfismo

Ereditariet

Una classe denisce un Bpo


Una soToclasse (transiBvamente) denisce un soToBpo
Un oggeTo del soToBpo sosBtuibile a un oggeTo del Bpo
Si disBngue tra

Bpo staBco: il Bpo dichiarato


Bpo dinamico (o aTuale): il Bpo dell'oggeTo aTualmente assegnato

Java garanBsce che ci non compromeTa la type safety (vedremo


come)
Il compilatore verica che ogni oggeTo venga manipolato
correTamente in base al Bpo staBco
Il linguaggio garanBsce che a run Bme non sorgono errori se invece
si opera su un oggeTo il cui Bpo dinamico un soToBpo del Bpo
staBco

Esempio
public class UsaAutomobile {
public static void partenza(Automobile p) {
if (p.puoPartire())

p.accendi();

}

public static void main(String args[]) {
Automobile myCar = new AutomobileElettrica("T");// legale!!
partenza(myCar); //funziona anche con AutomobileElettrica
}
}

Polimorsmo
L'esempio precedente un caso di polimorsmo
Polimorsmo la capacit per un elemento
sinta]co di riferirsi a elemenB di diverso Bpo
In Java una variabile di un Bpo riferimento T pu
riferirsi ad un qualsiasi oggeTo il cui Bpo sia T o
un soToBpo di T
Similmente un parametro formale di un Bpo
riferimento T pu riferirsi a parametri aTuali il cui
Bpo sia T o un soToBpo di T

Tipo dinamico e Bpo staBco


Il Bpo staBco quello denito dalla dichiarazione
Automobile myCar;

Il Bpo dinamico denito dal costruTore usato per denirlo


AutomobileElettrica yourCar = new AutomobileElettrica();

In Java, il Bpo dinamico pu essere soToBpo del Bpo staBco


Automobile myCar = new Automobile();
AutomobileElettrica yourCar = new AutomobileElettrica();
myCar = yourCar;

Assegnamento polimorco
A un oggeTo di Bpo staBco T si pu sempre assegnare
un oggeTo il cui Bpo staBco S soToBpo di T (ma non
viceversa)
Questo consente che il Bpo dinamico possa essere
soToBpo di quello staBco
Automobile myCar = new AutomobileEleTrica();

Il compilatore verica che ogni oggeTo venga


manipolato correTamente solo in base al Bpo staBco
La regola precedente garanBsce che a runBme non
sorgono errori se si opera su un oggeTo il cui Bpo
dinamico un soToBpo del Bpo staBco

Uso delle classi dellesempio


Automobile myCar = new Automobile("Ford");
AutomobileElettrica yourCar = new AutomobileElettrica("E1");
myCar = yourCar;
myCar

yourCar

xxx

xxx

Ford

modello

false

accesa

El

modello

false

accesa

true

baTerieCariche

Chiamata di un metodo
Automobile myCar = new AutomobileElettrica();

myCar.puoPartire(); //OK, chiama metodo di Automobile
myCar.accendi(); //OK, chiama metodo di AutomobileElettrica
myCar.ricarica(); //KO, ricarica non e metodo di Automobile
AutomobileElettrica yourCar = new AutomobileElettrica ();
yourCar.ricarica(); //OK, chiama metodo di AutomobileElettrica

Polimorsmo e binding dinamico


In Java, a fronte della invocazione x.f(x1,...,xn),
limplementazione scelta per il metodo f
dipende dal Bpo dinamico di x e non dal suo
Bpo staBco
Il legame (binding) tra il metodo invocato e il
metodo a]vato dinamico, dipende dal Bpo
aTuale dell'oggeTo

Esempio
public class UsaAutomobile {

public static void partenza(Automobile a) {
a.accendi(); //funziona anche con AutomobileElettrica
}

public static void main(String args[]) {
Automobile a1 = new Automobile("Ford");
Automobile a2 = new AutomobileElettrica("T");
a1.accendi();
//a run-time chiama implementazione di Automobile
a2.accendi();
//a run-time chiama implementazione di AutomobileElettrica
partenza(a2);
// solo a run time si puo conoscere il tipo effettivo
}
}

Binding dinamico
public static void partenza(Automobile a) {
a.accendi();
}

Quale implementazione del metodo accendi() chiamare


Quella di Automobile o quella di AutomobileEleTrica?
Il Bpo ee]vo del parametro a noto solo quando accendi
viene chiamato, cio a runBme

Il compilatore non genera il codice per eseguire il metodo,


ma genera il codice che cerca limplementazione giusta in
base al Bpo ee]vo di a e la esegue
Questo si chiama dispatching

Overloading e overriding
Overriding non va confuso con overloading
public class Punto2D{
public float distanza(Punto2D p){}
}
public class Punto3D extends Punto2D {
public float distanza(Punto3D p){}//OVERLOADING!!!
}

Il metodo distanza di Punto3D ha unintestazione diversa


da quella di distanza dichiarato in Punto2D:
Punto2D p = new Punto3D();
p.distanza(p); //chiama Punto2D.distanza(Punto2D)

NON overriding non si applica binding dinamico

Regola per chiamata metodi


Il compilatore, quando trova una chiamata di
un metodo x.m(p) risolve staBcamente
loverloading, individuando la segnatura del
metodo chiamato in base al Bpo staBco P del
parametro aTuale p e al Bpo staBco X di x
Il binding dinamico si applica a run-Bme: il
codice sceglie a runBme il metodo pi vicino
tra quelli che hanno il protoBpo X.m(P)
stabilito staBcamente

Esempio
public class Punto2D{public float distanza(Punto2D p){}}
public class Punto3D extends Punto2D {public float distanza(Punto3D p){}}

public void static void main(String[] args){
Punto2D p1,p2;
Punto3D p3;

p1 = new Punto2D(3,7);
p2 = new Punto3D(3,7, 4);
System.out.println(p1.distanza(p2));//metodo di Punto2D
System.out.println(p2.distanza(p1)); //Punto2D

p3 = new Punto3D(6,7, 5);
System.out.println(p2.distanza(p3)); //Punto2D
System.out.println(p3.distanza(p1)); //Punto2D
System.out.println(p1.distanza(p3)); //Punto2D

Punto3D p4 = new Punto3D(6,1, 5);
System.out.println(p3.distanza(p4)); //Punto3D
}

Annotazioni
@Deprecated indica un elemento deprecato e da
non conBnuare ad usare
@Override informa il compilatore che lelemento
sovrascrive un elemento dichiarato in una super
classe
Non richiesta, ma potrebbe aiutare ad evitare errori

@SuppressWarnings chiede al compilatore di


non generare warnings per quel metodo
@SuppressWarnings({"unchecked", "deprecaBon"})
104

Classi e metodi astra]


Un metodo astraTo un metodo per il quale
non viene specicata alcuna implementazione
Una classe astraTa se conBene almeno un
metodo astraTo
Non possibile creare istanze di una classe
astraTa
Le classi astraTe sono molto uBli per
introdurre delle astrazioni di alto livello

Classi e metodi astra]


abstract class Shape {
static Screen screen = new Screen();
Shape(){}
abstract void show();
}
class Circle extends Shape {
void show() {

}
}

Shape s=new Shape(); //ERRATO


Circle c=new Circle(); //CORRETTO
Shape s=new Circle(); //CORRETTO

Classi e metodi nal


Se vogliamo impedire che sia possibile creare
soToclassi di una certa classe la deniremo
nal
final class C {...}
class C1 extends C //ERRATO

Similmente, se vogliamo impedire loverriding


di un metodo dobbiamo denirlo nal
class C {final void f(){}
class C1 extends C {
void f(){} //ERRATO
}

I limiB dellereditariet semplice


Lereditariet semplice non permeTe la
descrizione di numerose situazioni reali
Supponiamo di avere una classe GiocaTolo ed una
classe Automobile
In assenza di ereditariet mulBpla non posso denire
la classe AutomobileGiocaTolo

La soluzione di Java
DisBngue tra una gerarchia di ereditariet (semplice)
ed una gerarchia di implementazione (mulBpla)
introducendo il costruTo interface

Interfacce
Uninterfaccia come una classe che pu avere solo
aTribuB costanB e i cui metodi sono tu] pubblici e
astra]
Sintassi:
interface <nome> {
<lista di denizione di aTribuB costanB e metodi privi di corpo>
}

Gli aTribuB dichiaraB in uninterfaccia sono


visibili alla classe che la implementa
immodicabili (staBc nal)

public interface Scalable {


int SMALL=0, MEDIUM=1, BIG=2; //static e final
void setScale(int size);
}

Interfacce ed ereditariet
Una interfaccia pu ereditare da una o pi
interfacce
interface <nome> extends <nome1>,..,<nomen> {
...
}

La gerarchia di implementazione
Una classe pu implementare una o pi
interfacce, ma estendere al pi una classe
se la classe non astraTa deve fornire
unimplementazione per tu] i metodi presenB
nelle interfacce che implementa
altrimenB la classe astraTa

Sintassi:
class <nome> extends <nome0>
implements <nome1>,..,<nomen> {...}

Classi astraTe e interfacce


Classi astraTe
Possono avere metodi implementaB e non

Interfacce
Possono avere solo metodi non implementaB

Classi concrete
Hanno tu] i metodi implementaB

Classe astraTa
abstract class TwoDimFigure {
public abstract double area();
public abstract double perimeter();
public abstract void printInfo();
public void setOutlineColor(Color cc) {

// code to set the color
}
public void setInsideColor(Color cc) {

// code to set the color
}
}

Interfaccia
public interface Shape {
public String baseclass="shape";
public void draw();
}


public class Circle implements Shape {
public void draw() {
System.out.println("Drawing Circle here");
}
}

public class Main {
public static void main(String[] args) {

Shape circleshape = new Circle();
circleshape.draw();
}
}

114

I tre principi
Incapsulamento
Gli ogge] nascondono il
loro stato e parte del
loro comportamento

Ereditariet
Ogni soToclasse eredit
tuTe le propriet della/
delle superclassi

Polimorsmo
Stessa interfaccia anche
per Bpi di daB diversi

auto

manuale

disegna()

Super classe

automaBca SoToclassi

disegna()

Conversioni automaBche
di Bpo

Promozioni

byte -> short, int, long, oat, double


short -> int, long, oat, double
int -> long, oat, double
long -> oat or double
oat -> double
char -> int, long, oat, double

Conversioni forzate: casBng


possibile forzare una conversione di Bpo aTraverso
loperatore di casBng:
(<Bpo>)<espressione>

Tra Bpi primiBvi sono consenBte le seguenB conversioni


forzate (quando possibile e con perdita di informazione)

short
char
int
long
oat
double
byte

->
->
->
->
->
->
->

byte, char
byte, short
byte, short, char
byte, short, char, int
byte, short, char, int, long
byte, short, char, int, long, oat
char

CasBng in generale
possibile forzare esplicitamente la
conversione da un Bpo riferimento T ad un
soToBpo T1 purch:
Il Bpo dinamico dellespressione che converBamo
sia un soToBpo di T1

Animale a = ;
Gatto mao = ;
a = mao; //OK assegnazione polimorfica
mao = (Gatto)a; //corretto (casting) perche a e un gatto

instanceof
Per evitare errori runBme e stabilire qual il
Bpo dinamico di un oggeTo si pu usare
loperatore instanceof
Object a;
int i = System.in.read();
if (i>0) a = new String();
else a = new Integer(5);
if (a instanceof String) return a.equals("abcd")

instanceof e equals
public class Data {
private int giorno;
private int mese;
private int anno;

public int leggiGiorno(){}
public boolean equals(Object o) {
if (!(o instanceof Data)) return false;
Data d= (Data) o;
return (giorno==d.giorno &&

mese == d.mese && anno == d.anno);
}
}

ArrayList
Gli arrayList sono contenitori estendibili e
accorciabili dinamicamente
Prima di JDK5 potevano contenere solo ogge]
Object
Da JDK5 sono parametrici (generici) rispeTo al
Bpo degli ogge] contenuB
Prima ancora cerano i Vector, analoghi ad
ArrayList non generici

ArrayList
import java.util.ArrayList;

ArrayList<Person> team = new ArrayList<Person>();

team.add(new Person("Bob"));
team.add(new Person("Joe"));

team.size()

ArrayList
Per accedere agli elemenB occorre usare i metodi get e
set (fanno riferimento a indici che iniziano da 0)

team.get(1); //restituisce la Person di nome Joe
team.set(0, new Person("Mary")); //sostituisce Mary a Bob

I metodi add(indice, oggeTo) e remove(indice)


aggiungono e tolgono un elemento nella posizione
indicata, alterando la lunghezza dellArrayList

team.add(1, new Person("Sue")); //ora ci sono Mary, Sue, Bob
team.remove(0); // rimuove Mary, ora ci sono Sue e Bob

ArrayList
add e remove sono operazioni costose perch
comportano la traslazione di segmenB
dellArrayList
Il metodo set NON deve essere usato per inserire un
elemento in una posizione che non c

team.set(4, new Person("Jack")); // scorretto

ma solo per sosBtuire un oggeTo gi presente in


quella posizione

for(Person p: team){
//fa qualcosa con la persona p
}

Genericit e soToBpi
Alcune cose sembrano andare contro lintuizione
List<String> ls = new ArrayList<String>();
List<Object> lo = ls; // ERRORE IN COMPILAZIONE
lo.add(new Object());
String s = ls.get(0); // ERRORE: tenta di assegnare un Object a
una String!

Qualche considerazione
Una lista di String una lista di Object?
NO! altrimenB tramite una variabile lista di Object si
potrebbe inserire un Object in una lista di String e
quando si tenta di estrarre, tramite una variabile lista
di String, un oggeTo String, si verica un errore
In generale, se Gen<T> una classe generica e se
ClassB soToclasse di ClassA allora Gen<ClassB> NON
soToclasse di Gen<ClassA>
E quindi una lista di Object NON soToclasse di una
lista di String

Come funzionano
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {

for (T o : a) {c.add(o);}
}

Per rendere correTo linserimento c.add(o) dobbiamo chiamare


fromArrayToCollecBon con parametri in cui il Bpo dellelemento
della collezione sia superBpo di quello dellarray
Non occorre indicare esplicitamente i parametri aTuali in
corrispondenza ai parametri formali di un metodo generico
Ci pensa il compilatore a inferire il Bpo del parametro aTuale
scegliendo il Bpo pi specico (il minimo, nellordinamento tra Bpi
denito dalla gerarchia di ereditariet, tra tu] quelli che rendono
legale linvocazione del metodo generico)

Esempi

String[] sa = new String[100];


Collection<String> cs = new ArrayList<String>();
fromArrayToCollection(sa, cs);// T inferred to be String
Collection<Object> co = new ArrayList<Object>();
fromArrayToCollection(sa, co);// T inferred to be Object
Integer[] ia = new Integer[100];
fromArrayToCollection(ia, cs);// String NON e supertipo
di Integer

I/O formaTato
Input

Dobbiamo costruire uno scanner collegato allo standard input


stream System.in, poi usare i metodi della classe Scanner

nextLine() legge la prossima riga


next() legge la prossima stringa no a uno spazio
nextInt() legge il prossimo int
nextDouble() legge il prossimo double
hasNext() dice se c una stringa in input
hasNextInt(), nextFloat(), nextBoolean()

Output

System.out fornisce anche il buon vecchio prinI di C, con le


solite convenzioni di formaTazione, pi print e println

Esempio
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
System.out.println("Come ti chiami?");
String nome = in.nextLine();
System.out.println("Quanti anni hai?");
int eta = in.nextInt();
System.out.println("Ciao "+nome+" tra un anno avrai "





+(eta+1)+" anni");
}

GesBone delle eccezioni

Situazioni eccezionali
Un metodo (utente o di libreria) deve poter segnalare limpossibilit di
produrre un risultato signicaBvo o la propria terminazione scorreTa
Apertura di un le (ma il le non esiste)
Calcolo della radice quadrata di un numero (ma il numero negaBvo)

Soluzioni

Terminazione del programma

SpeTa al chiamante e non al chiamato

ResBtuire un valore convenzionale che rappresenB lerrore


Pu non essere fa]bile
Il chiamante potrebbe dimenBcarsi di controllare

Portare il programma in uno stato scorreTo


Si usa una variabile globale ERROR

Usare un metodo predenito per la gesBone degli errori


Ad esempio, si chiama un metodo ERROR(...)

Centralizza la gesBone degli errori (che speTerebbe al chiamante)


Rende dicoltoso il riprisBno

GesBone esplicita delle eccezioni


Una procedura pu terminare normalmente

con un risultato valido o sollevando uneccezione

Uneccezione un oggeTo speciale resBtuito dal


metodo

Le eccezioni vengono segnalate al chiamante che pu


gesBrle
Le eccezioni hanno un Bpo (Classe)
Esempi: DivisionByZeroExcepBon, NullPointerExcepBon

Le eccezioni possono contenere daB che danno indicazioni


sul problema incontrato
Le eccezioni possono essere denite dallutente
(personalizzazione)

Eccezioni in Java
Un'eccezione pu essere caTurata e gesBta aTraverso il costruTo
try {<blocco>} catch(ClasseEccezione e) {<codice di gesBone>}

try {
x = x/y;
}
catch (DivisionByZeroException e) {
// e e loggetto eccezione
// codice per gestire leccezione
// Qui e possibile usare e
}
// istruzione successiva, da eseguire se non ce stata
// eccezione o se catch e riuscito a recuperare

Pi rami catch
Un ramo catch(Ex e) pu gesBre uneccezione di Bpo T se T
di Bpo Ex o T un soToBpo di Ex
Pi clausole catch possono seguire lo stesso blocco try
Ciascuna caTura leccezione del proprio Bpo

public void faiQualcosa() {


try {

leggiFile();
}
catch(FileInesistenteException fi) {

System.out.println("Ooops! Il file " +


fi.getNomeFile() + " non esiste!");
}
catch(FileDanneggiatoException fd) {

System.out.println("Ooops! Il file " +


fd.getNomeFile() + " contiene dati scorretti!");
}
}

Propagazione delle eccezioni


Si termina lesecuzione del blocco di codice in cui si
vericata leccezione e...

se il blocco di codice corrente un blocco try/catch ed esiste un


catch in grado di gesBre leccezione, si passa il controllo al
primo di tali rami catch e, completato questo, alla prima
istruzione dopo il blocco
altrimenB si risalgono eventuali blocchi di codice pi esterni no
a trovare un blocco try/catch che contenga un ramo catch che
sia in grado di gesBre leccezione, altrimenB...
Leccezione viene propagata nel contesto del chiamante
la propagazione conBnua no a che si trova un blocco try/catch
che gesBsce leccezione
se tale blocco non si trova, il programma termina

Flusso in presenza di eccezioni


Flusso:
main a]vato
blocco 1
blocco 2
proc1 invocata
proc2 invocata
blocco 3
blocco 4
... eccezione!
propagazione
delleccezione!

main
block1
block2
call to proc1

proc2
block3

block4
throw excepBon

proc1
call to proc2

block5

Il ramo nally
Un blocco try/catch pu avere un ramo nally in
aggiunta a uno o pi rami catch
Il ramo nally comunque eseguito
sia che allinterno del blocco try non vengano
sollevate eccezioni
sia che allinterno del ramo try vengano sollevate
eccezioni gesBte da un catch
In tal caso il ramo nally viene eseguito dopo il ramo catch
che gesBsce leccezione

sia che allinterno del blocco try vengano sollevate


eccezioni NON gesBte da un catch

Esempio
public class Prova {
public void read(String fileName) {
try{

FileInputStream f=new FileInputStream(fileName);

... // use f
} catch(IOException ex) {...}
finally {f.close();}
}
}

Metodi con eccezioni


Il faTo che un metodo possa terminare sollevando uneccezione
dichiarato nella sua interfaccia per mezzo della clausola throws per
Segnalare un comportamento anomalo incontrato durante
lesecuzione di unistruzione

public

int leggiInteroDaInput() throws IOException

NoBcare che una precondizione su unoperazione stata violata


public int fact(int n) throws NegativeException

ResBtuire un valore convenzionale


public int search(int[] a, int x) throws NullPointerException,
NotFoundException

Sollevare eccezioni
Per sollevare esplicitamente un'eccezione, si usa
il comando throw, seguito dalloggeTo (del Bpo
delleccezione) da lanciare al chiamante
Informalmente throw
Termina lesecuzione del blocco di codice che lo
conBene, generando un'eccezione del Bpo specicato
public int fact(int n) throws NegativeException {
if (n<0) throw new NegativeException();
else if (n==0 || n==1) return 1;
else return (n*fact(n-1));
}

Tipi di eccezioni
Eccezioni denite tramite classi, soToBpo del
Bpo Throwable
Esistono due Bpi di eccezioni:
Throwable

eccezioni checked
soToBpo di ExcepBon

Error

Exception

eccezioni unchecked
soToBpo di RunBmeExcepBon

RuntimeException (checked
exceptions)

(unchecked exceptions)

Eccezioni checked
Devono essere dichiarate dai metodi che possono
sollevarle (altrimenB si ha un errore in compilazione)
Quando un metodo M1 invoca un altro metodo M2
che pu sollevare uneccezione di Bpo Ex (checked),
una delle due seguenB aermazioni deve essere vera
Linvocazione di M2 in M1 avviene internamente ad un
blocco try/catch che gesBsce eccezioni di Bpo Ex (quindi,
M1 gesBsce leventuale eccezione)
Il Bpo Ex (o un suo super-Bpo) fa parte delle eccezioni
dichiarate nella clausola throws del metodo M1 (quindi,
M1 propaga leventuale eccezione)

Eccezioni unchecked
Possono propagarsi senza essere dichiarate in
alcuna intestazione di metodo e senza essere
gesBte da nessun blocco try/catch
Pu essere meglio includerle comunque in
throws, per renderne esplicita la presenza (ma
per il compilatore irrilevante)

Denizione di nuove eccezioni


Gli ogge] di un qualunque Bpo T denito
dallutente possono essere usaB per sollevare
e propagare eccezioni se T denito come
soTo-Bpo della classe ExcepBon (o
RunBmeExcepBon)
La denizione della classe che descrive
uneccezione non dierisce dalla denizione di
una qualsiasi classe denita dallutente

Denizione di nuove eccezioni


Pu possedere aTribuB e metodi propri usaB per
fornire informazioni aggiunBve al gestore
delleccezione
public class NewKindOfException extends Exception {
public NewKindOfException(){super();}
public NewKindOfException(String s){super(s);}
}


I due costruTori richiamano semplicemente i
costruTori di ExcepBon
throw new NewKindOfException("problema!!!")

try{....}
catch(NewKindOfException ecc){
String s = ecc.toString();System.out.println(s);
}

Eccezioni con un costruTore


public class ProvaEcc {
public static void main(String[] args) {
int g,m,a;
Data d;
... // leggi g, m, a
try {d=new Data(g,m,a);}
catch(DataIllegaleException e) {

System.out.println("Inserita una data illegale");

System.exit(-1);
}}}

public class Data {
private int giorno, mese, anno;
private boolean corretta(int g,int m,int a) {...}

public class DataIllegaleException extends Exception {};//inner class

public Data(int g, int m, int a) throws DataIllegaleException {
if(!corretta(g,m,a)) throw new DataIllegaleException();
giorno=g; mese=m; anno=a;
}}

Eccezioni unchecked
Il loro uso dovrebbe essere limitato ai casi in cui
Si traTa di eccezioni di Bpo aritmeBco/logico
C un modo conveniente e poco costoso di evitare
leccezione

Ad esempio, le eccezioni aritmeBche: posso sempre, se mi


serve, controllare prima di eseguire il calcolo
Ad esempio, per gli array, le eccezioni di Bpo
OutOfBoundExcepBon possono essere evitate controllando
in anBcipo il valore dellaTributo length dellarray

Leccezione usata solo in un contesto ristreTo


Meglio dichiararle comunque in throws quando un
metodo le pu lanciare

Masking
Dopo la gesBone delleccezione, lesecuzione conBnua
seguendo il normale usso del programma (leccezione
viene gesBta e non si propaga al chiamante)
Eccezione usata per vericare una condizione
public static boolean sorted (int[] a) {
int prev;
try {prev=a[0];} //lancia eccezione se array e vuoto
//(era meglio check diretto su a)
catch (IndexOutOfBoundsException e){return true;}
for (int i=1; i<a.length; i++) {

if (prev <= a[i]) prev=a[i];

else return false;
}
return true;
}

Consigli uBli
Aggiungere ai daB correlaB con leccezione
lindicazione del metodo che lha sollevata
Nel caso in cui la gesBone di uneccezione comporB
unulteriore eccezione (reecBng), conservare le
informazioni
Sebbene sia possibile scegliere liberamente i nomi
delle nuove eccezioni denite, buona convenzione
farli terminare con la parola ExcepBon
Pu essere talvolta uBle prevedere un package
contenente tuTe le nuove eccezioni denite
A volte invece conviene denire eccezioni come inner
classes

Potrebbero piacerti anche